diff --git a/carrier/websocket_test.go b/carrier/websocket_test.go index a0a32bb8..65072d0d 100644 --- a/carrier/websocket_test.go +++ b/carrier/websocket_test.go @@ -2,10 +2,11 @@ package carrier import ( "context" + "crypto/rand" "crypto/tls" "crypto/x509" "fmt" - "math/rand" + "math/big" "testing" "time" @@ -23,28 +24,19 @@ import ( func websocketClientTLSConfig(t *testing.T) *tls.Config { certPool := x509.NewCertPool() helloCert, err := tlsconfig.GetHelloCertificateX509() - assert.NoError(t, err) + require.NoError(t, err) certPool.AddCert(helloCert) assert.NotNil(t, certPool) return &tls.Config{RootCAs: certPool} } -func TestWebsocketHeaders(t *testing.T) { - req := testRequest(t, "http://example.com", nil) - wsHeaders := websocketHeaders(req) - for _, header := range stripWebsocketHeaders { - assert.Empty(t, wsHeaders[header]) - } - assert.Equal(t, "curl/7.59.0", wsHeaders.Get("User-Agent")) -} - func TestServe(t *testing.T) { log := zerolog.Nop() shutdownC := make(chan struct{}) errC := make(chan error) listener, err := hello.CreateTLSListener("localhost:1111") - assert.NoError(t, err) - defer listener.Close() + require.NoError(t, err) + defer func() { _ = listener.Close() }() go func() { errC <- hello.StartHelloWorldServer(&log, listener, shutdownC) @@ -56,19 +48,25 @@ func TestServe(t *testing.T) { assert.NotNil(t, tlsConfig) d := gws.Dialer{TLSClientConfig: tlsConfig} conn, resp, err := clientConnect(req, &d) - assert.NoError(t, err) + require.NoError(t, err) + defer func() { _ = resp.Body.Close() }() assert.Equal(t, "websocket", resp.Header.Get("Upgrade")) - for i := 0; i < 1000; i++ { - messageSize := rand.Int()%2048 + 1 - clientMessage := make([]byte, messageSize) - // rand.Read always returns len(clientMessage) and a nil error - rand.Read(clientMessage) + for range 1000 { + messageSize, err := rand.Int(rand.Reader, big.NewInt(2048)) + require.NoError(t, err) + clientMessage := make([]byte, messageSize.Int64()+1) + for i := range clientMessage { + n, err := rand.Int(rand.Reader, big.NewInt(256)) + n8 := uint8(n.Uint64()) //nolint:gosec // test-only + require.NoError(t, err) + clientMessage[i] = n8 + } err = conn.WriteMessage(websocket.BinaryFrame, clientMessage) - assert.NoError(t, err) + require.NoError(t, err) messageType, message, err := conn.ReadMessage() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, websocket.BinaryFrame, messageType) assert.Equal(t, clientMessage, message) } @@ -97,27 +95,30 @@ func TestWebsocketWrapper(t *testing.T) { req := testRequest(t, testAddr, nil) conn, resp, err := clientConnect(req, &d) require.NoError(t, err) + defer func() { _ = resp.Body.Close() }() assert.Equal(t, "websocket", resp.Header.Get("Upgrade")) // Websocket now connected to test server so lets check our wrapper wrapper := cfwebsocket.GorillaConn{Conn: conn} buf := make([]byte, 100) - wrapper.Write([]byte("abc")) + _, err = wrapper.Write([]byte("abc")) + require.NoError(t, err) n, err := wrapper.Read(buf) require.NoError(t, err) - require.Equal(t, n, 3) + require.Equal(t, 3, n) require.Equal(t, "abc", string(buf[:n])) // Test partial read, read 1 of 3 bytes in one read and the other 2 in another read - wrapper.Write([]byte("abc")) + _, err = wrapper.Write([]byte("abc")) + require.NoError(t, err) buf = buf[:1] n, err = wrapper.Read(buf) require.NoError(t, err) - require.Equal(t, n, 1) + require.Equal(t, 1, n) require.Equal(t, "a", string(buf[:n])) buf = buf[:cap(buf)] n, err = wrapper.Read(buf) require.NoError(t, err) - require.Equal(t, n, 2) + require.Equal(t, 2, n) require.Equal(t, "bc", string(buf[:n])) } diff --git a/connection/quic_connection.go b/connection/quic_connection.go index 6133a022..dff82ee4 100644 --- a/connection/quic_connection.go +++ b/connection/quic_connection.go @@ -143,7 +143,7 @@ func (q *quicConnection) Serve(ctx context.Context) error { } // serveControlStream will serve the RPC; blocking until the control plane is done. -func (q *quicConnection) serveControlStream(ctx context.Context, controlStream quic.Stream) error { +func (q *quicConnection) serveControlStream(ctx context.Context, controlStream *quic.Stream) error { return q.controlStreamHandler.ServeControlStream(ctx, controlStream, q.connOptions.ConnectionOptions(), q.orchestrator) } @@ -166,7 +166,7 @@ func (q *quicConnection) acceptStream(ctx context.Context) error { } } -func (q *quicConnection) runStream(quicStream quic.Stream) { +func (q *quicConnection) runStream(quicStream *quic.Stream) { ctx := quicStream.Context() stream := cfdquic.NewSafeStreamCloser(quicStream, q.streamWriteTimeout, q.logger) defer func() { _ = stream.Close() }() diff --git a/connection/quic_connection_test.go b/connection/quic_connection_test.go index 2df741a6..a66b4001 100644 --- a/connection/quic_connection_test.go +++ b/connection/quic_connection_test.go @@ -530,7 +530,7 @@ func TestServeUDPSession(t *testing.T) { ctx, cancel := context.WithCancel(t.Context()) // Establish QUIC connection with edge - edgeQUICSessionChan := make(chan quic.Connection) + edgeQUICSessionChan := make(chan *quic.Conn) go func() { earlyListener, err := quic.Listen(udpListener, testTLSServerConfig, testQUICConfig) assert.NoError(t, err) @@ -779,7 +779,7 @@ func TestDialQuicWithSkipPortReuse(t *testing.T) { <-serverDone } -func serveSession(ctx context.Context, datagramConn *datagramV2Connection, edgeQUICSession quic.Connection, closeType closeReason, expectedReason string, t *testing.T) { +func serveSession(ctx context.Context, datagramConn *datagramV2Connection, edgeQUICSession cfdquic.QUICConnection, closeType closeReason, expectedReason string, t *testing.T) { payload := []byte(t.Name()) sessionID := uuid.New() cfdConn, originConn := net.Pipe() @@ -843,7 +843,7 @@ const ( closedByTimeout ) -func runRPCServer(ctx context.Context, session quic.Connection, sessionRPCServer pogs.SessionManager, configRPCServer pogs.ConfigurationManager, t *testing.T) { +func runRPCServer(ctx context.Context, session cfdquic.QUICConnection, sessionRPCServer pogs.SessionManager, configRPCServer pogs.ConfigurationManager, t *testing.T) { stream, err := session.AcceptStream(ctx) require.NoError(t, err) diff --git a/connection/quic_datagram_v2.go b/connection/quic_datagram_v2.go index c6dfa170..37b829a1 100644 --- a/connection/quic_datagram_v2.go +++ b/connection/quic_datagram_v2.go @@ -8,7 +8,7 @@ import ( "time" "github.com/google/uuid" - pkgerrors "github.com/pkg/errors" + "github.com/pkg/errors" "github.com/rs/zerolog" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" @@ -22,7 +22,7 @@ import ( "github.com/cloudflare/cloudflared/packet" cfdquic "github.com/cloudflare/cloudflared/quic" "github.com/cloudflare/cloudflared/tracing" - tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs" + "github.com/cloudflare/cloudflared/tunnelrpc/pogs" rpcquic "github.com/cloudflare/cloudflared/tunnelrpc/quic" ) @@ -31,14 +31,14 @@ const ( demuxChanCapacity = 16 ) -var errInvalidDestinationIP = pkgerrors.New("unable to parse destination IP") +var errInvalidDestinationIP = errors.New("unable to parse destination IP") // DatagramSessionHandler is a service that can serve datagrams for a connection and handle sessions from incoming // connection streams. type DatagramSessionHandler interface { Serve(context.Context) error - tunnelpogs.SessionManager + pogs.SessionManager } type datagramV2Connection struct { @@ -111,7 +111,7 @@ func (d *datagramV2Connection) Serve(ctx context.Context) error { } // RegisterUdpSession is the RPC method invoked by edge to register and run a session -func (q *datagramV2Connection) RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeAfterIdleHint time.Duration, traceContext string) (*tunnelpogs.RegisterUdpSessionResponse, error) { +func (q *datagramV2Connection) RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeAfterIdleHint time.Duration, traceContext string) (*pogs.RegisterUdpSessionResponse, error) { traceCtx := tracing.NewTracedContext(ctx, traceContext, q.logger) ctx, registerSpan := traceCtx.Tracer().Start(traceCtx, "register-session", trace.WithAttributes( attribute.String("session-id", sessionID.String()), @@ -123,7 +123,7 @@ func (q *datagramV2Connection) RegisterUdpSession(ctx context.Context, sessionID if err := q.flowLimiter.Acquire(management.UDP.String()); err != nil { log.Warn().Msgf("Too many concurrent sessions being handled, rejecting udp proxy to %s:%d", dstIP, dstPort) - err := pkgerrors.Wrap(err, "failed to start udp session due to rate limiting") + err := errors.Wrap(err, "failed to start udp session due to rate limiting") tracing.EndWithErrorStatus(registerSpan, err) return nil, err } @@ -180,7 +180,7 @@ func (q *datagramV2Connection) RegisterUdpSession(ctx context.Context, sessionID Msgf("Registered session") tracing.End(registerSpan) - resp := tunnelpogs.RegisterUdpSessionResponse{ + resp := pogs.RegisterUdpSessionResponse{ Spans: traceCtx.GetProtoSpans(), } diff --git a/connection/quic_datagram_v2_test.go b/connection/quic_datagram_v2_test.go index e4edac46..5b4372a5 100644 --- a/connection/quic_datagram_v2_test.go +++ b/connection/quic_datagram_v2_test.go @@ -1,13 +1,11 @@ package connection import ( - "context" "net" "testing" "time" "github.com/google/uuid" - "github.com/quic-go/quic-go" "github.com/rs/zerolog" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -16,73 +14,15 @@ import ( "github.com/cloudflare/cloudflared/mocks" ) -type mockQuicConnection struct{} - -func (m *mockQuicConnection) AcceptStream(_ context.Context) (quic.Stream, error) { - return nil, nil -} - -func (m *mockQuicConnection) AcceptUniStream(_ context.Context) (quic.ReceiveStream, error) { - return nil, nil -} - -func (m *mockQuicConnection) OpenStream() (quic.Stream, error) { - return nil, nil -} - -func (m *mockQuicConnection) OpenStreamSync(_ context.Context) (quic.Stream, error) { - return nil, nil -} - -func (m *mockQuicConnection) OpenUniStream() (quic.SendStream, error) { - return nil, nil -} - -func (m *mockQuicConnection) OpenUniStreamSync(_ context.Context) (quic.SendStream, error) { - return nil, nil -} - -func (m *mockQuicConnection) LocalAddr() net.Addr { - return nil -} - -func (m *mockQuicConnection) RemoteAddr() net.Addr { - return nil -} - -func (m *mockQuicConnection) CloseWithError(_ quic.ApplicationErrorCode, s string) error { - return nil -} - -func (m *mockQuicConnection) Context() context.Context { - return nil -} - -func (m *mockQuicConnection) ConnectionState() quic.ConnectionState { - panic("not meant to be called") -} - -func (m *mockQuicConnection) SendDatagram(_ []byte) error { - return nil -} - -func (m *mockQuicConnection) ReceiveDatagram(_ context.Context) ([]byte, error) { - return nil, nil -} - -func (m *mockQuicConnection) AddPath(*quic.Transport) (*quic.Path, error) { - return nil, nil -} - func TestRateLimitOnNewDatagramV2UDPSession(t *testing.T) { log := zerolog.Nop() - conn := &mockQuicConnection{} ctrl := gomock.NewController(t) flowLimiterMock := mocks.NewMockLimiter(ctrl) + connMock := mocks.NewMockQUICConnection(ctrl) datagramConn := NewDatagramV2Connection( t.Context(), - conn, + connMock, nil, nil, 0, diff --git a/connection/quic_datagram_v3.go b/connection/quic_datagram_v3.go index 4b1d4553..8bda4f8f 100644 --- a/connection/quic_datagram_v3.go +++ b/connection/quic_datagram_v3.go @@ -12,7 +12,7 @@ import ( "github.com/cloudflare/cloudflared/ingress" "github.com/cloudflare/cloudflared/management" cfdquic "github.com/cloudflare/cloudflared/quic" - cfdquicv3 "github.com/cloudflare/cloudflared/quic/v3" + v3 "github.com/cloudflare/cloudflared/quic/v3" "github.com/cloudflare/cloudflared/tunnelrpc/pogs" ) @@ -25,17 +25,17 @@ type datagramV3Connection struct { conn cfdquic.QUICConnection index uint8 // datagramMuxer mux/demux datagrams from quic connection - datagramMuxer cfdquicv3.DatagramConn - metrics cfdquicv3.Metrics + datagramMuxer v3.DatagramConn + metrics v3.Metrics logger *zerolog.Logger } func NewDatagramV3Connection(ctx context.Context, conn cfdquic.QUICConnection, - sessionManager cfdquicv3.SessionManager, + sessionManager v3.SessionManager, icmpRouter ingress.ICMPRouter, index uint8, - metrics cfdquicv3.Metrics, + metrics v3.Metrics, logger *zerolog.Logger, ) DatagramSessionHandler { log := logger. @@ -43,7 +43,7 @@ func NewDatagramV3Connection(ctx context.Context, Int(management.EventTypeKey, int(management.UDP)). Uint8(LogFieldConnIndex, index). Logger() - datagramMuxer := cfdquicv3.NewDatagramConn(conn, sessionManager, icmpRouter, index, metrics, &log) + datagramMuxer := v3.NewDatagramConn(conn, sessionManager, icmpRouter, index, metrics, &log) return &datagramV3Connection{ conn, diff --git a/go.mod b/go.mod index c0c66946..50eb5598 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.22.0 github.com/prometheus/client_model v0.6.2 - github.com/quic-go/quic-go v0.52.0 + github.com/quic-go/quic-go v0.59.1 github.com/rs/zerolog v1.20.0 github.com/shirou/gopsutil/v4 v4.26.3 github.com/stretchr/testify v1.11.1 @@ -35,7 +35,7 @@ require ( go.opentelemetry.io/otel/trace v1.43.0 go.opentelemetry.io/proto/otlp v1.10.0 go.uber.org/automaxprocs v1.6.0 - go.uber.org/mock v0.5.1 + go.uber.org/mock v0.5.2 golang.org/x/crypto v0.52.0 golang.org/x/net v0.55.0 golang.org/x/sync v0.20.0 @@ -65,10 +65,8 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-playground/validator/v10 v10.15.1 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect - github.com/google/pprof v0.0.0-20250418163039-24c5476c6587 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect @@ -77,7 +75,6 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.23.4 // indirect github.com/pelletier/go-toml/v2 v2.0.9 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect @@ -108,5 +105,4 @@ replace github.com/prometheus/golang_client => github.com/prometheus/golang_clie replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 -// This fork is based on quic-go v0.45 -replace github.com/quic-go/quic-go => github.com/chungthuang/quic-go v0.45.1-0.20250428085412-43229ad201fd +replace github.com/quic-go/quic-go => github.com/chungthuang/quic-go v0.45.1-0.20260529212404-a9fddf436fc4 // This fork is based on quic-go v0.59.1 diff --git a/go.sum b/go.sum index 6936530d..398bae26 100644 --- a/go.sum +++ b/go.sum @@ -9,8 +9,8 @@ github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= 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/chungthuang/quic-go v0.45.1-0.20250428085412-43229ad201fd h1:VdYI5zFQ2h1/qzoC6rhyPx479bkF8i177Qpg4Q2n1vk= -github.com/chungthuang/quic-go v0.45.1-0.20250428085412-43229ad201fd/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ= +github.com/chungthuang/quic-go v0.45.1-0.20260529212404-a9fddf436fc4 h1:ZaFGQi6lUEnMyl0DvRy2mEp9u7FP+FrUBr7q+c4U68o= +github.com/chungthuang/quic-go v0.45.1-0.20260529212404-a9fddf436fc4/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= github.com/cloudflare/backoff v0.0.0-20240920015135-e46b80a3a7d0 h1:pRcxfaAlK0vR6nOeQs7eAEvjJzdGXl8+KaBlcvpQTyQ= github.com/cloudflare/backoff v0.0.0-20240920015135-e46b80a3a7d0/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY= github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= @@ -79,8 +79,6 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.15.1 h1:BSe8uhN+xQ4r5guV/ywQI4gO59C2raYcGffYWZEjZzM= github.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= @@ -104,8 +102,6 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/google/pprof v0.0.0-20250418163039-24c5476c6587 h1:b/8HpQhvKLSNzH5oTXN2WkNcMl6YB5K3FRbb+i+Ml34= -github.com/google/pprof v0.0.0-20250418163039-24c5476c6587/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= 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/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -150,10 +146,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= -github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= -github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU= -github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= @@ -239,8 +231,8 @@ go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.5.1 h1:ASgazW/qBmR+A32MYFDB6E2POoTgOwT509VP0CT/fjs= -go.uber.org/mock v0.5.1/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= +go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/mocks/mock_quic_connection.go b/mocks/mock_quic_connection.go new file mode 100644 index 00000000..0b73e6b7 --- /dev/null +++ b/mocks/mock_quic_connection.go @@ -0,0 +1,427 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ../quic/quic_connection.go +// +// Generated by this command: +// +// mockgen -typed -build_flags=-tags=gomock -package mocks -destination mock_quic_connection.go -source=../quic/quic_connection.go +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + net "net" + reflect "reflect" + + quic "github.com/quic-go/quic-go" + gomock "go.uber.org/mock/gomock" +) + +// MockQUICConnection is a mock of QUICConnection interface. +type MockQUICConnection struct { + ctrl *gomock.Controller + recorder *MockQUICConnectionMockRecorder + isgomock struct{} +} + +// MockQUICConnectionMockRecorder is the mock recorder for MockQUICConnection. +type MockQUICConnectionMockRecorder struct { + mock *MockQUICConnection +} + +// NewMockQUICConnection creates a new mock instance. +func NewMockQUICConnection(ctrl *gomock.Controller) *MockQUICConnection { + mock := &MockQUICConnection{ctrl: ctrl} + mock.recorder = &MockQUICConnectionMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockQUICConnection) EXPECT() *MockQUICConnectionMockRecorder { + return m.recorder +} + +// AcceptStream mocks base method. +func (m *MockQUICConnection) AcceptStream(ctx context.Context) (*quic.Stream, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AcceptStream", ctx) + ret0, _ := ret[0].(*quic.Stream) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AcceptStream indicates an expected call of AcceptStream. +func (mr *MockQUICConnectionMockRecorder) AcceptStream(ctx any) *MockQUICConnectionAcceptStreamCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptStream", reflect.TypeOf((*MockQUICConnection)(nil).AcceptStream), ctx) + return &MockQUICConnectionAcceptStreamCall{Call: call} +} + +// MockQUICConnectionAcceptStreamCall wrap *gomock.Call +type MockQUICConnectionAcceptStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockQUICConnectionAcceptStreamCall) Return(arg0 *quic.Stream, arg1 error) *MockQUICConnectionAcceptStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockQUICConnectionAcceptStreamCall) Do(f func(context.Context) (*quic.Stream, error)) *MockQUICConnectionAcceptStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockQUICConnectionAcceptStreamCall) DoAndReturn(f func(context.Context) (*quic.Stream, error)) *MockQUICConnectionAcceptStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// CloseWithError mocks base method. +func (m *MockQUICConnection) CloseWithError(code quic.ApplicationErrorCode, reason string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CloseWithError", code, reason) + ret0, _ := ret[0].(error) + return ret0 +} + +// CloseWithError indicates an expected call of CloseWithError. +func (mr *MockQUICConnectionMockRecorder) CloseWithError(code, reason any) *MockQUICConnectionCloseWithErrorCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseWithError", reflect.TypeOf((*MockQUICConnection)(nil).CloseWithError), code, reason) + return &MockQUICConnectionCloseWithErrorCall{Call: call} +} + +// MockQUICConnectionCloseWithErrorCall wrap *gomock.Call +type MockQUICConnectionCloseWithErrorCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockQUICConnectionCloseWithErrorCall) Return(arg0 error) *MockQUICConnectionCloseWithErrorCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockQUICConnectionCloseWithErrorCall) Do(f func(quic.ApplicationErrorCode, string) error) *MockQUICConnectionCloseWithErrorCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockQUICConnectionCloseWithErrorCall) DoAndReturn(f func(quic.ApplicationErrorCode, string) error) *MockQUICConnectionCloseWithErrorCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// ConnectionState mocks base method. +func (m *MockQUICConnection) ConnectionState() quic.ConnectionState { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ConnectionState") + ret0, _ := ret[0].(quic.ConnectionState) + return ret0 +} + +// ConnectionState indicates an expected call of ConnectionState. +func (mr *MockQUICConnectionMockRecorder) ConnectionState() *MockQUICConnectionConnectionStateCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectionState", reflect.TypeOf((*MockQUICConnection)(nil).ConnectionState)) + return &MockQUICConnectionConnectionStateCall{Call: call} +} + +// MockQUICConnectionConnectionStateCall wrap *gomock.Call +type MockQUICConnectionConnectionStateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockQUICConnectionConnectionStateCall) Return(arg0 quic.ConnectionState) *MockQUICConnectionConnectionStateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockQUICConnectionConnectionStateCall) Do(f func() quic.ConnectionState) *MockQUICConnectionConnectionStateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockQUICConnectionConnectionStateCall) DoAndReturn(f func() quic.ConnectionState) *MockQUICConnectionConnectionStateCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Context mocks base method. +func (m *MockQUICConnection) Context() context.Context { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Context") + ret0, _ := ret[0].(context.Context) + return ret0 +} + +// Context indicates an expected call of Context. +func (mr *MockQUICConnectionMockRecorder) Context() *MockQUICConnectionContextCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockQUICConnection)(nil).Context)) + return &MockQUICConnectionContextCall{Call: call} +} + +// MockQUICConnectionContextCall wrap *gomock.Call +type MockQUICConnectionContextCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockQUICConnectionContextCall) Return(arg0 context.Context) *MockQUICConnectionContextCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockQUICConnectionContextCall) Do(f func() context.Context) *MockQUICConnectionContextCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockQUICConnectionContextCall) DoAndReturn(f func() context.Context) *MockQUICConnectionContextCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// LocalAddr mocks base method. +func (m *MockQUICConnection) LocalAddr() net.Addr { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LocalAddr") + ret0, _ := ret[0].(net.Addr) + return ret0 +} + +// LocalAddr indicates an expected call of LocalAddr. +func (mr *MockQUICConnectionMockRecorder) LocalAddr() *MockQUICConnectionLocalAddrCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockQUICConnection)(nil).LocalAddr)) + return &MockQUICConnectionLocalAddrCall{Call: call} +} + +// MockQUICConnectionLocalAddrCall wrap *gomock.Call +type MockQUICConnectionLocalAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockQUICConnectionLocalAddrCall) Return(arg0 net.Addr) *MockQUICConnectionLocalAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockQUICConnectionLocalAddrCall) Do(f func() net.Addr) *MockQUICConnectionLocalAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockQUICConnectionLocalAddrCall) DoAndReturn(f func() net.Addr) *MockQUICConnectionLocalAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// OpenStream mocks base method. +func (m *MockQUICConnection) OpenStream() (*quic.Stream, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OpenStream") + ret0, _ := ret[0].(*quic.Stream) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// OpenStream indicates an expected call of OpenStream. +func (mr *MockQUICConnectionMockRecorder) OpenStream() *MockQUICConnectionOpenStreamCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStream", reflect.TypeOf((*MockQUICConnection)(nil).OpenStream)) + return &MockQUICConnectionOpenStreamCall{Call: call} +} + +// MockQUICConnectionOpenStreamCall wrap *gomock.Call +type MockQUICConnectionOpenStreamCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockQUICConnectionOpenStreamCall) Return(arg0 *quic.Stream, arg1 error) *MockQUICConnectionOpenStreamCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockQUICConnectionOpenStreamCall) Do(f func() (*quic.Stream, error)) *MockQUICConnectionOpenStreamCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockQUICConnectionOpenStreamCall) DoAndReturn(f func() (*quic.Stream, error)) *MockQUICConnectionOpenStreamCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// OpenStreamSync mocks base method. +func (m *MockQUICConnection) OpenStreamSync(ctx context.Context) (*quic.Stream, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OpenStreamSync", ctx) + ret0, _ := ret[0].(*quic.Stream) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// OpenStreamSync indicates an expected call of OpenStreamSync. +func (mr *MockQUICConnectionMockRecorder) OpenStreamSync(ctx any) *MockQUICConnectionOpenStreamSyncCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStreamSync", reflect.TypeOf((*MockQUICConnection)(nil).OpenStreamSync), ctx) + return &MockQUICConnectionOpenStreamSyncCall{Call: call} +} + +// MockQUICConnectionOpenStreamSyncCall wrap *gomock.Call +type MockQUICConnectionOpenStreamSyncCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockQUICConnectionOpenStreamSyncCall) Return(arg0 *quic.Stream, arg1 error) *MockQUICConnectionOpenStreamSyncCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockQUICConnectionOpenStreamSyncCall) Do(f func(context.Context) (*quic.Stream, error)) *MockQUICConnectionOpenStreamSyncCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockQUICConnectionOpenStreamSyncCall) DoAndReturn(f func(context.Context) (*quic.Stream, error)) *MockQUICConnectionOpenStreamSyncCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// ReceiveDatagram mocks base method. +func (m *MockQUICConnection) ReceiveDatagram(ctx context.Context) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReceiveDatagram", ctx) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReceiveDatagram indicates an expected call of ReceiveDatagram. +func (mr *MockQUICConnectionMockRecorder) ReceiveDatagram(ctx any) *MockQUICConnectionReceiveDatagramCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveDatagram", reflect.TypeOf((*MockQUICConnection)(nil).ReceiveDatagram), ctx) + return &MockQUICConnectionReceiveDatagramCall{Call: call} +} + +// MockQUICConnectionReceiveDatagramCall wrap *gomock.Call +type MockQUICConnectionReceiveDatagramCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockQUICConnectionReceiveDatagramCall) Return(arg0 []byte, arg1 error) *MockQUICConnectionReceiveDatagramCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockQUICConnectionReceiveDatagramCall) Do(f func(context.Context) ([]byte, error)) *MockQUICConnectionReceiveDatagramCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockQUICConnectionReceiveDatagramCall) DoAndReturn(f func(context.Context) ([]byte, error)) *MockQUICConnectionReceiveDatagramCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// RemoteAddr mocks base method. +func (m *MockQUICConnection) RemoteAddr() net.Addr { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoteAddr") + ret0, _ := ret[0].(net.Addr) + return ret0 +} + +// RemoteAddr indicates an expected call of RemoteAddr. +func (mr *MockQUICConnectionMockRecorder) RemoteAddr() *MockQUICConnectionRemoteAddrCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockQUICConnection)(nil).RemoteAddr)) + return &MockQUICConnectionRemoteAddrCall{Call: call} +} + +// MockQUICConnectionRemoteAddrCall wrap *gomock.Call +type MockQUICConnectionRemoteAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockQUICConnectionRemoteAddrCall) Return(arg0 net.Addr) *MockQUICConnectionRemoteAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockQUICConnectionRemoteAddrCall) Do(f func() net.Addr) *MockQUICConnectionRemoteAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockQUICConnectionRemoteAddrCall) DoAndReturn(f func() net.Addr) *MockQUICConnectionRemoteAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SendDatagram mocks base method. +func (m *MockQUICConnection) SendDatagram(payload []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendDatagram", payload) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendDatagram indicates an expected call of SendDatagram. +func (mr *MockQUICConnectionMockRecorder) SendDatagram(payload any) *MockQUICConnectionSendDatagramCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendDatagram", reflect.TypeOf((*MockQUICConnection)(nil).SendDatagram), payload) + return &MockQUICConnectionSendDatagramCall{Call: call} +} + +// MockQUICConnectionSendDatagramCall wrap *gomock.Call +type MockQUICConnectionSendDatagramCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockQUICConnectionSendDatagramCall) Return(arg0 error) *MockQUICConnectionSendDatagramCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockQUICConnectionSendDatagramCall) Do(f func([]byte) error) *MockQUICConnectionSendDatagramCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockQUICConnectionSendDatagramCall) DoAndReturn(f func([]byte) error) *MockQUICConnectionSendDatagramCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/mocks/mockgen.go b/mocks/mockgen.go index 58c4124e..c17a48c8 100644 --- a/mocks/mockgen.go +++ b/mocks/mockgen.go @@ -5,3 +5,5 @@ package mocks //go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mocks -destination mock_limiter.go -source=../flow/limiter.go Limiter" //go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mocks -destination mock_resolvers.go -source=../prechecks/resolvers.go" + +//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package mocks -destination mock_quic_connection.go -source=../quic/quic_connection.go" diff --git a/prechecks/checker_test.go b/prechecks/checker_test.go index 2286b783..4bd968aa 100644 --- a/prechecks/checker_test.go +++ b/prechecks/checker_test.go @@ -8,7 +8,6 @@ import ( "time" "github.com/google/uuid" - "github.com/quic-go/quic-go" "github.com/rs/zerolog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -67,15 +66,6 @@ type nopConn struct{ net.Conn } func (nopConn) Close() error { return nil } -// fakeQUICConn satisfies quic.Connection for tests. Only CloseWithError is -// implemented; the pre-check never opens streams so the rest of the interface -// is unused via the embedded nil. -type fakeQUICConn struct { - quic.Connection -} - -func (*fakeQUICConn) CloseWithError(_ quic.ApplicationErrorCode, _ string) error { return nil } - // requireStatuses asserts the probe statuses in report.Results match // expected (in order), failing immediately on length mismatch. func requireStatuses(t *testing.T, report Report, expected ...Status) { @@ -94,6 +84,14 @@ func nopLogger() *zerolog.Logger { return &l } +// newFakeQUICConn creates a mock QUIC connection with CloseWithError +// expectation pre-configured so gomock does not fail at runtime. +func newFakeQUICConn(ctrl *gomock.Controller) *mocks.MockQUICConnection { + conn := mocks.NewMockQUICConnection(ctrl) + conn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + return conn +} + // --------------------------------------------------------------------------- // Tests // --------------------------------------------------------------------------- @@ -108,13 +106,14 @@ func TestRun_AllPass(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) dns.EXPECT().Resolve(gomock.Any()).Return(twoRegionAddrs(), nil) // twoRegionAddrs has 2 regions × 1 V4 address each = 2 dials per transport. tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil).Times(2) quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).Times(2) + Return(fakeQUICConn, nil).Times(2) mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil) @@ -166,6 +165,7 @@ func TestRun_HTTP2Blocked(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) + fakeQUICConn := newFakeQUICConn(ctrl) dns := mocks.NewMockDNSResolver(ctrl) tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) @@ -175,7 +175,7 @@ func TestRun_HTTP2Blocked(t *testing.T) { tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, errors.New("connection refused")).AnyTimes() quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).AnyTimes() + Return(fakeQUICConn, nil).AnyTimes() mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil) @@ -229,6 +229,7 @@ func TestRun_PartialRegionQUICFail(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) // Two regions: 1.2.3.4 (region1) and 5.6.7.8 (region2). dns.EXPECT().Resolve(gomock.Any()).Return(twoRegionAddrs(), nil) @@ -241,7 +242,7 @@ func TestRun_PartialRegionQUICFail(t *testing.T) { region1Addr := &net.UDPAddr{IP: net.ParseIP("1.2.3.4"), Port: 7844} region2Addr := &net.UDPAddr{IP: net.ParseIP("5.6.7.8"), Port: 7844} quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), region1Addr.AddrPort(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).AnyTimes() + Return(fakeQUICConn, nil).AnyTimes() quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), region2Addr.AddrPort(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, errors.New("connection refused")).AnyTimes() @@ -308,13 +309,14 @@ func TestRun_ManagementAPIFail(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) dns.EXPECT().Resolve(gomock.Any()).Return(twoRegionAddrs(), nil) // twoRegionAddrs has 2 regions × 1 V4 address each; each succeeds on first try. tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil).Times(2) quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).Times(2) + Return(fakeQUICConn, nil).Times(2) mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nil, errors.New("connection refused")).AnyTimes() @@ -339,13 +341,14 @@ func TestRun_RegionFlagForwardedToDNS(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) // The region string must be forwarded verbatim to the DNS resolver. dns.EXPECT().Resolve("us").Return(twoRegionAddrs(), nil) tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil).Times(2) quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).Times(2) + Return(fakeQUICConn, nil).Times(2) mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil) @@ -373,6 +376,7 @@ func TestRun_QUICUsesProbeConnIndex(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) dns.EXPECT().Resolve(gomock.Any()).Return(twoRegionAddrs(), nil) tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). @@ -383,7 +387,7 @@ func TestRun_QUICUsesProbeConnIndex(t *testing.T) { gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Eq(uint8(math.MaxUint8)), gomock.Any(), gomock.Any(), - ).Return(&fakeQUICConn{}, nil).Times(2) + ).Return(fakeQUICConn, nil).Times(2) mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil) @@ -401,13 +405,14 @@ func TestRun_BothFamiliesProbed(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) dns.EXPECT().Resolve(gomock.Any()).Return(twoRegionAddrsBothFamilies(), nil) // 2 regions × 2 families = 4 dial calls each for QUIC and HTTP/2. tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil).Times(4) quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).Times(4) + Return(fakeQUICConn, nil).Times(4) mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil) @@ -443,13 +448,14 @@ func TestRun_IPVersionRestriction(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) dns.EXPECT().Resolve(gomock.Any()).Return(twoRegionAddrsBothFamilies(), nil) // 2 regions × 1 addr per restricted family = 2 dials each. tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil).Times(2) quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).Times(2) + Return(fakeQUICConn, nil).Times(2) mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil) @@ -471,6 +477,7 @@ func TestRun_EdgeAddrs_SingleAddr(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) // DNS resolver must NOT be called when EdgeAddrs is set. dns := mocks.NewMockDNSResolver(ctrl) @@ -480,7 +487,7 @@ func TestRun_EdgeAddrs_SingleAddr(t *testing.T) { tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil).Times(1) quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).Times(1) + Return(fakeQUICConn, nil).Times(1) mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil) @@ -510,6 +517,7 @@ func TestRun_EdgeAddrs_MultipleAddrs(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) dns := mocks.NewMockDNSResolver(ctrl) dns.EXPECT().Resolve(gomock.Any()).Times(0) @@ -518,7 +526,7 @@ func TestRun_EdgeAddrs_MultipleAddrs(t *testing.T) { tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil).Times(2) quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).Times(2) + Return(fakeQUICConn, nil).Times(2) mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil) @@ -595,12 +603,13 @@ func TestRun_ProtocolOverride_HTTP2_BothPass(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) dns.EXPECT().Resolve(gomock.Any()).Return(twoRegionAddrs(), nil) tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil).AnyTimes() quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).AnyTimes() + Return(fakeQUICConn, nil).AnyTimes() mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil) @@ -630,12 +639,13 @@ func TestRun_ProtocolOverride_QUIC_BothPass(t *testing.T) { tcp := mocks.NewMockTCPDialer(ctrl) quicD := mocks.NewMockQUICDialer(ctrl) mgmt := mocks.NewMockManagementDialer(ctrl) + fakeQUICConn := newFakeQUICConn(ctrl) dns.EXPECT().Resolve(gomock.Any()).Return(twoRegionAddrs(), nil) tcp.EXPECT().DialEdge(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil).AnyTimes() quicD.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(&fakeQUICConn{}, nil).AnyTimes() + Return(fakeQUICConn, nil).AnyTimes() mgmt.EXPECT().DialContext(gomock.Any(), gomock.Any(), gomock.Any()). Return(nopConn{}, nil) diff --git a/prechecks/probes_test.go b/prechecks/probes_test.go index 1d2375b2..502800d3 100644 --- a/prechecks/probes_test.go +++ b/prechecks/probes_test.go @@ -7,7 +7,6 @@ import ( "net" "testing" - "github.com/quic-go/quic-go" "github.com/rs/zerolog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -33,67 +32,6 @@ const ( // perform a real TLS handshake, so an empty config is sufficient. var testTLSConfig = &tls.Config{} //nolint:gosec -// mockQuicConnection is a minimal test double for quic.Connection. -type mockQuicConnection struct { - closeErr error -} - -func (m *mockQuicConnection) AcceptStream(_ context.Context) (quic.Stream, error) { - return nil, nil -} - -func (m *mockQuicConnection) AcceptUniStream(_ context.Context) (quic.ReceiveStream, error) { - return nil, nil -} - -func (m *mockQuicConnection) OpenStream() (quic.Stream, error) { - return nil, nil -} - -func (m *mockQuicConnection) OpenStreamSync(_ context.Context) (quic.Stream, error) { - return nil, nil -} - -func (m *mockQuicConnection) OpenUniStream() (quic.SendStream, error) { - return nil, nil -} - -func (m *mockQuicConnection) OpenUniStreamSync(_ context.Context) (quic.SendStream, error) { - return nil, nil -} - -func (m *mockQuicConnection) LocalAddr() net.Addr { - return nil -} - -func (m *mockQuicConnection) RemoteAddr() net.Addr { - return nil -} - -func (m *mockQuicConnection) CloseWithError(_ quic.ApplicationErrorCode, _ string) error { - return m.closeErr -} - -func (m *mockQuicConnection) Context() context.Context { - return context.Background() -} - -func (m *mockQuicConnection) ConnectionState() quic.ConnectionState { - return quic.ConnectionState{} -} - -func (m *mockQuicConnection) SendDatagram(_ []byte) error { - return nil -} - -func (m *mockQuicConnection) ReceiveDatagram(_ context.Context) ([]byte, error) { - return nil, nil -} - -func (m *mockQuicConnection) AddPath(*quic.Transport) (*quic.Path, error) { - return nil, nil -} - // Helper to create test edge addresses. func createTestEdgeAddr(ip string, port int, version allregions.EdgeIPVersion) *allregions.EdgeAddr { parsedIP := net.ParseIP(ip) @@ -225,9 +163,10 @@ func TestProbeQUIC_Success(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - mockConn := &mockQuicConnection{} + successfulQUICConn := mocks.NewMockQUICConnection(ctrl) + successfulQUICConn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Return(nil) dialer := mocks.NewMockQUICDialer(ctrl) - dialer.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockConn, nil) + dialer.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(successfulQUICConn, nil) addr := createTestEdgeAddr("192.0.2.1", testEdgePort, allregions.V4) logger := zerolog.New(nil) @@ -263,9 +202,12 @@ func TestProbeQUIC_CloseErrorDoesNotAffectResult(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - mockConn := &mockQuicConnection{closeErr: errors.New("close failed")} + // Return a mock whose CloseWithError returns an error — probeQUIC must still + // report Pass because the handshake itself succeeded. + fakeQUICConn := mocks.NewMockQUICConnection(ctrl) + fakeQUICConn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Return(errors.New("close failed")) dialer := mocks.NewMockQUICDialer(ctrl) - dialer.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockConn, nil) + dialer.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(fakeQUICConn, nil) addr := createTestEdgeAddr("192.0.2.1", testEdgePort, allregions.V4) logger := zerolog.New(nil) @@ -505,10 +447,11 @@ func TestProbeQUIC_IPv6Address(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) defer ctrl.Finish() + successfulQUICConn := mocks.NewMockQUICConnection(ctrl) + successfulQUICConn.EXPECT().CloseWithError(gomock.Any(), gomock.Any()).Return(nil) - mockConn := &mockQuicConnection{} dialer := mocks.NewMockQUICDialer(ctrl) - dialer.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockConn, nil) + dialer.EXPECT().DialQuic(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(successfulQUICConn, nil) addr := createTestEdgeAddr("2001:db8::1", testEdgePort, allregions.V6) logger := zerolog.New(nil) diff --git a/prechecks/resolvers.go b/prechecks/resolvers.go index a3ea0e34..a04231cc 100644 --- a/prechecks/resolvers.go +++ b/prechecks/resolvers.go @@ -11,9 +11,8 @@ import ( "github.com/rs/zerolog" "github.com/cloudflare/cloudflared/connection/dialopts" - cfdquic "github.com/cloudflare/cloudflared/quic" - "github.com/cloudflare/cloudflared/edgediscovery/allregions" + cfdquic "github.com/cloudflare/cloudflared/quic" ) // DNSResolver abstracts edge DNS discovery used by DNS probes. diff --git a/quic/conversion.go b/quic/conversion.go index 0f20f461..5c397805 100644 --- a/quic/conversion.go +++ b/quic/conversion.go @@ -4,85 +4,85 @@ import ( "strconv" "time" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" ) -// Helper to convert logging.ByteCount(alias for int64) to float64 used in prometheus -func byteCountToPromCount(count logging.ByteCount) float64 { +// byteCountToPromCount converts an int64 byte count to float64 used in prometheus. +func byteCountToPromCount(count int64) float64 { return float64(count) } -// Helper to convert Duration to float64 used in prometheus +// durationToPromGauge converts a Duration to float64 milliseconds used in prometheus. func durationToPromGauge(duration time.Duration) float64 { return float64(duration.Milliseconds()) } -// Helper to convert https://pkg.go.dev/github.com/quic-go/quic-go@v0.23.0/logging#PacketType into string -func packetTypeString(pt logging.PacketType) string { +// packetTypeString converts a qlog.PacketType to a Prometheus-safe label string. +// The allowlist prevents unbounded cardinality if upstream adds new values. +func packetTypeString(pt qlog.PacketType) string { switch pt { - case logging.PacketTypeInitial: - return "initial" - case logging.PacketTypeHandshake: - return "handshake" - case logging.PacketTypeRetry: - return "retry" - case logging.PacketType0RTT: - return "0_rtt" - case logging.PacketTypeVersionNegotiation: - return "version_negotiation" - case logging.PacketType1RTT: - return "1_rtt" - case logging.PacketTypeStatelessReset: - return "stateless_reset" - case logging.PacketTypeNotDetermined: - return "undetermined" + case qlog.PacketTypeInitial, + qlog.PacketTypeHandshake, + qlog.PacketType0RTT, + qlog.PacketType1RTT, + qlog.PacketTypeRetry, + qlog.PacketTypeVersionNegotiation, + qlog.PacketTypeStatelessReset: + return string(pt) default: return "unknown_packet_type" } } -// Helper to convert https://pkg.go.dev/github.com/quic-go/quic-go@v0.23.0/logging#PacketDropReason into string -func packetDropReasonString(reason logging.PacketDropReason) string { +// packetDropReasonString converts a qlog.PacketDropReason to a Prometheus-safe label string. +// The allowlist passes known values through and guards against unbounded cardinality. +func packetDropReasonString(reason qlog.PacketDropReason) string { switch reason { - case logging.PacketDropKeyUnavailable: - return "key_unavailable" - case logging.PacketDropUnknownConnectionID: - return "unknown_conn_id" - case logging.PacketDropHeaderParseError: - return "header_parse_err" - case logging.PacketDropPayloadDecryptError: - return "payload_decrypt_err" - case logging.PacketDropProtocolViolation: - return "protocol_violation" - case logging.PacketDropDOSPrevention: - return "dos_prevention" - case logging.PacketDropUnsupportedVersion: - return "unsupported_version" - case logging.PacketDropUnexpectedPacket: - return "unexpected_packet" - case logging.PacketDropUnexpectedSourceConnectionID: - return "unexpected_src_conn_id" - case logging.PacketDropUnexpectedVersion: - return "unexpected_version" - case logging.PacketDropDuplicate: - return "duplicate" + case qlog.PacketDropKeyUnavailable, + qlog.PacketDropUnknownConnectionID, + qlog.PacketDropHeaderParseError, + qlog.PacketDropPayloadDecryptError, + qlog.PacketDropProtocolViolation, + qlog.PacketDropDOSPrevention, + qlog.PacketDropUnsupportedVersion, + qlog.PacketDropUnexpectedPacket, + qlog.PacketDropUnexpectedSourceConnectionID, + qlog.PacketDropUnexpectedVersion, + qlog.PacketDropDuplicate: + return string(reason) default: return "unknown_reason" } } -// Helper to convert https://pkg.go.dev/github.com/quic-go/quic-go@v0.23.0/logging#PacketLossReason into string -func packetLossReasonString(reason logging.PacketLossReason) string { +// packetLossReasonString converts a qlog.PacketLossReason to a Prometheus-safe label string. +func packetLossReasonString(reason qlog.PacketLossReason) string { switch reason { - case logging.PacketLossReorderingThreshold: - return "reordering" - case logging.PacketLossTimeThreshold: - return "timeout" + case qlog.PacketLossReorderingThreshold, + qlog.PacketLossTimeThreshold: + return string(reason) default: return "unknown_loss_reason" } } +// congestionStateToFloat maps a qlog.CongestionState string to a numeric value for prometheus gauges. +// Mapping: slow_start=0, congestion_avoidance=1, application_limited=2, recovery=3, unknown=-1. +func congestionStateToFloat(state qlog.CongestionState) float64 { + switch state { + case qlog.CongestionStateSlowStart: + return 0 + case qlog.CongestionStateCongestionAvoidance: + return 1 + case qlog.CongestionStateApplicationLimited: + return 2 + case qlog.CongestionStateRecovery: + return 3 + default: + return -1 + } +} + func uint8ToString(input uint8) string { return strconv.FormatUint(uint64(input), 10) } diff --git a/quic/datagram.go b/quic/datagram.go index cb5fde77..5f7dde6e 100644 --- a/quic/datagram.go +++ b/quic/datagram.go @@ -6,7 +6,6 @@ import ( "github.com/google/uuid" "github.com/pkg/errors" - "github.com/quic-go/quic-go" "github.com/rs/zerolog" "github.com/cloudflare/cloudflared/packet" @@ -25,12 +24,12 @@ type BaseDatagramMuxer interface { } type DatagramMuxer struct { - session quic.Connection + session QUICConnection logger *zerolog.Logger demuxChan chan<- *packet.Session } -func NewDatagramMuxer(quicSession quic.Connection, log *zerolog.Logger, demuxChan chan<- *packet.Session) *DatagramMuxer { +func NewDatagramMuxer(quicSession QUICConnection, log *zerolog.Logger, demuxChan chan<- *packet.Session) *DatagramMuxer { logger := log.With().Uint8("datagramVersion", 1).Logger() return &DatagramMuxer{ session: quicSession, diff --git a/quic/datagramv2.go b/quic/datagramv2.go index 73712d86..a19ed45c 100644 --- a/quic/datagramv2.go +++ b/quic/datagramv2.go @@ -141,7 +141,7 @@ func (dm *DatagramMuxerV2) demux(ctx context.Context, msgWithType []byte) error } msgType := DatagramV2Type(msgWithType[len(msgWithType)-typeIDLen]) msg := msgWithType[0 : len(msgWithType)-typeIDLen] - switch msgType { + switch msgType { //nolint:exhaustive // default handles all non-UDP types via handlePacket case DatagramTypeUDP: return dm.handleSession(ctx, msg) case DatagramTypeIP, DatagramTypeIPWithTrace, DatagramTypeTracingSpan: @@ -170,7 +170,7 @@ func (dm *DatagramMuxerV2) handleSession(ctx context.Context, session []byte) er func (dm *DatagramMuxerV2) handlePacket(ctx context.Context, pk []byte, msgType DatagramV2Type) error { var demuxedPacket Packet - switch msgType { + switch msgType { //nolint:exhaustive // DatagramTypeUDP is handled by the caller (demux) case DatagramTypeIP: demuxedPacket = RawPacket(packet.RawPacket{Data: pk}) case DatagramTypeIPWithTrace: diff --git a/quic/metrics.go b/quic/metrics.go index fb6f3e08..92d7555b 100644 --- a/quic/metrics.go +++ b/quic/metrics.go @@ -4,9 +4,10 @@ import ( "reflect" "strings" "sync" + "time" "github.com/prometheus/client_golang/prometheus" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" "github.com/rs/zerolog" ) @@ -175,7 +176,7 @@ var ( Namespace: namespace, Subsystem: "client", Name: "congestion_state", - Help: "Current congestion control state. See https://pkg.go.dev/github.com/quic-go/quic-go@v0.45.0/logging#CongestionState for what each value maps to", + Help: "Current congestion control state (0=slow_start, 1=congestion_avoidance, 2=application_limited, 3=recovery, -1=unknown)", }, []string{ConnectionIndexMetricLabel}, ), @@ -229,28 +230,37 @@ func (cc *clientCollector) startedConnection() { clientMetrics.totalConnections.Inc() } -func (cc *clientCollector) closedConnection(error) { +func (cc *clientCollector) closedConnection() { clientMetrics.closedConnections.Inc() } -func (cc *clientCollector) receivedTransportParameters(params *logging.TransportParameters) { - clientMetrics.maxUDPPayloadSize.WithLabelValues(cc.index).Set(float64(params.MaxUDPPayloadSize)) - cc.logger.Debug().Msgf("Received transport parameters: MaxUDPPayloadSize=%d, MaxIdleTimeout=%v, MaxDatagramFrameSize=%d", params.MaxUDPPayloadSize, params.MaxIdleTimeout, params.MaxDatagramFrameSize) +// receivedTransportParameters records metrics from the peer's transport parameters. +func (cc *clientCollector) receivedTransportParameters(maxUDPPayloadSize int64, maxIdleTimeout time.Duration, maxDatagramFrameSize int64) { + clientMetrics.maxUDPPayloadSize.WithLabelValues(cc.index).Set(float64(maxUDPPayloadSize)) + cc.logger. + Debug(). + Int64("MaxUDPPayloadSize", maxUDPPayloadSize). + Dur("MaxIdleTimeout", maxIdleTimeout). + Int64("MaxDatagramFrameSize", maxDatagramFrameSize).Msgf("Received transport parameters") } -func (cc *clientCollector) sentPackets(size logging.ByteCount, frames []logging.Frame) { +// sentPackets records metrics for sent packets. +func (cc *clientCollector) sentPackets(size int64, frames []qlog.Frame) { cc.collectPackets(size, frames, clientMetrics.sentFrames, clientMetrics.sentBytes, sent) } -func (cc *clientCollector) receivedPackets(size logging.ByteCount, frames []logging.Frame) { +// receivedPackets records metrics for received packets. +func (cc *clientCollector) receivedPackets(size int64, frames []qlog.Frame) { cc.collectPackets(size, frames, clientMetrics.receivedFrames, clientMetrics.receivedBytes, received) } -func (cc *clientCollector) bufferedPackets(packetType logging.PacketType) { +// bufferedPackets records metrics for buffered packets. +func (cc *clientCollector) bufferedPackets(packetType qlog.PacketType) { clientMetrics.bufferedPackets.WithLabelValues(cc.index, packetTypeString(packetType)).Inc() } -func (cc *clientCollector) droppedPackets(packetType logging.PacketType, size logging.ByteCount, reason logging.PacketDropReason) { +// droppedPackets records metrics for dropped packets. +func (cc *clientCollector) droppedPackets(packetType qlog.PacketType, size int64, reason qlog.PacketDropReason) { clientMetrics.droppedPackets.WithLabelValues( cc.index, packetTypeString(packetType), @@ -258,35 +268,43 @@ func (cc *clientCollector) droppedPackets(packetType logging.PacketType, size lo ).Add(byteCountToPromCount(size)) } -func (cc *clientCollector) lostPackets(reason logging.PacketLossReason) { +// lostPackets records metrics for lost packets. +func (cc *clientCollector) lostPackets(reason qlog.PacketLossReason) { clientMetrics.lostPackets.WithLabelValues(cc.index, packetLossReasonString(reason)).Inc() } -func (cc *clientCollector) updatedRTT(rtt *logging.RTTStats) { - clientMetrics.minRTT.WithLabelValues(cc.index).Set(durationToPromGauge(rtt.MinRTT())) - clientMetrics.latestRTT.WithLabelValues(cc.index).Set(durationToPromGauge(rtt.LatestRTT())) - clientMetrics.smoothedRTT.WithLabelValues(cc.index).Set(durationToPromGauge(rtt.SmoothedRTT())) +// updatedRTT records RTT metrics. +func (cc *clientCollector) updatedRTT(m qlog.MetricsUpdated) { + clientMetrics.minRTT.WithLabelValues(cc.index).Set(durationToPromGauge(m.MinRTT)) + clientMetrics.latestRTT.WithLabelValues(cc.index).Set(durationToPromGauge(m.LatestRTT)) + clientMetrics.smoothedRTT.WithLabelValues(cc.index).Set(durationToPromGauge(m.SmoothedRTT)) } -func (cc *clientCollector) updateCongestionWindow(size logging.ByteCount) { +// updateCongestionWindow records the congestion window size. +func (cc *clientCollector) updateCongestionWindow(size int64) { clientMetrics.congestionWindow.WithLabelValues(cc.index).Set(float64(size)) } -func (cc *clientCollector) updatedCongestionState(state logging.CongestionState) { - clientMetrics.congestionState.WithLabelValues(cc.index).Set(float64(state)) +// updatedCongestionState records the congestion control state. +func (cc *clientCollector) updatedCongestionState(state qlog.CongestionState) { + clientMetrics.congestionState.WithLabelValues(cc.index).Set(congestionStateToFloat(state)) } -func (cc *clientCollector) updateMTU(mtu logging.ByteCount) { +// updateMTU records the MTU value. +func (cc *clientCollector) updateMTU(mtu int64) { clientMetrics.mtu.WithLabelValues(cc.index).Set(float64(mtu)) cc.logger.Debug().Msgf("QUIC MTU updated to %d", mtu) } -func (cc *clientCollector) collectPackets(size logging.ByteCount, frames []logging.Frame, counter, bandwidth *prometheus.CounterVec, direction direction) { +// collectPackets is the shared implementation for sentPackets and receivedPackets. +func (cc *clientCollector) collectPackets(size int64, frames []qlog.Frame, counter, bandwidth *prometheus.CounterVec, direction direction) { for _, frame := range frames { - switch f := frame.(type) { - case logging.DataBlockedFrame: - cc.logger.Debug().Msgf("%s data_blocked frame", direction) - case logging.StreamDataBlockedFrame: + // qlog.Frame.Frame holds the concrete wire frame type as any. + // The quic-go encoder always stores pointers (*wire.XxxFrame). + switch f := frame.Frame.(type) { + case *qlog.DataBlockedFrame: + cc.logger.Debug().Int64("limit", int64(f.MaximumData)).Msgf("%s data_blocked frame", direction) + case *qlog.StreamDataBlockedFrame: cc.logger.Debug().Int64("streamID", int64(f.StreamID)).Msgf("%s stream_data_blocked frame", direction) } counter.WithLabelValues(cc.index, frameName(frame)).Inc() @@ -294,13 +312,16 @@ func (cc *clientCollector) collectPackets(size logging.ByteCount, frames []loggi bandwidth.WithLabelValues(cc.index).Add(byteCountToPromCount(size)) } -func frameName(frame logging.Frame) string { - if frame == nil { +// frameName extracts the type name from a qlog.Frame for use as a Prometheus label. +func frameName(frame qlog.Frame) string { + if frame.Frame == nil { return "nil" - } else { - name := reflect.TypeOf(frame).Elem().Name() - return strings.TrimSuffix(name, "Frame") } + t := reflect.TypeOf(frame.Frame) + if t.Kind() == reflect.Pointer { + t = t.Elem() + } + return strings.TrimSuffix(t.Name(), "Frame") } type direction uint8 diff --git a/quic/quic_connection.go b/quic/quic_connection.go index d8253fe1..8c384395 100644 --- a/quic/quic_connection.go +++ b/quic/quic_connection.go @@ -12,9 +12,9 @@ import ( // QUICConnection defines the subset of [quic.Connection] methods used by cloudflared. // Consumers should accept this interface; producers should return [*ConnWithCloser]. type QUICConnection interface { - AcceptStream(ctx context.Context) (quic.Stream, error) - OpenStream() (quic.Stream, error) - OpenStreamSync(ctx context.Context) (quic.Stream, error) + AcceptStream(ctx context.Context) (*quic.Stream, error) + OpenStream() (*quic.Stream, error) + OpenStreamSync(ctx context.Context) (*quic.Stream, error) CloseWithError(code quic.ApplicationErrorCode, reason string) error Context() context.Context SendDatagram(payload []byte) error @@ -28,9 +28,9 @@ type QUICConnection interface { var _ QUICConnection = (*ConnWithCloser)(nil) var ( - // error returned when the [NewConnWithCloser] is called with a nil conn argument + // error returned when the [NewQUICConnection] is called with a nil conn argument ErrNilQuicConnection = errors.New("the provided quic connection is nil") - // error returned when the [NewConnWithCloser] is called with a nil closer argument + // error returned when the [NewQUICConnection] is called with a nil closer argument ErrNilCloser = errors.New("the provided closer is nil") ) @@ -38,16 +38,15 @@ var ( // underlying [*net.UDPConn]). When [CloseWithError] is called the QUIC // connection is closed first, then the closer is closed deterministically. // -// A nil conn is only safe for [CloseWithError] (used in tests). All other -// delegated methods will panic on a nil conn. +// All fields are non-nil after successful construction via [NewQUICConnection]. type ConnWithCloser struct { - conn quic.Connection + conn *quic.Conn closer io.Closer } // NewQUICConnection returns a [*ConnWithCloser] that will close closer after // the QUIC connection is closed. -func NewQUICConnection(conn quic.Connection, closer io.Closer) (*ConnWithCloser, error) { +func NewQUICConnection(conn *quic.Conn, closer io.Closer) (*ConnWithCloser, error) { if conn == nil { return nil, ErrNilQuicConnection } @@ -68,15 +67,15 @@ func (c *ConnWithCloser) CloseWithError(code quic.ApplicationErrorCode, reason s return errors.Join(connErr, closerErr) } -func (c *ConnWithCloser) AcceptStream(ctx context.Context) (quic.Stream, error) { +func (c *ConnWithCloser) AcceptStream(ctx context.Context) (*quic.Stream, error) { return c.conn.AcceptStream(ctx) } -func (c *ConnWithCloser) OpenStream() (quic.Stream, error) { +func (c *ConnWithCloser) OpenStream() (*quic.Stream, error) { return c.conn.OpenStream() } -func (c *ConnWithCloser) OpenStreamSync(ctx context.Context) (quic.Stream, error) { +func (c *ConnWithCloser) OpenStreamSync(ctx context.Context) (*quic.Stream, error) { return c.conn.OpenStreamSync(ctx) } diff --git a/quic/quic_connection_test.go b/quic/quic_connection_test.go index 7f208d5d..15ada82e 100644 --- a/quic/quic_connection_test.go +++ b/quic/quic_connection_test.go @@ -1,7 +1,6 @@ package quic import ( - "errors" "testing" "github.com/quic-go/quic-go" @@ -17,16 +16,6 @@ func (m *mockCloser) Close() error { return m.closeErr } -// mockQuicConnection is a minimal test double for [quic.Connection]. -type mockQuicConnection struct { - quic.Connection - closeWithErrorErr error -} - -func (m *mockQuicConnection) CloseWithError(_ quic.ApplicationErrorCode, _ string) error { - return m.closeWithErrorErr -} - func TestNewConnWithCloser_NilConn(t *testing.T) { t.Parallel() conn, err := NewQUICConnection(nil, &mockCloser{}) @@ -36,73 +25,7 @@ func TestNewConnWithCloser_NilConn(t *testing.T) { func TestNewConnWithCloser_NilCloser(t *testing.T) { t.Parallel() - conn, err := NewQUICConnection(&mockQuicConnection{}, nil) + conn, err := NewQUICConnection(&quic.Conn{}, nil) require.ErrorIs(t, err, ErrNilCloser) require.Nil(t, conn) } - -func TestNewConnWithCloser_Success(t *testing.T) { - t.Parallel() - qc := &mockQuicConnection{} - cl := &mockCloser{} - conn, err := NewQUICConnection(qc, cl) - require.NoError(t, err) - require.NotNil(t, conn) -} - -func TestConnWithCloser_CloseWithError_BothSucceed(t *testing.T) { - t.Parallel() - qc := &mockQuicConnection{} - cl := &mockCloser{} - conn, err := NewQUICConnection(qc, cl) - require.NoError(t, err) - - err = conn.CloseWithError(0, "test") - require.NoError(t, err) -} - -func TestConnWithCloser_CloseWithError_QuicFails(t *testing.T) { - t.Parallel() - quicErr := errors.New("quic close failed") - qc := &mockQuicConnection{closeWithErrorErr: quicErr} - cl := &mockCloser{} - conn, err := NewQUICConnection(qc, cl) - require.NoError(t, err) - - err = conn.CloseWithError(0, "test") - require.ErrorIs(t, err, quicErr) -} - -func TestConnWithCloser_CloseWithError_CloserFails(t *testing.T) { - t.Parallel() - closerErr := errors.New("closer failed") - qc := &mockQuicConnection{} - cl := &mockCloser{closeErr: closerErr} - conn, err := NewQUICConnection(qc, cl) - require.NoError(t, err) - - err = conn.CloseWithError(0, "test") - require.ErrorIs(t, err, closerErr) -} - -func TestConnWithCloser_CloseWithError_BothFail(t *testing.T) { - t.Parallel() - quicErr := errors.New("quic close failed") - closerErr := errors.New("closer failed") - qc := &mockQuicConnection{closeWithErrorErr: quicErr} - cl := &mockCloser{closeErr: closerErr} - conn, err := NewQUICConnection(qc, cl) - require.NoError(t, err) - - err = conn.CloseWithError(0, "test") - require.ErrorIs(t, err, quicErr) - require.ErrorIs(t, err, closerErr) -} - -// TestConnWithCloser_ImplementsInterface is a runtime assertion that -// *ConnWithCloser satisfies QUICConnection. The compile-time assertion is in -// quic_connection.go. -func TestConnWithCloser_ImplementsInterface(t *testing.T) { - t.Parallel() - var _ QUICConnection = (*ConnWithCloser)(nil) -} diff --git a/quic/safe_stream.go b/quic/safe_stream.go index a1575b46..377342a6 100644 --- a/quic/safe_stream.go +++ b/quic/safe_stream.go @@ -17,13 +17,13 @@ var idleTimeoutError = quic.IdleTimeoutError{} type SafeStreamCloser struct { lock sync.Mutex - stream quic.Stream + stream *quic.Stream writeTimeout time.Duration log *zerolog.Logger closing atomic.Bool } -func NewSafeStreamCloser(stream quic.Stream, writeTimeout time.Duration, log *zerolog.Logger) *SafeStreamCloser { +func NewSafeStreamCloser(stream *quic.Stream, writeTimeout time.Duration, log *zerolog.Logger) *SafeStreamCloser { return &SafeStreamCloser{ stream: stream, writeTimeout: writeTimeout, diff --git a/quic/tracing.go b/quic/tracing.go index e5849d4d..c01154c5 100644 --- a/quic/tracing.go +++ b/quic/tracing.go @@ -2,19 +2,20 @@ package quic import ( "context" - "net" + "time" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" + "github.com/quic-go/quic-go/qlogwriter" "github.com/rs/zerolog" ) -// QUICTracer is a wrapper to create new quicConnTracer +// tracer builds a connTracer for each new QUIC connection. type tracer struct { index string logger *zerolog.Logger } -func NewClientTracer(logger *zerolog.Logger, index uint8) func(context.Context, logging.Perspective, logging.ConnectionID) *logging.ConnectionTracer { +func NewClientTracer(logger *zerolog.Logger, index uint8) func(context.Context, bool, qlog.ConnectionID) qlogwriter.Trace { t := &tracer{ index: uint8ToString(index), logger: logger, @@ -22,85 +23,111 @@ func NewClientTracer(logger *zerolog.Logger, index uint8) func(context.Context, return t.TracerForConnection } -func (t *tracer) TracerForConnection(_ctx context.Context, _p logging.Perspective, _odcid logging.ConnectionID) *logging.ConnectionTracer { +// TracerForConnection returns a qlogwriter.Trace for a new connection. +func (t *tracer) TracerForConnection(_ context.Context, _ bool, _ qlog.ConnectionID) qlogwriter.Trace { return newConnTracer(newClientCollector(t.index, t.logger)) } -// connTracer collects connection level metrics +// connTracer collects connection level metrics. It implements +// qlogwriter.Trace + qlogwriter.Recorder and dispatches qlog events to the +// metric-collection methods via RecordEvent. type connTracer struct { metricsCollector *clientCollector } -func newConnTracer(metricsCollector *clientCollector) *logging.ConnectionTracer { - tracer := connTracer{ +func newConnTracer(metricsCollector *clientCollector) *connTracer { + return &connTracer{ metricsCollector: metricsCollector, } - return &logging.ConnectionTracer{ - StartedConnection: tracer.StartedConnection, - ClosedConnection: tracer.ClosedConnection, - ReceivedTransportParameters: tracer.ReceivedTransportParameters, - SentLongHeaderPacket: tracer.SentLongHeaderPacket, - SentShortHeaderPacket: tracer.SentShortHeaderPacket, - ReceivedLongHeaderPacket: tracer.ReceivedLongHeaderPacket, - ReceivedShortHeaderPacket: tracer.ReceivedShortHeaderPacket, - BufferedPacket: tracer.BufferedPacket, - DroppedPacket: tracer.DroppedPacket, - UpdatedMetrics: tracer.UpdatedMetrics, - LostPacket: tracer.LostPacket, - UpdatedMTU: tracer.UpdatedMTU, - UpdatedCongestionState: tracer.UpdatedCongestionState, - } } -func (ct *connTracer) StartedConnection(local, remote net.Addr, srcConnID, destConnID logging.ConnectionID) { +func (ct *connTracer) AddProducer() qlogwriter.Recorder { + // connTracer is both the Trace and the Recorder: each connection gets + // exactly one producer that routes events to the collector methods below. + return ct +} + +func (ct *connTracer) SupportsSchemas(_ string) bool { + return true +} + +// RecordEvent dispatches qlog events to the collector methods. +func (ct *connTracer) RecordEvent(ev qlogwriter.Event) { + switch e := ev.(type) { + case qlog.StartedConnection: + ct.StartedConnection() + case qlog.ConnectionClosed: + ct.ClosedConnection() + case qlog.ParametersSet: + // ParametersSet fires for both local and remote; filter to remote only + // via the Initiator field. + if e.Initiator == qlog.InitiatorRemote { + ct.ReceivedTransportParameters(int64(e.MaxUDPPayloadSize), e.MaxIdleTimeout, int64(e.MaxDatagramFrameSize)) + } + case qlog.PacketSent: + ct.SentPacket(int64(e.Raw.Length), e.Frames) + case qlog.PacketReceived: + ct.ReceivedPacket(int64(e.Raw.Length), e.Frames) + case qlog.PacketBuffered: + ct.BufferedPacket(e.Header.PacketType) + case qlog.PacketDropped: + ct.DroppedPacket(e.Header.PacketType, int64(e.Raw.Length), e.Trigger) + case qlog.PacketLost: + ct.LostPacket(e.Trigger) + case qlog.MetricsUpdated: + ct.UpdatedMetrics(e) + case qlog.MTUUpdated: + ct.UpdatedMTU(int64(e.Value)) + case qlog.CongestionStateUpdated: + ct.UpdatedCongestionState(e.State) + } +} + +func (ct *connTracer) Close() error { + return nil +} + +func (ct *connTracer) StartedConnection() { ct.metricsCollector.startedConnection() } -func (ct *connTracer) ClosedConnection(err error) { - ct.metricsCollector.closedConnection(err) +func (ct *connTracer) ClosedConnection() { + ct.metricsCollector.closedConnection() } -func (ct *connTracer) ReceivedTransportParameters(params *logging.TransportParameters) { - ct.metricsCollector.receivedTransportParameters(params) +func (ct *connTracer) ReceivedTransportParameters(maxUDPPayloadSize int64, maxIdleTimeout time.Duration, maxDatagramFrameSize int64) { + ct.metricsCollector.receivedTransportParameters(maxUDPPayloadSize, maxIdleTimeout, maxDatagramFrameSize) } -func (ct *connTracer) BufferedPacket(pt logging.PacketType, size logging.ByteCount) { +func (ct *connTracer) SentPacket(size int64, frames []qlog.Frame) { + ct.metricsCollector.sentPackets(size, frames) +} + +func (ct *connTracer) ReceivedPacket(size int64, frames []qlog.Frame) { + ct.metricsCollector.receivedPackets(size, frames) +} + +func (ct *connTracer) BufferedPacket(pt qlog.PacketType) { ct.metricsCollector.bufferedPackets(pt) } -func (ct *connTracer) DroppedPacket(pt logging.PacketType, number logging.PacketNumber, size logging.ByteCount, reason logging.PacketDropReason) { +func (ct *connTracer) DroppedPacket(pt qlog.PacketType, size int64, reason qlog.PacketDropReason) { ct.metricsCollector.droppedPackets(pt, size, reason) } -func (ct *connTracer) LostPacket(level logging.EncryptionLevel, number logging.PacketNumber, reason logging.PacketLossReason) { +func (ct *connTracer) LostPacket(reason qlog.PacketLossReason) { ct.metricsCollector.lostPackets(reason) } -func (ct *connTracer) UpdatedMetrics(rttStats *logging.RTTStats, cwnd, bytesInFlight logging.ByteCount, packetsInFlight int) { - ct.metricsCollector.updatedRTT(rttStats) - ct.metricsCollector.updateCongestionWindow(cwnd) +func (ct *connTracer) UpdatedMetrics(m qlog.MetricsUpdated) { + ct.metricsCollector.updatedRTT(m) + ct.metricsCollector.updateCongestionWindow(int64(m.CongestionWindow)) } -func (ct *connTracer) SentLongHeaderPacket(hdr *logging.ExtendedHeader, size logging.ByteCount, ecn logging.ECN, ack *logging.AckFrame, frames []logging.Frame) { - ct.metricsCollector.sentPackets(size, frames) -} - -func (ct *connTracer) SentShortHeaderPacket(hdr *logging.ShortHeader, size logging.ByteCount, ecn logging.ECN, ack *logging.AckFrame, frames []logging.Frame) { - ct.metricsCollector.sentPackets(size, frames) -} - -func (ct *connTracer) ReceivedLongHeaderPacket(hdr *logging.ExtendedHeader, size logging.ByteCount, ecn logging.ECN, frames []logging.Frame) { - ct.metricsCollector.receivedPackets(size, frames) -} - -func (ct *connTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, size logging.ByteCount, ecn logging.ECN, frames []logging.Frame) { - ct.metricsCollector.receivedPackets(size, frames) -} - -func (ct *connTracer) UpdatedMTU(mtu logging.ByteCount, done bool) { +func (ct *connTracer) UpdatedMTU(mtu int64) { ct.metricsCollector.updateMTU(mtu) } -func (ct *connTracer) UpdatedCongestionState(state logging.CongestionState) { +func (ct *connTracer) UpdatedCongestionState(state qlog.CongestionState) { ct.metricsCollector.updatedCongestionState(state) } diff --git a/vendor/github.com/go-task/slim-sprig/v3/.editorconfig b/vendor/github.com/go-task/slim-sprig/v3/.editorconfig deleted file mode 100644 index b0c95367..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/.editorconfig +++ /dev/null @@ -1,14 +0,0 @@ -# editorconfig.org - -root = true - -[*] -insert_final_newline = true -charset = utf-8 -trim_trailing_whitespace = true -indent_style = tab -indent_size = 8 - -[*.{md,yml,yaml,json}] -indent_style = space -indent_size = 2 diff --git a/vendor/github.com/go-task/slim-sprig/v3/.gitattributes b/vendor/github.com/go-task/slim-sprig/v3/.gitattributes deleted file mode 100644 index 176a458f..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* text=auto diff --git a/vendor/github.com/go-task/slim-sprig/v3/.gitignore b/vendor/github.com/go-task/slim-sprig/v3/.gitignore deleted file mode 100644 index 5e3002f8..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -vendor/ -/.glide diff --git a/vendor/github.com/go-task/slim-sprig/v3/CHANGELOG.md b/vendor/github.com/go-task/slim-sprig/v3/CHANGELOG.md deleted file mode 100644 index 2ce45dd4..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/CHANGELOG.md +++ /dev/null @@ -1,383 +0,0 @@ -# Changelog - -## Release 3.2.3 (2022-11-29) - -### Changed - -- Updated docs (thanks @book987 @aJetHorn @neelayu @pellizzetti @apricote @SaigyoujiYuyuko233 @AlekSi) -- #348: Updated huandu/xstrings which fixed a snake case bug (thanks @yxxhero) -- #353: Updated masterminds/semver which included bug fixes -- #354: Updated golang.org/x/crypto which included bug fixes - -## Release 3.2.2 (2021-02-04) - -This is a re-release of 3.2.1 to satisfy something with the Go module system. - -## Release 3.2.1 (2021-02-04) - -### Changed - -- Upgraded `Masterminds/goutils` to `v1.1.1`. see the [Security Advisory](https://github.com/Masterminds/goutils/security/advisories/GHSA-xg2h-wx96-xgxr) - -## Release 3.2.0 (2020-12-14) - -### Added - -- #211: Added randInt function (thanks @kochurovro) -- #223: Added fromJson and mustFromJson functions (thanks @mholt) -- #242: Added a bcrypt function (thanks @robbiet480) -- #253: Added randBytes function (thanks @MikaelSmith) -- #254: Added dig function for dicts (thanks @nyarly) -- #257: Added regexQuoteMeta for quoting regex metadata (thanks @rheaton) -- #261: Added filepath functions osBase, osDir, osExt, osClean, osIsAbs (thanks @zugl) -- #268: Added and and all functions for testing conditions (thanks @phuslu) -- #181: Added float64 arithmetic addf, add1f, subf, divf, mulf, maxf, and minf - (thanks @andrewmostello) -- #265: Added chunk function to split array into smaller arrays (thanks @karelbilek) -- #270: Extend certificate functions to handle non-RSA keys + add support for - ed25519 keys (thanks @misberner) - -### Changed - -- Removed testing and support for Go 1.12. ed25519 support requires Go 1.13 or newer -- Using semver 3.1.1 and mergo 0.3.11 - -### Fixed - -- #249: Fix htmlDateInZone example (thanks @spawnia) - -NOTE: The dependency github.com/imdario/mergo reverted the breaking change in -0.3.9 via 0.3.10 release. - -## Release 3.1.0 (2020-04-16) - -NOTE: The dependency github.com/imdario/mergo made a behavior change in 0.3.9 -that impacts sprig functionality. Do not use sprig with a version newer than 0.3.8. - -### Added - -- #225: Added support for generating htpasswd hash (thanks @rustycl0ck) -- #224: Added duration filter (thanks @frebib) -- #205: Added `seq` function (thanks @thadc23) - -### Changed - -- #203: Unlambda functions with correct signature (thanks @muesli) -- #236: Updated the license formatting for GitHub display purposes -- #238: Updated package dependency versions. Note, mergo not updated to 0.3.9 - as it causes a breaking change for sprig. That issue is tracked at - https://github.com/imdario/mergo/issues/139 - -### Fixed - -- #229: Fix `seq` example in docs (thanks @kalmant) - -## Release 3.0.2 (2019-12-13) - -### Fixed - -- #220: Updating to semver v3.0.3 to fix issue with <= ranges -- #218: fix typo elyptical->elliptic in ecdsa key description (thanks @laverya) - -## Release 3.0.1 (2019-12-08) - -### Fixed - -- #212: Updated semver fixing broken constraint checking with ^0.0 - -## Release 3.0.0 (2019-10-02) - -### Added - -- #187: Added durationRound function (thanks @yjp20) -- #189: Added numerous template functions that return errors rather than panic (thanks @nrvnrvn) -- #193: Added toRawJson support (thanks @Dean-Coakley) -- #197: Added get support to dicts (thanks @Dean-Coakley) - -### Changed - -- #186: Moving dependency management to Go modules -- #186: Updated semver to v3. This has changes in the way ^ is handled -- #194: Updated documentation on merging and how it copies. Added example using deepCopy -- #196: trunc now supports negative values (thanks @Dean-Coakley) - -## Release 2.22.0 (2019-10-02) - -### Added - -- #173: Added getHostByName function to resolve dns names to ips (thanks @fcgravalos) -- #195: Added deepCopy function for use with dicts - -### Changed - -- Updated merge and mergeOverwrite documentation to explain copying and how to - use deepCopy with it - -## Release 2.21.0 (2019-09-18) - -### Added - -- #122: Added encryptAES/decryptAES functions (thanks @n0madic) -- #128: Added toDecimal support (thanks @Dean-Coakley) -- #169: Added list contcat (thanks @astorath) -- #174: Added deepEqual function (thanks @bonifaido) -- #170: Added url parse and join functions (thanks @astorath) - -### Changed - -- #171: Updated glide config for Google UUID to v1 and to add ranges to semver and testify - -### Fixed - -- #172: Fix semver wildcard example (thanks @piepmatz) -- #175: Fix dateInZone doc example (thanks @s3than) - -## Release 2.20.0 (2019-06-18) - -### Added - -- #164: Adding function to get unix epoch for a time (@mattfarina) -- #166: Adding tests for date_in_zone (@mattfarina) - -### Changed - -- #144: Fix function comments based on best practices from Effective Go (@CodeLingoTeam) -- #150: Handles pointer type for time.Time in "htmlDate" (@mapreal19) -- #161, #157, #160, #153, #158, #156, #155, #159, #152 documentation updates (@badeadan) - -### Fixed - -## Release 2.19.0 (2019-03-02) - -IMPORTANT: This release reverts a change from 2.18.0 - -In the previous release (2.18), we prematurely merged a partial change to the crypto functions that led to creating two sets of crypto functions (I blame @technosophos -- since that's me). This release rolls back that change, and does what was originally intended: It alters the existing crypto functions to use secure random. - -We debated whether this classifies as a change worthy of major revision, but given the proximity to the last release, we have decided that treating 2.18 as a faulty release is the correct course of action. We apologize for any inconvenience. - -### Changed - -- Fix substr panic 35fb796 (Alexey igrychev) -- Remove extra period 1eb7729 (Matthew Lorimor) -- Make random string functions use crypto by default 6ceff26 (Matthew Lorimor) -- README edits/fixes/suggestions 08fe136 (Lauri Apple) - - -## Release 2.18.0 (2019-02-12) - -### Added - -- Added mergeOverwrite function -- cryptographic functions that use secure random (see fe1de12) - -### Changed - -- Improve documentation of regexMatch function, resolves #139 90b89ce (Jan Tagscherer) -- Handle has for nil list 9c10885 (Daniel Cohen) -- Document behaviour of mergeOverwrite fe0dbe9 (Lukas Rieder) -- doc: adds missing documentation. 4b871e6 (Fernandez Ludovic) -- Replace outdated goutils imports 01893d2 (Matthew Lorimor) -- Surface crypto secure random strings from goutils fe1de12 (Matthew Lorimor) -- Handle untyped nil values as paramters to string functions 2b2ec8f (Morten Torkildsen) - -### Fixed - -- Fix dict merge issue and provide mergeOverwrite .dst .src1 to overwrite from src -> dst 4c59c12 (Lukas Rieder) -- Fix substr var names and comments d581f80 (Dean Coakley) -- Fix substr documentation 2737203 (Dean Coakley) - -## Release 2.17.1 (2019-01-03) - -### Fixed - -The 2.17.0 release did not have a version pinned for xstrings, which caused compilation failures when xstrings < 1.2 was used. This adds the correct version string to glide.yaml. - -## Release 2.17.0 (2019-01-03) - -### Added - -- adds alder32sum function and test 6908fc2 (marshallford) -- Added kebabcase function ca331a1 (Ilyes512) - -### Changed - -- Update goutils to 1.1.0 4e1125d (Matt Butcher) - -### Fixed - -- Fix 'has' documentation e3f2a85 (dean-coakley) -- docs(dict): fix typo in pick example dc424f9 (Dustin Specker) -- fixes spelling errors... not sure how that happened 4cf188a (marshallford) - -## Release 2.16.0 (2018-08-13) - -### Added - -- add splitn function fccb0b0 (Helgi Þorbjörnsson) -- Add slice func df28ca7 (gongdo) -- Generate serial number a3bdffd (Cody Coons) -- Extract values of dict with values function df39312 (Lawrence Jones) - -### Changed - -- Modify panic message for list.slice ae38335 (gongdo) -- Minor improvement in code quality - Removed an unreachable piece of code at defaults.go#L26:6 - Resolve formatting issues. 5834241 (Abhishek Kashyap) -- Remove duplicated documentation 1d97af1 (Matthew Fisher) -- Test on go 1.11 49df809 (Helgi Þormar Þorbjörnsson) - -### Fixed - -- Fix file permissions c5f40b5 (gongdo) -- Fix example for buildCustomCert 7779e0d (Tin Lam) - -## Release 2.15.0 (2018-04-02) - -### Added - -- #68 and #69: Add json helpers to docs (thanks @arunvelsriram) -- #66: Add ternary function (thanks @binoculars) -- #67: Allow keys function to take multiple dicts (thanks @binoculars) -- #89: Added sha1sum to crypto function (thanks @benkeil) -- #81: Allow customizing Root CA that used by genSignedCert (thanks @chenzhiwei) -- #92: Add travis testing for go 1.10 -- #93: Adding appveyor config for windows testing - -### Changed - -- #90: Updating to more recent dependencies -- #73: replace satori/go.uuid with google/uuid (thanks @petterw) - -### Fixed - -- #76: Fixed documentation typos (thanks @Thiht) -- Fixed rounding issue on the `ago` function. Note, the removes support for Go 1.8 and older - -## Release 2.14.1 (2017-12-01) - -### Fixed - -- #60: Fix typo in function name documentation (thanks @neil-ca-moore) -- #61: Removing line with {{ due to blocking github pages genertion -- #64: Update the list functions to handle int, string, and other slices for compatibility - -## Release 2.14.0 (2017-10-06) - -This new version of Sprig adds a set of functions for generating and working with SSL certificates. - -- `genCA` generates an SSL Certificate Authority -- `genSelfSignedCert` generates an SSL self-signed certificate -- `genSignedCert` generates an SSL certificate and key based on a given CA - -## Release 2.13.0 (2017-09-18) - -This release adds new functions, including: - -- `regexMatch`, `regexFindAll`, `regexFind`, `regexReplaceAll`, `regexReplaceAllLiteral`, and `regexSplit` to work with regular expressions -- `floor`, `ceil`, and `round` math functions -- `toDate` converts a string to a date -- `nindent` is just like `indent` but also prepends a new line -- `ago` returns the time from `time.Now` - -### Added - -- #40: Added basic regex functionality (thanks @alanquillin) -- #41: Added ceil floor and round functions (thanks @alanquillin) -- #48: Added toDate function (thanks @andreynering) -- #50: Added nindent function (thanks @binoculars) -- #46: Added ago function (thanks @slayer) - -### Changed - -- #51: Updated godocs to include new string functions (thanks @curtisallen) -- #49: Added ability to merge multiple dicts (thanks @binoculars) - -## Release 2.12.0 (2017-05-17) - -- `snakecase`, `camelcase`, and `shuffle` are three new string functions -- `fail` allows you to bail out of a template render when conditions are not met - -## Release 2.11.0 (2017-05-02) - -- Added `toJson` and `toPrettyJson` -- Added `merge` -- Refactored documentation - -## Release 2.10.0 (2017-03-15) - -- Added `semver` and `semverCompare` for Semantic Versions -- `list` replaces `tuple` -- Fixed issue with `join` -- Added `first`, `last`, `intial`, `rest`, `prepend`, `append`, `toString`, `toStrings`, `sortAlpha`, `reverse`, `coalesce`, `pluck`, `pick`, `compact`, `keys`, `omit`, `uniq`, `has`, `without` - -## Release 2.9.0 (2017-02-23) - -- Added `splitList` to split a list -- Added crypto functions of `genPrivateKey` and `derivePassword` - -## Release 2.8.0 (2016-12-21) - -- Added access to several path functions (`base`, `dir`, `clean`, `ext`, and `abs`) -- Added functions for _mutating_ dictionaries (`set`, `unset`, `hasKey`) - -## Release 2.7.0 (2016-12-01) - -- Added `sha256sum` to generate a hash of an input -- Added functions to convert a numeric or string to `int`, `int64`, `float64` - -## Release 2.6.0 (2016-10-03) - -- Added a `uuidv4` template function for generating UUIDs inside of a template. - -## Release 2.5.0 (2016-08-19) - -- New `trimSuffix`, `trimPrefix`, `hasSuffix`, and `hasPrefix` functions -- New aliases have been added for a few functions that didn't follow the naming conventions (`trimAll` and `abbrevBoth`) -- `trimall` and `abbrevboth` (notice the case) are deprecated and will be removed in 3.0.0 - -## Release 2.4.0 (2016-08-16) - -- Adds two functions: `until` and `untilStep` - -## Release 2.3.0 (2016-06-21) - -- cat: Concatenate strings with whitespace separators. -- replace: Replace parts of a string: `replace " " "-" "Me First"` renders "Me-First" -- plural: Format plurals: `len "foo" | plural "one foo" "many foos"` renders "many foos" -- indent: Indent blocks of text in a way that is sensitive to "\n" characters. - -## Release 2.2.0 (2016-04-21) - -- Added a `genPrivateKey` function (Thanks @bacongobbler) - -## Release 2.1.0 (2016-03-30) - -- `default` now prints the default value when it does not receive a value down the pipeline. It is much safer now to do `{{.Foo | default "bar"}}`. -- Added accessors for "hermetic" functions. These return only functions that, when given the same input, produce the same output. - -## Release 2.0.0 (2016-03-29) - -Because we switched from `int` to `int64` as the return value for all integer math functions, the library's major version number has been incremented. - -- `min` complements `max` (formerly `biggest`) -- `empty` indicates that a value is the empty value for its type -- `tuple` creates a tuple inside of a template: `{{$t := tuple "a", "b" "c"}}` -- `dict` creates a dictionary inside of a template `{{$d := dict "key1" "val1" "key2" "val2"}}` -- Date formatters have been added for HTML dates (as used in `date` input fields) -- Integer math functions can convert from a number of types, including `string` (via `strconv.ParseInt`). - -## Release 1.2.0 (2016-02-01) - -- Added quote and squote -- Added b32enc and b32dec -- add now takes varargs -- biggest now takes varargs - -## Release 1.1.0 (2015-12-29) - -- Added #4: Added contains function. strings.Contains, but with the arguments - switched to simplify common pipelines. (thanks krancour) -- Added Travis-CI testing support - -## Release 1.0.0 (2015-12-23) - -- Initial release diff --git a/vendor/github.com/go-task/slim-sprig/v3/LICENSE.txt b/vendor/github.com/go-task/slim-sprig/v3/LICENSE.txt deleted file mode 100644 index f311b1ea..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2013-2020 Masterminds - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/go-task/slim-sprig/v3/README.md b/vendor/github.com/go-task/slim-sprig/v3/README.md deleted file mode 100644 index b5ab5642..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Slim-Sprig: Template functions for Go templates [![Go Reference](https://pkg.go.dev/badge/github.com/go-task/slim-sprig/v3.svg)](https://pkg.go.dev/github.com/go-task/slim-sprig/v3) - -Slim-Sprig is a fork of [Sprig](https://github.com/Masterminds/sprig), but with -all functions that depend on external (non standard library) or crypto packages -removed. -The reason for this is to make this library more lightweight. Most of these -functions (specially crypto ones) are not needed on most apps, but costs a lot -in terms of binary size and compilation time. - -## Usage - -**Template developers**: Please use Slim-Sprig's [function documentation](https://go-task.github.io/slim-sprig/) for -detailed instructions and code snippets for the >100 template functions available. - -**Go developers**: If you'd like to include Slim-Sprig as a library in your program, -our API documentation is available [at GoDoc.org](http://godoc.org/github.com/go-task/slim-sprig). - -For standard usage, read on. - -### Load the Slim-Sprig library - -To load the Slim-Sprig `FuncMap`: - -```go - -import ( - "html/template" - - "github.com/go-task/slim-sprig" -) - -// This example illustrates that the FuncMap *must* be set before the -// templates themselves are loaded. -tpl := template.Must( - template.New("base").Funcs(sprig.FuncMap()).ParseGlob("*.html") -) -``` - -### Calling the functions inside of templates - -By convention, all functions are lowercase. This seems to follow the Go -idiom for template functions (as opposed to template methods, which are -TitleCase). For example, this: - -``` -{{ "hello!" | upper | repeat 5 }} -``` - -produces this: - -``` -HELLO!HELLO!HELLO!HELLO!HELLO! -``` - -## Principles Driving Our Function Selection - -We followed these principles to decide which functions to add and how to implement them: - -- Use template functions to build layout. The following - types of operations are within the domain of template functions: - - Formatting - - Layout - - Simple type conversions - - Utilities that assist in handling common formatting and layout needs (e.g. arithmetic) -- Template functions should not return errors unless there is no way to print - a sensible value. For example, converting a string to an integer should not - produce an error if conversion fails. Instead, it should display a default - value. -- Simple math is necessary for grid layouts, pagers, and so on. Complex math - (anything other than arithmetic) should be done outside of templates. -- Template functions only deal with the data passed into them. They never retrieve - data from a source. -- Finally, do not override core Go template functions. diff --git a/vendor/github.com/go-task/slim-sprig/v3/Taskfile.yml b/vendor/github.com/go-task/slim-sprig/v3/Taskfile.yml deleted file mode 100644 index 8e6346bb..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/Taskfile.yml +++ /dev/null @@ -1,12 +0,0 @@ -# https://taskfile.dev - -version: '3' - -tasks: - default: - cmds: - - task: test - - test: - cmds: - - go test -v . diff --git a/vendor/github.com/go-task/slim-sprig/v3/crypto.go b/vendor/github.com/go-task/slim-sprig/v3/crypto.go deleted file mode 100644 index d06e516d..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/crypto.go +++ /dev/null @@ -1,24 +0,0 @@ -package sprig - -import ( - "crypto/sha1" - "crypto/sha256" - "encoding/hex" - "fmt" - "hash/adler32" -) - -func sha256sum(input string) string { - hash := sha256.Sum256([]byte(input)) - return hex.EncodeToString(hash[:]) -} - -func sha1sum(input string) string { - hash := sha1.Sum([]byte(input)) - return hex.EncodeToString(hash[:]) -} - -func adler32sum(input string) string { - hash := adler32.Checksum([]byte(input)) - return fmt.Sprintf("%d", hash) -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/date.go b/vendor/github.com/go-task/slim-sprig/v3/date.go deleted file mode 100644 index ed022dda..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/date.go +++ /dev/null @@ -1,152 +0,0 @@ -package sprig - -import ( - "strconv" - "time" -) - -// Given a format and a date, format the date string. -// -// Date can be a `time.Time` or an `int, int32, int64`. -// In the later case, it is treated as seconds since UNIX -// epoch. -func date(fmt string, date interface{}) string { - return dateInZone(fmt, date, "Local") -} - -func htmlDate(date interface{}) string { - return dateInZone("2006-01-02", date, "Local") -} - -func htmlDateInZone(date interface{}, zone string) string { - return dateInZone("2006-01-02", date, zone) -} - -func dateInZone(fmt string, date interface{}, zone string) string { - var t time.Time - switch date := date.(type) { - default: - t = time.Now() - case time.Time: - t = date - case *time.Time: - t = *date - case int64: - t = time.Unix(date, 0) - case int: - t = time.Unix(int64(date), 0) - case int32: - t = time.Unix(int64(date), 0) - } - - loc, err := time.LoadLocation(zone) - if err != nil { - loc, _ = time.LoadLocation("UTC") - } - - return t.In(loc).Format(fmt) -} - -func dateModify(fmt string, date time.Time) time.Time { - d, err := time.ParseDuration(fmt) - if err != nil { - return date - } - return date.Add(d) -} - -func mustDateModify(fmt string, date time.Time) (time.Time, error) { - d, err := time.ParseDuration(fmt) - if err != nil { - return time.Time{}, err - } - return date.Add(d), nil -} - -func dateAgo(date interface{}) string { - var t time.Time - - switch date := date.(type) { - default: - t = time.Now() - case time.Time: - t = date - case int64: - t = time.Unix(date, 0) - case int: - t = time.Unix(int64(date), 0) - } - // Drop resolution to seconds - duration := time.Since(t).Round(time.Second) - return duration.String() -} - -func duration(sec interface{}) string { - var n int64 - switch value := sec.(type) { - default: - n = 0 - case string: - n, _ = strconv.ParseInt(value, 10, 64) - case int64: - n = value - } - return (time.Duration(n) * time.Second).String() -} - -func durationRound(duration interface{}) string { - var d time.Duration - switch duration := duration.(type) { - default: - d = 0 - case string: - d, _ = time.ParseDuration(duration) - case int64: - d = time.Duration(duration) - case time.Time: - d = time.Since(duration) - } - - u := uint64(d) - neg := d < 0 - if neg { - u = -u - } - - var ( - year = uint64(time.Hour) * 24 * 365 - month = uint64(time.Hour) * 24 * 30 - day = uint64(time.Hour) * 24 - hour = uint64(time.Hour) - minute = uint64(time.Minute) - second = uint64(time.Second) - ) - switch { - case u > year: - return strconv.FormatUint(u/year, 10) + "y" - case u > month: - return strconv.FormatUint(u/month, 10) + "mo" - case u > day: - return strconv.FormatUint(u/day, 10) + "d" - case u > hour: - return strconv.FormatUint(u/hour, 10) + "h" - case u > minute: - return strconv.FormatUint(u/minute, 10) + "m" - case u > second: - return strconv.FormatUint(u/second, 10) + "s" - } - return "0s" -} - -func toDate(fmt, str string) time.Time { - t, _ := time.ParseInLocation(fmt, str, time.Local) - return t -} - -func mustToDate(fmt, str string) (time.Time, error) { - return time.ParseInLocation(fmt, str, time.Local) -} - -func unixEpoch(date time.Time) string { - return strconv.FormatInt(date.Unix(), 10) -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/defaults.go b/vendor/github.com/go-task/slim-sprig/v3/defaults.go deleted file mode 100644 index b9f97966..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/defaults.go +++ /dev/null @@ -1,163 +0,0 @@ -package sprig - -import ( - "bytes" - "encoding/json" - "math/rand" - "reflect" - "strings" - "time" -) - -func init() { - rand.Seed(time.Now().UnixNano()) -} - -// dfault checks whether `given` is set, and returns default if not set. -// -// This returns `d` if `given` appears not to be set, and `given` otherwise. -// -// For numeric types 0 is unset. -// For strings, maps, arrays, and slices, len() = 0 is considered unset. -// For bool, false is unset. -// Structs are never considered unset. -// -// For everything else, including pointers, a nil value is unset. -func dfault(d interface{}, given ...interface{}) interface{} { - - if empty(given) || empty(given[0]) { - return d - } - return given[0] -} - -// empty returns true if the given value has the zero value for its type. -func empty(given interface{}) bool { - g := reflect.ValueOf(given) - if !g.IsValid() { - return true - } - - // Basically adapted from text/template.isTrue - switch g.Kind() { - default: - return g.IsNil() - case reflect.Array, reflect.Slice, reflect.Map, reflect.String: - return g.Len() == 0 - case reflect.Bool: - return !g.Bool() - case reflect.Complex64, reflect.Complex128: - return g.Complex() == 0 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return g.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return g.Uint() == 0 - case reflect.Float32, reflect.Float64: - return g.Float() == 0 - case reflect.Struct: - return false - } -} - -// coalesce returns the first non-empty value. -func coalesce(v ...interface{}) interface{} { - for _, val := range v { - if !empty(val) { - return val - } - } - return nil -} - -// all returns true if empty(x) is false for all values x in the list. -// If the list is empty, return true. -func all(v ...interface{}) bool { - for _, val := range v { - if empty(val) { - return false - } - } - return true -} - -// any returns true if empty(x) is false for any x in the list. -// If the list is empty, return false. -func any(v ...interface{}) bool { - for _, val := range v { - if !empty(val) { - return true - } - } - return false -} - -// fromJson decodes JSON into a structured value, ignoring errors. -func fromJson(v string) interface{} { - output, _ := mustFromJson(v) - return output -} - -// mustFromJson decodes JSON into a structured value, returning errors. -func mustFromJson(v string) (interface{}, error) { - var output interface{} - err := json.Unmarshal([]byte(v), &output) - return output, err -} - -// toJson encodes an item into a JSON string -func toJson(v interface{}) string { - output, _ := json.Marshal(v) - return string(output) -} - -func mustToJson(v interface{}) (string, error) { - output, err := json.Marshal(v) - if err != nil { - return "", err - } - return string(output), nil -} - -// toPrettyJson encodes an item into a pretty (indented) JSON string -func toPrettyJson(v interface{}) string { - output, _ := json.MarshalIndent(v, "", " ") - return string(output) -} - -func mustToPrettyJson(v interface{}) (string, error) { - output, err := json.MarshalIndent(v, "", " ") - if err != nil { - return "", err - } - return string(output), nil -} - -// toRawJson encodes an item into a JSON string with no escaping of HTML characters. -func toRawJson(v interface{}) string { - output, err := mustToRawJson(v) - if err != nil { - panic(err) - } - return string(output) -} - -// mustToRawJson encodes an item into a JSON string with no escaping of HTML characters. -func mustToRawJson(v interface{}) (string, error) { - buf := new(bytes.Buffer) - enc := json.NewEncoder(buf) - enc.SetEscapeHTML(false) - err := enc.Encode(&v) - if err != nil { - return "", err - } - return strings.TrimSuffix(buf.String(), "\n"), nil -} - -// ternary returns the first value if the last value is true, otherwise returns the second value. -func ternary(vt interface{}, vf interface{}, v bool) interface{} { - if v { - return vt - } - - return vf -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/dict.go b/vendor/github.com/go-task/slim-sprig/v3/dict.go deleted file mode 100644 index 77ebc61b..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/dict.go +++ /dev/null @@ -1,118 +0,0 @@ -package sprig - -func get(d map[string]interface{}, key string) interface{} { - if val, ok := d[key]; ok { - return val - } - return "" -} - -func set(d map[string]interface{}, key string, value interface{}) map[string]interface{} { - d[key] = value - return d -} - -func unset(d map[string]interface{}, key string) map[string]interface{} { - delete(d, key) - return d -} - -func hasKey(d map[string]interface{}, key string) bool { - _, ok := d[key] - return ok -} - -func pluck(key string, d ...map[string]interface{}) []interface{} { - res := []interface{}{} - for _, dict := range d { - if val, ok := dict[key]; ok { - res = append(res, val) - } - } - return res -} - -func keys(dicts ...map[string]interface{}) []string { - k := []string{} - for _, dict := range dicts { - for key := range dict { - k = append(k, key) - } - } - return k -} - -func pick(dict map[string]interface{}, keys ...string) map[string]interface{} { - res := map[string]interface{}{} - for _, k := range keys { - if v, ok := dict[k]; ok { - res[k] = v - } - } - return res -} - -func omit(dict map[string]interface{}, keys ...string) map[string]interface{} { - res := map[string]interface{}{} - - omit := make(map[string]bool, len(keys)) - for _, k := range keys { - omit[k] = true - } - - for k, v := range dict { - if _, ok := omit[k]; !ok { - res[k] = v - } - } - return res -} - -func dict(v ...interface{}) map[string]interface{} { - dict := map[string]interface{}{} - lenv := len(v) - for i := 0; i < lenv; i += 2 { - key := strval(v[i]) - if i+1 >= lenv { - dict[key] = "" - continue - } - dict[key] = v[i+1] - } - return dict -} - -func values(dict map[string]interface{}) []interface{} { - values := []interface{}{} - for _, value := range dict { - values = append(values, value) - } - - return values -} - -func dig(ps ...interface{}) (interface{}, error) { - if len(ps) < 3 { - panic("dig needs at least three arguments") - } - dict := ps[len(ps)-1].(map[string]interface{}) - def := ps[len(ps)-2] - ks := make([]string, len(ps)-2) - for i := 0; i < len(ks); i++ { - ks[i] = ps[i].(string) - } - - return digFromDict(dict, def, ks) -} - -func digFromDict(dict map[string]interface{}, d interface{}, ks []string) (interface{}, error) { - k, ns := ks[0], ks[1:len(ks)] - step, has := dict[k] - if !has { - return d, nil - } - if len(ns) == 0 { - return step, nil - } - return digFromDict(step.(map[string]interface{}), d, ns) -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/doc.go b/vendor/github.com/go-task/slim-sprig/v3/doc.go deleted file mode 100644 index aabb9d44..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Package sprig provides template functions for Go. - -This package contains a number of utility functions for working with data -inside of Go `html/template` and `text/template` files. - -To add these functions, use the `template.Funcs()` method: - - t := templates.New("foo").Funcs(sprig.FuncMap()) - -Note that you should add the function map before you parse any template files. - - In several cases, Sprig reverses the order of arguments from the way they - appear in the standard library. This is to make it easier to pipe - arguments into functions. - -See http://masterminds.github.io/sprig/ for more detailed documentation on each of the available functions. -*/ -package sprig diff --git a/vendor/github.com/go-task/slim-sprig/v3/functions.go b/vendor/github.com/go-task/slim-sprig/v3/functions.go deleted file mode 100644 index 5ea74f89..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/functions.go +++ /dev/null @@ -1,317 +0,0 @@ -package sprig - -import ( - "errors" - "html/template" - "math/rand" - "os" - "path" - "path/filepath" - "reflect" - "strconv" - "strings" - ttemplate "text/template" - "time" -) - -// FuncMap produces the function map. -// -// Use this to pass the functions into the template engine: -// -// tpl := template.New("foo").Funcs(sprig.FuncMap())) -// -func FuncMap() template.FuncMap { - return HtmlFuncMap() -} - -// HermeticTxtFuncMap returns a 'text/template'.FuncMap with only repeatable functions. -func HermeticTxtFuncMap() ttemplate.FuncMap { - r := TxtFuncMap() - for _, name := range nonhermeticFunctions { - delete(r, name) - } - return r -} - -// HermeticHtmlFuncMap returns an 'html/template'.Funcmap with only repeatable functions. -func HermeticHtmlFuncMap() template.FuncMap { - r := HtmlFuncMap() - for _, name := range nonhermeticFunctions { - delete(r, name) - } - return r -} - -// TxtFuncMap returns a 'text/template'.FuncMap -func TxtFuncMap() ttemplate.FuncMap { - return ttemplate.FuncMap(GenericFuncMap()) -} - -// HtmlFuncMap returns an 'html/template'.Funcmap -func HtmlFuncMap() template.FuncMap { - return template.FuncMap(GenericFuncMap()) -} - -// GenericFuncMap returns a copy of the basic function map as a map[string]interface{}. -func GenericFuncMap() map[string]interface{} { - gfm := make(map[string]interface{}, len(genericMap)) - for k, v := range genericMap { - gfm[k] = v - } - return gfm -} - -// These functions are not guaranteed to evaluate to the same result for given input, because they -// refer to the environment or global state. -var nonhermeticFunctions = []string{ - // Date functions - "date", - "date_in_zone", - "date_modify", - "now", - "htmlDate", - "htmlDateInZone", - "dateInZone", - "dateModify", - - // Strings - "randAlphaNum", - "randAlpha", - "randAscii", - "randNumeric", - "randBytes", - "uuidv4", - - // OS - "env", - "expandenv", - - // Network - "getHostByName", -} - -var genericMap = map[string]interface{}{ - "hello": func() string { return "Hello!" }, - - // Date functions - "ago": dateAgo, - "date": date, - "date_in_zone": dateInZone, - "date_modify": dateModify, - "dateInZone": dateInZone, - "dateModify": dateModify, - "duration": duration, - "durationRound": durationRound, - "htmlDate": htmlDate, - "htmlDateInZone": htmlDateInZone, - "must_date_modify": mustDateModify, - "mustDateModify": mustDateModify, - "mustToDate": mustToDate, - "now": time.Now, - "toDate": toDate, - "unixEpoch": unixEpoch, - - // Strings - "trunc": trunc, - "trim": strings.TrimSpace, - "upper": strings.ToUpper, - "lower": strings.ToLower, - "title": strings.Title, - "substr": substring, - // Switch order so that "foo" | repeat 5 - "repeat": func(count int, str string) string { return strings.Repeat(str, count) }, - // Deprecated: Use trimAll. - "trimall": func(a, b string) string { return strings.Trim(b, a) }, - // Switch order so that "$foo" | trimall "$" - "trimAll": func(a, b string) string { return strings.Trim(b, a) }, - "trimSuffix": func(a, b string) string { return strings.TrimSuffix(b, a) }, - "trimPrefix": func(a, b string) string { return strings.TrimPrefix(b, a) }, - // Switch order so that "foobar" | contains "foo" - "contains": func(substr string, str string) bool { return strings.Contains(str, substr) }, - "hasPrefix": func(substr string, str string) bool { return strings.HasPrefix(str, substr) }, - "hasSuffix": func(substr string, str string) bool { return strings.HasSuffix(str, substr) }, - "quote": quote, - "squote": squote, - "cat": cat, - "indent": indent, - "nindent": nindent, - "replace": replace, - "plural": plural, - "sha1sum": sha1sum, - "sha256sum": sha256sum, - "adler32sum": adler32sum, - "toString": strval, - - // Wrap Atoi to stop errors. - "atoi": func(a string) int { i, _ := strconv.Atoi(a); return i }, - "int64": toInt64, - "int": toInt, - "float64": toFloat64, - "seq": seq, - "toDecimal": toDecimal, - - //"gt": func(a, b int) bool {return a > b}, - //"gte": func(a, b int) bool {return a >= b}, - //"lt": func(a, b int) bool {return a < b}, - //"lte": func(a, b int) bool {return a <= b}, - - // split "/" foo/bar returns map[int]string{0: foo, 1: bar} - "split": split, - "splitList": func(sep, orig string) []string { return strings.Split(orig, sep) }, - // splitn "/" foo/bar/fuu returns map[int]string{0: foo, 1: bar/fuu} - "splitn": splitn, - "toStrings": strslice, - - "until": until, - "untilStep": untilStep, - - // VERY basic arithmetic. - "add1": func(i interface{}) int64 { return toInt64(i) + 1 }, - "add": func(i ...interface{}) int64 { - var a int64 = 0 - for _, b := range i { - a += toInt64(b) - } - return a - }, - "sub": func(a, b interface{}) int64 { return toInt64(a) - toInt64(b) }, - "div": func(a, b interface{}) int64 { return toInt64(a) / toInt64(b) }, - "mod": func(a, b interface{}) int64 { return toInt64(a) % toInt64(b) }, - "mul": func(a interface{}, v ...interface{}) int64 { - val := toInt64(a) - for _, b := range v { - val = val * toInt64(b) - } - return val - }, - "randInt": func(min, max int) int { return rand.Intn(max-min) + min }, - "biggest": max, - "max": max, - "min": min, - "maxf": maxf, - "minf": minf, - "ceil": ceil, - "floor": floor, - "round": round, - - // string slices. Note that we reverse the order b/c that's better - // for template processing. - "join": join, - "sortAlpha": sortAlpha, - - // Defaults - "default": dfault, - "empty": empty, - "coalesce": coalesce, - "all": all, - "any": any, - "compact": compact, - "mustCompact": mustCompact, - "fromJson": fromJson, - "toJson": toJson, - "toPrettyJson": toPrettyJson, - "toRawJson": toRawJson, - "mustFromJson": mustFromJson, - "mustToJson": mustToJson, - "mustToPrettyJson": mustToPrettyJson, - "mustToRawJson": mustToRawJson, - "ternary": ternary, - - // Reflection - "typeOf": typeOf, - "typeIs": typeIs, - "typeIsLike": typeIsLike, - "kindOf": kindOf, - "kindIs": kindIs, - "deepEqual": reflect.DeepEqual, - - // OS: - "env": os.Getenv, - "expandenv": os.ExpandEnv, - - // Network: - "getHostByName": getHostByName, - - // Paths: - "base": path.Base, - "dir": path.Dir, - "clean": path.Clean, - "ext": path.Ext, - "isAbs": path.IsAbs, - - // Filepaths: - "osBase": filepath.Base, - "osClean": filepath.Clean, - "osDir": filepath.Dir, - "osExt": filepath.Ext, - "osIsAbs": filepath.IsAbs, - - // Encoding: - "b64enc": base64encode, - "b64dec": base64decode, - "b32enc": base32encode, - "b32dec": base32decode, - - // Data Structures: - "tuple": list, // FIXME: with the addition of append/prepend these are no longer immutable. - "list": list, - "dict": dict, - "get": get, - "set": set, - "unset": unset, - "hasKey": hasKey, - "pluck": pluck, - "keys": keys, - "pick": pick, - "omit": omit, - "values": values, - - "append": push, "push": push, - "mustAppend": mustPush, "mustPush": mustPush, - "prepend": prepend, - "mustPrepend": mustPrepend, - "first": first, - "mustFirst": mustFirst, - "rest": rest, - "mustRest": mustRest, - "last": last, - "mustLast": mustLast, - "initial": initial, - "mustInitial": mustInitial, - "reverse": reverse, - "mustReverse": mustReverse, - "uniq": uniq, - "mustUniq": mustUniq, - "without": without, - "mustWithout": mustWithout, - "has": has, - "mustHas": mustHas, - "slice": slice, - "mustSlice": mustSlice, - "concat": concat, - "dig": dig, - "chunk": chunk, - "mustChunk": mustChunk, - - // Flow Control: - "fail": func(msg string) (string, error) { return "", errors.New(msg) }, - - // Regex - "regexMatch": regexMatch, - "mustRegexMatch": mustRegexMatch, - "regexFindAll": regexFindAll, - "mustRegexFindAll": mustRegexFindAll, - "regexFind": regexFind, - "mustRegexFind": mustRegexFind, - "regexReplaceAll": regexReplaceAll, - "mustRegexReplaceAll": mustRegexReplaceAll, - "regexReplaceAllLiteral": regexReplaceAllLiteral, - "mustRegexReplaceAllLiteral": mustRegexReplaceAllLiteral, - "regexSplit": regexSplit, - "mustRegexSplit": mustRegexSplit, - "regexQuoteMeta": regexQuoteMeta, - - // URLs: - "urlParse": urlParse, - "urlJoin": urlJoin, -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/list.go b/vendor/github.com/go-task/slim-sprig/v3/list.go deleted file mode 100644 index ca0fbb78..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/list.go +++ /dev/null @@ -1,464 +0,0 @@ -package sprig - -import ( - "fmt" - "math" - "reflect" - "sort" -) - -// Reflection is used in these functions so that slices and arrays of strings, -// ints, and other types not implementing []interface{} can be worked with. -// For example, this is useful if you need to work on the output of regexs. - -func list(v ...interface{}) []interface{} { - return v -} - -func push(list interface{}, v interface{}) []interface{} { - l, err := mustPush(list, v) - if err != nil { - panic(err) - } - - return l -} - -func mustPush(list interface{}, v interface{}) ([]interface{}, error) { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - nl := make([]interface{}, l) - for i := 0; i < l; i++ { - nl[i] = l2.Index(i).Interface() - } - - return append(nl, v), nil - - default: - return nil, fmt.Errorf("Cannot push on type %s", tp) - } -} - -func prepend(list interface{}, v interface{}) []interface{} { - l, err := mustPrepend(list, v) - if err != nil { - panic(err) - } - - return l -} - -func mustPrepend(list interface{}, v interface{}) ([]interface{}, error) { - //return append([]interface{}{v}, list...) - - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - nl := make([]interface{}, l) - for i := 0; i < l; i++ { - nl[i] = l2.Index(i).Interface() - } - - return append([]interface{}{v}, nl...), nil - - default: - return nil, fmt.Errorf("Cannot prepend on type %s", tp) - } -} - -func chunk(size int, list interface{}) [][]interface{} { - l, err := mustChunk(size, list) - if err != nil { - panic(err) - } - - return l -} - -func mustChunk(size int, list interface{}) ([][]interface{}, error) { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - - cs := int(math.Floor(float64(l-1)/float64(size)) + 1) - nl := make([][]interface{}, cs) - - for i := 0; i < cs; i++ { - clen := size - if i == cs-1 { - clen = int(math.Floor(math.Mod(float64(l), float64(size)))) - if clen == 0 { - clen = size - } - } - - nl[i] = make([]interface{}, clen) - - for j := 0; j < clen; j++ { - ix := i*size + j - nl[i][j] = l2.Index(ix).Interface() - } - } - - return nl, nil - - default: - return nil, fmt.Errorf("Cannot chunk type %s", tp) - } -} - -func last(list interface{}) interface{} { - l, err := mustLast(list) - if err != nil { - panic(err) - } - - return l -} - -func mustLast(list interface{}) (interface{}, error) { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - if l == 0 { - return nil, nil - } - - return l2.Index(l - 1).Interface(), nil - default: - return nil, fmt.Errorf("Cannot find last on type %s", tp) - } -} - -func first(list interface{}) interface{} { - l, err := mustFirst(list) - if err != nil { - panic(err) - } - - return l -} - -func mustFirst(list interface{}) (interface{}, error) { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - if l == 0 { - return nil, nil - } - - return l2.Index(0).Interface(), nil - default: - return nil, fmt.Errorf("Cannot find first on type %s", tp) - } -} - -func rest(list interface{}) []interface{} { - l, err := mustRest(list) - if err != nil { - panic(err) - } - - return l -} - -func mustRest(list interface{}) ([]interface{}, error) { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - if l == 0 { - return nil, nil - } - - nl := make([]interface{}, l-1) - for i := 1; i < l; i++ { - nl[i-1] = l2.Index(i).Interface() - } - - return nl, nil - default: - return nil, fmt.Errorf("Cannot find rest on type %s", tp) - } -} - -func initial(list interface{}) []interface{} { - l, err := mustInitial(list) - if err != nil { - panic(err) - } - - return l -} - -func mustInitial(list interface{}) ([]interface{}, error) { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - if l == 0 { - return nil, nil - } - - nl := make([]interface{}, l-1) - for i := 0; i < l-1; i++ { - nl[i] = l2.Index(i).Interface() - } - - return nl, nil - default: - return nil, fmt.Errorf("Cannot find initial on type %s", tp) - } -} - -func sortAlpha(list interface{}) []string { - k := reflect.Indirect(reflect.ValueOf(list)).Kind() - switch k { - case reflect.Slice, reflect.Array: - a := strslice(list) - s := sort.StringSlice(a) - s.Sort() - return s - } - return []string{strval(list)} -} - -func reverse(v interface{}) []interface{} { - l, err := mustReverse(v) - if err != nil { - panic(err) - } - - return l -} - -func mustReverse(v interface{}) ([]interface{}, error) { - tp := reflect.TypeOf(v).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(v) - - l := l2.Len() - // We do not sort in place because the incoming array should not be altered. - nl := make([]interface{}, l) - for i := 0; i < l; i++ { - nl[l-i-1] = l2.Index(i).Interface() - } - - return nl, nil - default: - return nil, fmt.Errorf("Cannot find reverse on type %s", tp) - } -} - -func compact(list interface{}) []interface{} { - l, err := mustCompact(list) - if err != nil { - panic(err) - } - - return l -} - -func mustCompact(list interface{}) ([]interface{}, error) { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - nl := []interface{}{} - var item interface{} - for i := 0; i < l; i++ { - item = l2.Index(i).Interface() - if !empty(item) { - nl = append(nl, item) - } - } - - return nl, nil - default: - return nil, fmt.Errorf("Cannot compact on type %s", tp) - } -} - -func uniq(list interface{}) []interface{} { - l, err := mustUniq(list) - if err != nil { - panic(err) - } - - return l -} - -func mustUniq(list interface{}) ([]interface{}, error) { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - dest := []interface{}{} - var item interface{} - for i := 0; i < l; i++ { - item = l2.Index(i).Interface() - if !inList(dest, item) { - dest = append(dest, item) - } - } - - return dest, nil - default: - return nil, fmt.Errorf("Cannot find uniq on type %s", tp) - } -} - -func inList(haystack []interface{}, needle interface{}) bool { - for _, h := range haystack { - if reflect.DeepEqual(needle, h) { - return true - } - } - return false -} - -func without(list interface{}, omit ...interface{}) []interface{} { - l, err := mustWithout(list, omit...) - if err != nil { - panic(err) - } - - return l -} - -func mustWithout(list interface{}, omit ...interface{}) ([]interface{}, error) { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - res := []interface{}{} - var item interface{} - for i := 0; i < l; i++ { - item = l2.Index(i).Interface() - if !inList(omit, item) { - res = append(res, item) - } - } - - return res, nil - default: - return nil, fmt.Errorf("Cannot find without on type %s", tp) - } -} - -func has(needle interface{}, haystack interface{}) bool { - l, err := mustHas(needle, haystack) - if err != nil { - panic(err) - } - - return l -} - -func mustHas(needle interface{}, haystack interface{}) (bool, error) { - if haystack == nil { - return false, nil - } - tp := reflect.TypeOf(haystack).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(haystack) - var item interface{} - l := l2.Len() - for i := 0; i < l; i++ { - item = l2.Index(i).Interface() - if reflect.DeepEqual(needle, item) { - return true, nil - } - } - - return false, nil - default: - return false, fmt.Errorf("Cannot find has on type %s", tp) - } -} - -// $list := [1, 2, 3, 4, 5] -// slice $list -> list[0:5] = list[:] -// slice $list 0 3 -> list[0:3] = list[:3] -// slice $list 3 5 -> list[3:5] -// slice $list 3 -> list[3:5] = list[3:] -func slice(list interface{}, indices ...interface{}) interface{} { - l, err := mustSlice(list, indices...) - if err != nil { - panic(err) - } - - return l -} - -func mustSlice(list interface{}, indices ...interface{}) (interface{}, error) { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - - l := l2.Len() - if l == 0 { - return nil, nil - } - - var start, end int - if len(indices) > 0 { - start = toInt(indices[0]) - } - if len(indices) < 2 { - end = l - } else { - end = toInt(indices[1]) - } - - return l2.Slice(start, end).Interface(), nil - default: - return nil, fmt.Errorf("list should be type of slice or array but %s", tp) - } -} - -func concat(lists ...interface{}) interface{} { - var res []interface{} - for _, list := range lists { - tp := reflect.TypeOf(list).Kind() - switch tp { - case reflect.Slice, reflect.Array: - l2 := reflect.ValueOf(list) - for i := 0; i < l2.Len(); i++ { - res = append(res, l2.Index(i).Interface()) - } - default: - panic(fmt.Sprintf("Cannot concat type %s as list", tp)) - } - } - return res -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/network.go b/vendor/github.com/go-task/slim-sprig/v3/network.go deleted file mode 100644 index 108d78a9..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/network.go +++ /dev/null @@ -1,12 +0,0 @@ -package sprig - -import ( - "math/rand" - "net" -) - -func getHostByName(name string) string { - addrs, _ := net.LookupHost(name) - //TODO: add error handing when release v3 comes out - return addrs[rand.Intn(len(addrs))] -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/numeric.go b/vendor/github.com/go-task/slim-sprig/v3/numeric.go deleted file mode 100644 index 98cbb37a..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/numeric.go +++ /dev/null @@ -1,228 +0,0 @@ -package sprig - -import ( - "fmt" - "math" - "reflect" - "strconv" - "strings" -) - -// toFloat64 converts 64-bit floats -func toFloat64(v interface{}) float64 { - if str, ok := v.(string); ok { - iv, err := strconv.ParseFloat(str, 64) - if err != nil { - return 0 - } - return iv - } - - val := reflect.Indirect(reflect.ValueOf(v)) - switch val.Kind() { - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return float64(val.Int()) - case reflect.Uint8, reflect.Uint16, reflect.Uint32: - return float64(val.Uint()) - case reflect.Uint, reflect.Uint64: - return float64(val.Uint()) - case reflect.Float32, reflect.Float64: - return val.Float() - case reflect.Bool: - if val.Bool() { - return 1 - } - return 0 - default: - return 0 - } -} - -func toInt(v interface{}) int { - //It's not optimal. Bud I don't want duplicate toInt64 code. - return int(toInt64(v)) -} - -// toInt64 converts integer types to 64-bit integers -func toInt64(v interface{}) int64 { - if str, ok := v.(string); ok { - iv, err := strconv.ParseInt(str, 10, 64) - if err != nil { - return 0 - } - return iv - } - - val := reflect.Indirect(reflect.ValueOf(v)) - switch val.Kind() { - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return val.Int() - case reflect.Uint8, reflect.Uint16, reflect.Uint32: - return int64(val.Uint()) - case reflect.Uint, reflect.Uint64: - tv := val.Uint() - if tv <= math.MaxInt64 { - return int64(tv) - } - // TODO: What is the sensible thing to do here? - return math.MaxInt64 - case reflect.Float32, reflect.Float64: - return int64(val.Float()) - case reflect.Bool: - if val.Bool() { - return 1 - } - return 0 - default: - return 0 - } -} - -func max(a interface{}, i ...interface{}) int64 { - aa := toInt64(a) - for _, b := range i { - bb := toInt64(b) - if bb > aa { - aa = bb - } - } - return aa -} - -func maxf(a interface{}, i ...interface{}) float64 { - aa := toFloat64(a) - for _, b := range i { - bb := toFloat64(b) - aa = math.Max(aa, bb) - } - return aa -} - -func min(a interface{}, i ...interface{}) int64 { - aa := toInt64(a) - for _, b := range i { - bb := toInt64(b) - if bb < aa { - aa = bb - } - } - return aa -} - -func minf(a interface{}, i ...interface{}) float64 { - aa := toFloat64(a) - for _, b := range i { - bb := toFloat64(b) - aa = math.Min(aa, bb) - } - return aa -} - -func until(count int) []int { - step := 1 - if count < 0 { - step = -1 - } - return untilStep(0, count, step) -} - -func untilStep(start, stop, step int) []int { - v := []int{} - - if stop < start { - if step >= 0 { - return v - } - for i := start; i > stop; i += step { - v = append(v, i) - } - return v - } - - if step <= 0 { - return v - } - for i := start; i < stop; i += step { - v = append(v, i) - } - return v -} - -func floor(a interface{}) float64 { - aa := toFloat64(a) - return math.Floor(aa) -} - -func ceil(a interface{}) float64 { - aa := toFloat64(a) - return math.Ceil(aa) -} - -func round(a interface{}, p int, rOpt ...float64) float64 { - roundOn := .5 - if len(rOpt) > 0 { - roundOn = rOpt[0] - } - val := toFloat64(a) - places := toFloat64(p) - - var round float64 - pow := math.Pow(10, places) - digit := pow * val - _, div := math.Modf(digit) - if div >= roundOn { - round = math.Ceil(digit) - } else { - round = math.Floor(digit) - } - return round / pow -} - -// converts unix octal to decimal -func toDecimal(v interface{}) int64 { - result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64) - if err != nil { - return 0 - } - return result -} - -func seq(params ...int) string { - increment := 1 - switch len(params) { - case 0: - return "" - case 1: - start := 1 - end := params[0] - if end < start { - increment = -1 - } - return intArrayToString(untilStep(start, end+increment, increment), " ") - case 3: - start := params[0] - end := params[2] - step := params[1] - if end < start { - increment = -1 - if step > 0 { - return "" - } - } - return intArrayToString(untilStep(start, end+increment, step), " ") - case 2: - start := params[0] - end := params[1] - step := 1 - if end < start { - step = -1 - } - return intArrayToString(untilStep(start, end+step, step), " ") - default: - return "" - } -} - -func intArrayToString(slice []int, delimeter string) string { - return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(slice)), delimeter), "[]") -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/reflect.go b/vendor/github.com/go-task/slim-sprig/v3/reflect.go deleted file mode 100644 index 8a65c132..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/reflect.go +++ /dev/null @@ -1,28 +0,0 @@ -package sprig - -import ( - "fmt" - "reflect" -) - -// typeIs returns true if the src is the type named in target. -func typeIs(target string, src interface{}) bool { - return target == typeOf(src) -} - -func typeIsLike(target string, src interface{}) bool { - t := typeOf(src) - return target == t || "*"+target == t -} - -func typeOf(src interface{}) string { - return fmt.Sprintf("%T", src) -} - -func kindIs(target string, src interface{}) bool { - return target == kindOf(src) -} - -func kindOf(src interface{}) string { - return reflect.ValueOf(src).Kind().String() -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/regex.go b/vendor/github.com/go-task/slim-sprig/v3/regex.go deleted file mode 100644 index fab55101..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/regex.go +++ /dev/null @@ -1,83 +0,0 @@ -package sprig - -import ( - "regexp" -) - -func regexMatch(regex string, s string) bool { - match, _ := regexp.MatchString(regex, s) - return match -} - -func mustRegexMatch(regex string, s string) (bool, error) { - return regexp.MatchString(regex, s) -} - -func regexFindAll(regex string, s string, n int) []string { - r := regexp.MustCompile(regex) - return r.FindAllString(s, n) -} - -func mustRegexFindAll(regex string, s string, n int) ([]string, error) { - r, err := regexp.Compile(regex) - if err != nil { - return []string{}, err - } - return r.FindAllString(s, n), nil -} - -func regexFind(regex string, s string) string { - r := regexp.MustCompile(regex) - return r.FindString(s) -} - -func mustRegexFind(regex string, s string) (string, error) { - r, err := regexp.Compile(regex) - if err != nil { - return "", err - } - return r.FindString(s), nil -} - -func regexReplaceAll(regex string, s string, repl string) string { - r := regexp.MustCompile(regex) - return r.ReplaceAllString(s, repl) -} - -func mustRegexReplaceAll(regex string, s string, repl string) (string, error) { - r, err := regexp.Compile(regex) - if err != nil { - return "", err - } - return r.ReplaceAllString(s, repl), nil -} - -func regexReplaceAllLiteral(regex string, s string, repl string) string { - r := regexp.MustCompile(regex) - return r.ReplaceAllLiteralString(s, repl) -} - -func mustRegexReplaceAllLiteral(regex string, s string, repl string) (string, error) { - r, err := regexp.Compile(regex) - if err != nil { - return "", err - } - return r.ReplaceAllLiteralString(s, repl), nil -} - -func regexSplit(regex string, s string, n int) []string { - r := regexp.MustCompile(regex) - return r.Split(s, n) -} - -func mustRegexSplit(regex string, s string, n int) ([]string, error) { - r, err := regexp.Compile(regex) - if err != nil { - return []string{}, err - } - return r.Split(s, n), nil -} - -func regexQuoteMeta(s string) string { - return regexp.QuoteMeta(s) -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/strings.go b/vendor/github.com/go-task/slim-sprig/v3/strings.go deleted file mode 100644 index 3c62d6b6..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/strings.go +++ /dev/null @@ -1,189 +0,0 @@ -package sprig - -import ( - "encoding/base32" - "encoding/base64" - "fmt" - "reflect" - "strconv" - "strings" -) - -func base64encode(v string) string { - return base64.StdEncoding.EncodeToString([]byte(v)) -} - -func base64decode(v string) string { - data, err := base64.StdEncoding.DecodeString(v) - if err != nil { - return err.Error() - } - return string(data) -} - -func base32encode(v string) string { - return base32.StdEncoding.EncodeToString([]byte(v)) -} - -func base32decode(v string) string { - data, err := base32.StdEncoding.DecodeString(v) - if err != nil { - return err.Error() - } - return string(data) -} - -func quote(str ...interface{}) string { - out := make([]string, 0, len(str)) - for _, s := range str { - if s != nil { - out = append(out, fmt.Sprintf("%q", strval(s))) - } - } - return strings.Join(out, " ") -} - -func squote(str ...interface{}) string { - out := make([]string, 0, len(str)) - for _, s := range str { - if s != nil { - out = append(out, fmt.Sprintf("'%v'", s)) - } - } - return strings.Join(out, " ") -} - -func cat(v ...interface{}) string { - v = removeNilElements(v) - r := strings.TrimSpace(strings.Repeat("%v ", len(v))) - return fmt.Sprintf(r, v...) -} - -func indent(spaces int, v string) string { - pad := strings.Repeat(" ", spaces) - return pad + strings.Replace(v, "\n", "\n"+pad, -1) -} - -func nindent(spaces int, v string) string { - return "\n" + indent(spaces, v) -} - -func replace(old, new, src string) string { - return strings.Replace(src, old, new, -1) -} - -func plural(one, many string, count int) string { - if count == 1 { - return one - } - return many -} - -func strslice(v interface{}) []string { - switch v := v.(type) { - case []string: - return v - case []interface{}: - b := make([]string, 0, len(v)) - for _, s := range v { - if s != nil { - b = append(b, strval(s)) - } - } - return b - default: - val := reflect.ValueOf(v) - switch val.Kind() { - case reflect.Array, reflect.Slice: - l := val.Len() - b := make([]string, 0, l) - for i := 0; i < l; i++ { - value := val.Index(i).Interface() - if value != nil { - b = append(b, strval(value)) - } - } - return b - default: - if v == nil { - return []string{} - } - - return []string{strval(v)} - } - } -} - -func removeNilElements(v []interface{}) []interface{} { - newSlice := make([]interface{}, 0, len(v)) - for _, i := range v { - if i != nil { - newSlice = append(newSlice, i) - } - } - return newSlice -} - -func strval(v interface{}) string { - switch v := v.(type) { - case string: - return v - case []byte: - return string(v) - case error: - return v.Error() - case fmt.Stringer: - return v.String() - default: - return fmt.Sprintf("%v", v) - } -} - -func trunc(c int, s string) string { - if c < 0 && len(s)+c > 0 { - return s[len(s)+c:] - } - if c >= 0 && len(s) > c { - return s[:c] - } - return s -} - -func join(sep string, v interface{}) string { - return strings.Join(strslice(v), sep) -} - -func split(sep, orig string) map[string]string { - parts := strings.Split(orig, sep) - res := make(map[string]string, len(parts)) - for i, v := range parts { - res["_"+strconv.Itoa(i)] = v - } - return res -} - -func splitn(sep string, n int, orig string) map[string]string { - parts := strings.SplitN(orig, sep, n) - res := make(map[string]string, len(parts)) - for i, v := range parts { - res["_"+strconv.Itoa(i)] = v - } - return res -} - -// substring creates a substring of the given string. -// -// If start is < 0, this calls string[:end]. -// -// If start is >= 0 and end < 0 or end bigger than s length, this calls string[start:] -// -// Otherwise, this calls string[start, end]. -func substring(start, end int, s string) string { - if start < 0 { - return s[:end] - } - if end < 0 || end > len(s) { - return s[start:] - } - return s[start:end] -} diff --git a/vendor/github.com/go-task/slim-sprig/v3/url.go b/vendor/github.com/go-task/slim-sprig/v3/url.go deleted file mode 100644 index b8e120e1..00000000 --- a/vendor/github.com/go-task/slim-sprig/v3/url.go +++ /dev/null @@ -1,66 +0,0 @@ -package sprig - -import ( - "fmt" - "net/url" - "reflect" -) - -func dictGetOrEmpty(dict map[string]interface{}, key string) string { - value, ok := dict[key] - if !ok { - return "" - } - tp := reflect.TypeOf(value).Kind() - if tp != reflect.String { - panic(fmt.Sprintf("unable to parse %s key, must be of type string, but %s found", key, tp.String())) - } - return reflect.ValueOf(value).String() -} - -// parses given URL to return dict object -func urlParse(v string) map[string]interface{} { - dict := map[string]interface{}{} - parsedURL, err := url.Parse(v) - if err != nil { - panic(fmt.Sprintf("unable to parse url: %s", err)) - } - dict["scheme"] = parsedURL.Scheme - dict["host"] = parsedURL.Host - dict["hostname"] = parsedURL.Hostname() - dict["path"] = parsedURL.Path - dict["query"] = parsedURL.RawQuery - dict["opaque"] = parsedURL.Opaque - dict["fragment"] = parsedURL.Fragment - if parsedURL.User != nil { - dict["userinfo"] = parsedURL.User.String() - } else { - dict["userinfo"] = "" - } - - return dict -} - -// join given dict to URL string -func urlJoin(d map[string]interface{}) string { - resURL := url.URL{ - Scheme: dictGetOrEmpty(d, "scheme"), - Host: dictGetOrEmpty(d, "host"), - Path: dictGetOrEmpty(d, "path"), - RawQuery: dictGetOrEmpty(d, "query"), - Opaque: dictGetOrEmpty(d, "opaque"), - Fragment: dictGetOrEmpty(d, "fragment"), - } - userinfo := dictGetOrEmpty(d, "userinfo") - var user *url.Userinfo - if userinfo != "" { - tempURL, err := url.Parse(fmt.Sprintf("proto://%s@host", userinfo)) - if err != nil { - panic(fmt.Sprintf("unable to parse userinfo in dict: %s", err)) - } - user = tempURL.User - } - - resURL.User = user - return resURL.String() -} diff --git a/vendor/github.com/google/pprof/AUTHORS b/vendor/github.com/google/pprof/AUTHORS deleted file mode 100644 index fd736cb1..00000000 --- a/vendor/github.com/google/pprof/AUTHORS +++ /dev/null @@ -1,7 +0,0 @@ -# This is the official list of pprof authors for copyright purposes. -# This file is distinct from the CONTRIBUTORS files. -# See the latter for an explanation. -# Names should be added to this file as: -# Name or Organization -# The email address is not required for organizations. -Google Inc. \ No newline at end of file diff --git a/vendor/github.com/google/pprof/CONTRIBUTORS b/vendor/github.com/google/pprof/CONTRIBUTORS deleted file mode 100644 index 8c8c37d2..00000000 --- a/vendor/github.com/google/pprof/CONTRIBUTORS +++ /dev/null @@ -1,16 +0,0 @@ -# People who have agreed to one of the CLAs and can contribute patches. -# The AUTHORS file lists the copyright holders; this file -# lists people. For example, Google employees are listed here -# but not in AUTHORS, because Google holds the copyright. -# -# https://developers.google.com/open-source/cla/individual -# https://developers.google.com/open-source/cla/corporate -# -# Names should be added to this file as: -# Name -Raul Silvera -Tipp Moseley -Hyoun Kyu Cho -Martin Spier -Taco de Wolff -Andrew Hunter diff --git a/vendor/github.com/google/pprof/LICENSE b/vendor/github.com/google/pprof/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/github.com/google/pprof/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. diff --git a/vendor/github.com/google/pprof/profile/encode.go b/vendor/github.com/google/pprof/profile/encode.go deleted file mode 100644 index 8ce9d3cf..00000000 --- a/vendor/github.com/google/pprof/profile/encode.go +++ /dev/null @@ -1,596 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// 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 profile - -import ( - "errors" - "sort" - "strings" -) - -func (p *Profile) decoder() []decoder { - return profileDecoder -} - -// preEncode populates the unexported fields to be used by encode -// (with suffix X) from the corresponding exported fields. The -// exported fields are cleared up to facilitate testing. -func (p *Profile) preEncode() { - strings := make(map[string]int) - addString(strings, "") - - for _, st := range p.SampleType { - st.typeX = addString(strings, st.Type) - st.unitX = addString(strings, st.Unit) - } - - for _, s := range p.Sample { - s.labelX = nil - var keys []string - for k := range s.Label { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - vs := s.Label[k] - for _, v := range vs { - s.labelX = append(s.labelX, - label{ - keyX: addString(strings, k), - strX: addString(strings, v), - }, - ) - } - } - var numKeys []string - for k := range s.NumLabel { - numKeys = append(numKeys, k) - } - sort.Strings(numKeys) - for _, k := range numKeys { - keyX := addString(strings, k) - vs := s.NumLabel[k] - units := s.NumUnit[k] - for i, v := range vs { - var unitX int64 - if len(units) != 0 { - unitX = addString(strings, units[i]) - } - s.labelX = append(s.labelX, - label{ - keyX: keyX, - numX: v, - unitX: unitX, - }, - ) - } - } - s.locationIDX = make([]uint64, len(s.Location)) - for i, loc := range s.Location { - s.locationIDX[i] = loc.ID - } - } - - for _, m := range p.Mapping { - m.fileX = addString(strings, m.File) - m.buildIDX = addString(strings, m.BuildID) - } - - for _, l := range p.Location { - for i, ln := range l.Line { - if ln.Function != nil { - l.Line[i].functionIDX = ln.Function.ID - } else { - l.Line[i].functionIDX = 0 - } - } - if l.Mapping != nil { - l.mappingIDX = l.Mapping.ID - } else { - l.mappingIDX = 0 - } - } - for _, f := range p.Function { - f.nameX = addString(strings, f.Name) - f.systemNameX = addString(strings, f.SystemName) - f.filenameX = addString(strings, f.Filename) - } - - p.dropFramesX = addString(strings, p.DropFrames) - p.keepFramesX = addString(strings, p.KeepFrames) - - if pt := p.PeriodType; pt != nil { - pt.typeX = addString(strings, pt.Type) - pt.unitX = addString(strings, pt.Unit) - } - - p.commentX = nil - for _, c := range p.Comments { - p.commentX = append(p.commentX, addString(strings, c)) - } - - p.defaultSampleTypeX = addString(strings, p.DefaultSampleType) - p.docURLX = addString(strings, p.DocURL) - - p.stringTable = make([]string, len(strings)) - for s, i := range strings { - p.stringTable[i] = s - } -} - -func (p *Profile) encode(b *buffer) { - for _, x := range p.SampleType { - encodeMessage(b, 1, x) - } - for _, x := range p.Sample { - encodeMessage(b, 2, x) - } - for _, x := range p.Mapping { - encodeMessage(b, 3, x) - } - for _, x := range p.Location { - encodeMessage(b, 4, x) - } - for _, x := range p.Function { - encodeMessage(b, 5, x) - } - encodeStrings(b, 6, p.stringTable) - encodeInt64Opt(b, 7, p.dropFramesX) - encodeInt64Opt(b, 8, p.keepFramesX) - encodeInt64Opt(b, 9, p.TimeNanos) - encodeInt64Opt(b, 10, p.DurationNanos) - if pt := p.PeriodType; pt != nil && (pt.typeX != 0 || pt.unitX != 0) { - encodeMessage(b, 11, p.PeriodType) - } - encodeInt64Opt(b, 12, p.Period) - encodeInt64s(b, 13, p.commentX) - encodeInt64(b, 14, p.defaultSampleTypeX) - encodeInt64Opt(b, 15, p.docURLX) -} - -var profileDecoder = []decoder{ - nil, // 0 - // repeated ValueType sample_type = 1 - func(b *buffer, m message) error { - x := new(ValueType) - pp := m.(*Profile) - pp.SampleType = append(pp.SampleType, x) - return decodeMessage(b, x) - }, - // repeated Sample sample = 2 - func(b *buffer, m message) error { - x := new(Sample) - pp := m.(*Profile) - pp.Sample = append(pp.Sample, x) - return decodeMessage(b, x) - }, - // repeated Mapping mapping = 3 - func(b *buffer, m message) error { - x := new(Mapping) - pp := m.(*Profile) - pp.Mapping = append(pp.Mapping, x) - return decodeMessage(b, x) - }, - // repeated Location location = 4 - func(b *buffer, m message) error { - x := new(Location) - x.Line = b.tmpLines[:0] // Use shared space temporarily - pp := m.(*Profile) - pp.Location = append(pp.Location, x) - err := decodeMessage(b, x) - b.tmpLines = x.Line[:0] - // Copy to shrink size and detach from shared space. - x.Line = append([]Line(nil), x.Line...) - return err - }, - // repeated Function function = 5 - func(b *buffer, m message) error { - x := new(Function) - pp := m.(*Profile) - pp.Function = append(pp.Function, x) - return decodeMessage(b, x) - }, - // repeated string string_table = 6 - func(b *buffer, m message) error { - err := decodeStrings(b, &m.(*Profile).stringTable) - if err != nil { - return err - } - if m.(*Profile).stringTable[0] != "" { - return errors.New("string_table[0] must be ''") - } - return nil - }, - // int64 drop_frames = 7 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).dropFramesX) }, - // int64 keep_frames = 8 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) }, - // int64 time_nanos = 9 - func(b *buffer, m message) error { - if m.(*Profile).TimeNanos != 0 { - return errConcatProfile - } - return decodeInt64(b, &m.(*Profile).TimeNanos) - }, - // int64 duration_nanos = 10 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) }, - // ValueType period_type = 11 - func(b *buffer, m message) error { - x := new(ValueType) - pp := m.(*Profile) - pp.PeriodType = x - return decodeMessage(b, x) - }, - // int64 period = 12 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) }, - // repeated int64 comment = 13 - func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Profile).commentX) }, - // int64 defaultSampleType = 14 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).defaultSampleTypeX) }, - // string doc_link = 15; - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).docURLX) }, -} - -// postDecode takes the unexported fields populated by decode (with -// suffix X) and populates the corresponding exported fields. -// The unexported fields are cleared up to facilitate testing. -func (p *Profile) postDecode() error { - var err error - mappings := make(map[uint64]*Mapping, len(p.Mapping)) - mappingIds := make([]*Mapping, len(p.Mapping)+1) - for _, m := range p.Mapping { - m.File, err = getString(p.stringTable, &m.fileX, err) - m.BuildID, err = getString(p.stringTable, &m.buildIDX, err) - if m.ID < uint64(len(mappingIds)) { - mappingIds[m.ID] = m - } else { - mappings[m.ID] = m - } - - // If this a main linux kernel mapping with a relocation symbol suffix - // ("[kernel.kallsyms]_text"), extract said suffix. - // It is fairly hacky to handle at this level, but the alternatives appear even worse. - const prefix = "[kernel.kallsyms]" - if strings.HasPrefix(m.File, prefix) { - m.KernelRelocationSymbol = m.File[len(prefix):] - } - } - - functions := make(map[uint64]*Function, len(p.Function)) - functionIds := make([]*Function, len(p.Function)+1) - for _, f := range p.Function { - f.Name, err = getString(p.stringTable, &f.nameX, err) - f.SystemName, err = getString(p.stringTable, &f.systemNameX, err) - f.Filename, err = getString(p.stringTable, &f.filenameX, err) - if f.ID < uint64(len(functionIds)) { - functionIds[f.ID] = f - } else { - functions[f.ID] = f - } - } - - locations := make(map[uint64]*Location, len(p.Location)) - locationIds := make([]*Location, len(p.Location)+1) - for _, l := range p.Location { - if id := l.mappingIDX; id < uint64(len(mappingIds)) { - l.Mapping = mappingIds[id] - } else { - l.Mapping = mappings[id] - } - l.mappingIDX = 0 - for i, ln := range l.Line { - if id := ln.functionIDX; id != 0 { - l.Line[i].functionIDX = 0 - if id < uint64(len(functionIds)) { - l.Line[i].Function = functionIds[id] - } else { - l.Line[i].Function = functions[id] - } - } - } - if l.ID < uint64(len(locationIds)) { - locationIds[l.ID] = l - } else { - locations[l.ID] = l - } - } - - for _, st := range p.SampleType { - st.Type, err = getString(p.stringTable, &st.typeX, err) - st.Unit, err = getString(p.stringTable, &st.unitX, err) - } - - // Pre-allocate space for all locations. - numLocations := 0 - for _, s := range p.Sample { - numLocations += len(s.locationIDX) - } - locBuffer := make([]*Location, numLocations) - - for _, s := range p.Sample { - if len(s.labelX) > 0 { - labels := make(map[string][]string, len(s.labelX)) - numLabels := make(map[string][]int64, len(s.labelX)) - numUnits := make(map[string][]string, len(s.labelX)) - for _, l := range s.labelX { - var key, value string - key, err = getString(p.stringTable, &l.keyX, err) - if l.strX != 0 { - value, err = getString(p.stringTable, &l.strX, err) - labels[key] = append(labels[key], value) - } else if l.numX != 0 || l.unitX != 0 { - numValues := numLabels[key] - units := numUnits[key] - if l.unitX != 0 { - var unit string - unit, err = getString(p.stringTable, &l.unitX, err) - units = padStringArray(units, len(numValues)) - numUnits[key] = append(units, unit) - } - numLabels[key] = append(numLabels[key], l.numX) - } - } - if len(labels) > 0 { - s.Label = labels - } - if len(numLabels) > 0 { - s.NumLabel = numLabels - for key, units := range numUnits { - if len(units) > 0 { - numUnits[key] = padStringArray(units, len(numLabels[key])) - } - } - s.NumUnit = numUnits - } - } - - s.Location = locBuffer[:len(s.locationIDX)] - locBuffer = locBuffer[len(s.locationIDX):] - for i, lid := range s.locationIDX { - if lid < uint64(len(locationIds)) { - s.Location[i] = locationIds[lid] - } else { - s.Location[i] = locations[lid] - } - } - s.locationIDX = nil - } - - p.DropFrames, err = getString(p.stringTable, &p.dropFramesX, err) - p.KeepFrames, err = getString(p.stringTable, &p.keepFramesX, err) - - if pt := p.PeriodType; pt == nil { - p.PeriodType = &ValueType{} - } - - if pt := p.PeriodType; pt != nil { - pt.Type, err = getString(p.stringTable, &pt.typeX, err) - pt.Unit, err = getString(p.stringTable, &pt.unitX, err) - } - - for _, i := range p.commentX { - var c string - c, err = getString(p.stringTable, &i, err) - p.Comments = append(p.Comments, c) - } - - p.commentX = nil - p.DefaultSampleType, err = getString(p.stringTable, &p.defaultSampleTypeX, err) - p.DocURL, err = getString(p.stringTable, &p.docURLX, err) - p.stringTable = nil - return err -} - -// padStringArray pads arr with enough empty strings to make arr -// length l when arr's length is less than l. -func padStringArray(arr []string, l int) []string { - if l <= len(arr) { - return arr - } - return append(arr, make([]string, l-len(arr))...) -} - -func (p *ValueType) decoder() []decoder { - return valueTypeDecoder -} - -func (p *ValueType) encode(b *buffer) { - encodeInt64Opt(b, 1, p.typeX) - encodeInt64Opt(b, 2, p.unitX) -} - -var valueTypeDecoder = []decoder{ - nil, // 0 - // optional int64 type = 1 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) }, - // optional int64 unit = 2 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).unitX) }, -} - -func (p *Sample) decoder() []decoder { - return sampleDecoder -} - -func (p *Sample) encode(b *buffer) { - encodeUint64s(b, 1, p.locationIDX) - encodeInt64s(b, 2, p.Value) - for _, x := range p.labelX { - encodeMessage(b, 3, x) - } -} - -var sampleDecoder = []decoder{ - nil, // 0 - // repeated uint64 location = 1 - func(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) }, - // repeated int64 value = 2 - func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) }, - // repeated Label label = 3 - func(b *buffer, m message) error { - s := m.(*Sample) - n := len(s.labelX) - s.labelX = append(s.labelX, label{}) - return decodeMessage(b, &s.labelX[n]) - }, -} - -func (p label) decoder() []decoder { - return labelDecoder -} - -func (p label) encode(b *buffer) { - encodeInt64Opt(b, 1, p.keyX) - encodeInt64Opt(b, 2, p.strX) - encodeInt64Opt(b, 3, p.numX) - encodeInt64Opt(b, 4, p.unitX) -} - -var labelDecoder = []decoder{ - nil, // 0 - // optional int64 key = 1 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).keyX) }, - // optional int64 str = 2 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).strX) }, - // optional int64 num = 3 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).numX) }, - // optional int64 num = 4 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).unitX) }, -} - -func (p *Mapping) decoder() []decoder { - return mappingDecoder -} - -func (p *Mapping) encode(b *buffer) { - encodeUint64Opt(b, 1, p.ID) - encodeUint64Opt(b, 2, p.Start) - encodeUint64Opt(b, 3, p.Limit) - encodeUint64Opt(b, 4, p.Offset) - encodeInt64Opt(b, 5, p.fileX) - encodeInt64Opt(b, 6, p.buildIDX) - encodeBoolOpt(b, 7, p.HasFunctions) - encodeBoolOpt(b, 8, p.HasFilenames) - encodeBoolOpt(b, 9, p.HasLineNumbers) - encodeBoolOpt(b, 10, p.HasInlineFrames) -} - -var mappingDecoder = []decoder{ - nil, // 0 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) }, // optional uint64 id = 1 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) }, // optional uint64 memory_offset = 2 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) }, // optional uint64 memory_limit = 3 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) }, // optional uint64 file_offset = 4 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) }, // optional int64 filename = 5 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) }, // optional int64 build_id = 6 - func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) }, // optional bool has_functions = 7 - func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) }, // optional bool has_filenames = 8 - func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) }, // optional bool has_line_numbers = 9 - func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10 -} - -func (p *Location) decoder() []decoder { - return locationDecoder -} - -func (p *Location) encode(b *buffer) { - encodeUint64Opt(b, 1, p.ID) - encodeUint64Opt(b, 2, p.mappingIDX) - encodeUint64Opt(b, 3, p.Address) - for i := range p.Line { - encodeMessage(b, 4, &p.Line[i]) - } - encodeBoolOpt(b, 5, p.IsFolded) -} - -var locationDecoder = []decoder{ - nil, // 0 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) }, // optional uint64 id = 1; - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2; - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) }, // optional uint64 address = 3; - func(b *buffer, m message) error { // repeated Line line = 4 - pp := m.(*Location) - n := len(pp.Line) - pp.Line = append(pp.Line, Line{}) - return decodeMessage(b, &pp.Line[n]) - }, - func(b *buffer, m message) error { return decodeBool(b, &m.(*Location).IsFolded) }, // optional bool is_folded = 5; -} - -func (p *Line) decoder() []decoder { - return lineDecoder -} - -func (p *Line) encode(b *buffer) { - encodeUint64Opt(b, 1, p.functionIDX) - encodeInt64Opt(b, 2, p.Line) - encodeInt64Opt(b, 3, p.Column) -} - -var lineDecoder = []decoder{ - nil, // 0 - // optional uint64 function_id = 1 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) }, - // optional int64 line = 2 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) }, - // optional int64 column = 3 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Column) }, -} - -func (p *Function) decoder() []decoder { - return functionDecoder -} - -func (p *Function) encode(b *buffer) { - encodeUint64Opt(b, 1, p.ID) - encodeInt64Opt(b, 2, p.nameX) - encodeInt64Opt(b, 3, p.systemNameX) - encodeInt64Opt(b, 4, p.filenameX) - encodeInt64Opt(b, 5, p.StartLine) -} - -var functionDecoder = []decoder{ - nil, // 0 - // optional uint64 id = 1 - func(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) }, - // optional int64 function_name = 2 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) }, - // optional int64 function_system_name = 3 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) }, - // repeated int64 filename = 4 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) }, - // optional int64 start_line = 5 - func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).StartLine) }, -} - -func addString(strings map[string]int, s string) int64 { - i, ok := strings[s] - if !ok { - i = len(strings) - strings[s] = i - } - return int64(i) -} - -func getString(strings []string, strng *int64, err error) (string, error) { - if err != nil { - return "", err - } - s := int(*strng) - if s < 0 || s >= len(strings) { - return "", errMalformed - } - *strng = 0 - return strings[s], nil -} diff --git a/vendor/github.com/google/pprof/profile/filter.go b/vendor/github.com/google/pprof/profile/filter.go deleted file mode 100644 index c794b939..00000000 --- a/vendor/github.com/google/pprof/profile/filter.go +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// 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 profile - -// Implements methods to filter samples from profiles. - -import "regexp" - -// FilterSamplesByName filters the samples in a profile and only keeps -// samples where at least one frame matches focus but none match ignore. -// Returns true is the corresponding regexp matched at least one sample. -func (p *Profile) FilterSamplesByName(focus, ignore, hide, show *regexp.Regexp) (fm, im, hm, hnm bool) { - if focus == nil && ignore == nil && hide == nil && show == nil { - fm = true // Missing focus implies a match - return - } - focusOrIgnore := make(map[uint64]bool) - hidden := make(map[uint64]bool) - for _, l := range p.Location { - if ignore != nil && l.matchesName(ignore) { - im = true - focusOrIgnore[l.ID] = false - } else if focus == nil || l.matchesName(focus) { - fm = true - focusOrIgnore[l.ID] = true - } - - if hide != nil && l.matchesName(hide) { - hm = true - l.Line = l.unmatchedLines(hide) - if len(l.Line) == 0 { - hidden[l.ID] = true - } - } - if show != nil { - l.Line = l.matchedLines(show) - if len(l.Line) == 0 { - hidden[l.ID] = true - } else { - hnm = true - } - } - } - - s := make([]*Sample, 0, len(p.Sample)) - for _, sample := range p.Sample { - if focusedAndNotIgnored(sample.Location, focusOrIgnore) { - if len(hidden) > 0 { - var locs []*Location - for _, loc := range sample.Location { - if !hidden[loc.ID] { - locs = append(locs, loc) - } - } - if len(locs) == 0 { - // Remove sample with no locations (by not adding it to s). - continue - } - sample.Location = locs - } - s = append(s, sample) - } - } - p.Sample = s - - return -} - -// ShowFrom drops all stack frames above the highest matching frame and returns -// whether a match was found. If showFrom is nil it returns false and does not -// modify the profile. -// -// Example: consider a sample with frames [A, B, C, B], where A is the root. -// ShowFrom(nil) returns false and has frames [A, B, C, B]. -// ShowFrom(A) returns true and has frames [A, B, C, B]. -// ShowFrom(B) returns true and has frames [B, C, B]. -// ShowFrom(C) returns true and has frames [C, B]. -// ShowFrom(D) returns false and drops the sample because no frames remain. -func (p *Profile) ShowFrom(showFrom *regexp.Regexp) (matched bool) { - if showFrom == nil { - return false - } - // showFromLocs stores location IDs that matched ShowFrom. - showFromLocs := make(map[uint64]bool) - // Apply to locations. - for _, loc := range p.Location { - if filterShowFromLocation(loc, showFrom) { - showFromLocs[loc.ID] = true - matched = true - } - } - // For all samples, strip locations after the highest matching one. - s := make([]*Sample, 0, len(p.Sample)) - for _, sample := range p.Sample { - for i := len(sample.Location) - 1; i >= 0; i-- { - if showFromLocs[sample.Location[i].ID] { - sample.Location = sample.Location[:i+1] - s = append(s, sample) - break - } - } - } - p.Sample = s - return matched -} - -// filterShowFromLocation tests a showFrom regex against a location, removes -// lines after the last match and returns whether a match was found. If the -// mapping is matched, then all lines are kept. -func filterShowFromLocation(loc *Location, showFrom *regexp.Regexp) bool { - if m := loc.Mapping; m != nil && showFrom.MatchString(m.File) { - return true - } - if i := loc.lastMatchedLineIndex(showFrom); i >= 0 { - loc.Line = loc.Line[:i+1] - return true - } - return false -} - -// lastMatchedLineIndex returns the index of the last line that matches a regex, -// or -1 if no match is found. -func (loc *Location) lastMatchedLineIndex(re *regexp.Regexp) int { - for i := len(loc.Line) - 1; i >= 0; i-- { - if fn := loc.Line[i].Function; fn != nil { - if re.MatchString(fn.Name) || re.MatchString(fn.Filename) { - return i - } - } - } - return -1 -} - -// FilterTagsByName filters the tags in a profile and only keeps -// tags that match show and not hide. -func (p *Profile) FilterTagsByName(show, hide *regexp.Regexp) (sm, hm bool) { - matchRemove := func(name string) bool { - matchShow := show == nil || show.MatchString(name) - matchHide := hide != nil && hide.MatchString(name) - - if matchShow { - sm = true - } - if matchHide { - hm = true - } - return !matchShow || matchHide - } - for _, s := range p.Sample { - for lab := range s.Label { - if matchRemove(lab) { - delete(s.Label, lab) - } - } - for lab := range s.NumLabel { - if matchRemove(lab) { - delete(s.NumLabel, lab) - } - } - } - return -} - -// matchesName returns whether the location matches the regular -// expression. It checks any available function names, file names, and -// mapping object filename. -func (loc *Location) matchesName(re *regexp.Regexp) bool { - for _, ln := range loc.Line { - if fn := ln.Function; fn != nil { - if re.MatchString(fn.Name) || re.MatchString(fn.Filename) { - return true - } - } - } - if m := loc.Mapping; m != nil && re.MatchString(m.File) { - return true - } - return false -} - -// unmatchedLines returns the lines in the location that do not match -// the regular expression. -func (loc *Location) unmatchedLines(re *regexp.Regexp) []Line { - if m := loc.Mapping; m != nil && re.MatchString(m.File) { - return nil - } - var lines []Line - for _, ln := range loc.Line { - if fn := ln.Function; fn != nil { - if re.MatchString(fn.Name) || re.MatchString(fn.Filename) { - continue - } - } - lines = append(lines, ln) - } - return lines -} - -// matchedLines returns the lines in the location that match -// the regular expression. -func (loc *Location) matchedLines(re *regexp.Regexp) []Line { - if m := loc.Mapping; m != nil && re.MatchString(m.File) { - return loc.Line - } - var lines []Line - for _, ln := range loc.Line { - if fn := ln.Function; fn != nil { - if !re.MatchString(fn.Name) && !re.MatchString(fn.Filename) { - continue - } - } - lines = append(lines, ln) - } - return lines -} - -// focusedAndNotIgnored looks up a slice of ids against a map of -// focused/ignored locations. The map only contains locations that are -// explicitly focused or ignored. Returns whether there is at least -// one focused location but no ignored locations. -func focusedAndNotIgnored(locs []*Location, m map[uint64]bool) bool { - var f bool - for _, loc := range locs { - if focus, focusOrIgnore := m[loc.ID]; focusOrIgnore { - if focus { - // Found focused location. Must keep searching in case there - // is an ignored one as well. - f = true - } else { - // Found ignored location. Can return false right away. - return false - } - } - } - return f -} - -// TagMatch selects tags for filtering -type TagMatch func(s *Sample) bool - -// FilterSamplesByTag removes all samples from the profile, except -// those that match focus and do not match the ignore regular -// expression. -func (p *Profile) FilterSamplesByTag(focus, ignore TagMatch) (fm, im bool) { - samples := make([]*Sample, 0, len(p.Sample)) - for _, s := range p.Sample { - focused, ignored := true, false - if focus != nil { - focused = focus(s) - } - if ignore != nil { - ignored = ignore(s) - } - fm = fm || focused - im = im || ignored - if focused && !ignored { - samples = append(samples, s) - } - } - p.Sample = samples - return -} diff --git a/vendor/github.com/google/pprof/profile/index.go b/vendor/github.com/google/pprof/profile/index.go deleted file mode 100644 index bef1d604..00000000 --- a/vendor/github.com/google/pprof/profile/index.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2016 Google Inc. All Rights Reserved. -// -// 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 profile - -import ( - "fmt" - "strconv" - "strings" -) - -// SampleIndexByName returns the appropriate index for a value of sample index. -// If numeric, it returns the number, otherwise it looks up the text in the -// profile sample types. -func (p *Profile) SampleIndexByName(sampleIndex string) (int, error) { - if sampleIndex == "" { - if dst := p.DefaultSampleType; dst != "" { - for i, t := range sampleTypes(p) { - if t == dst { - return i, nil - } - } - } - // By default select the last sample value - return len(p.SampleType) - 1, nil - } - if i, err := strconv.Atoi(sampleIndex); err == nil { - if i < 0 || i >= len(p.SampleType) { - return 0, fmt.Errorf("sample_index %s is outside the range [0..%d]", sampleIndex, len(p.SampleType)-1) - } - return i, nil - } - - // Remove the inuse_ prefix to support legacy pprof options - // "inuse_space" and "inuse_objects" for profiles containing types - // "space" and "objects". - noInuse := strings.TrimPrefix(sampleIndex, "inuse_") - for i, t := range p.SampleType { - if t.Type == sampleIndex || t.Type == noInuse { - return i, nil - } - } - - return 0, fmt.Errorf("sample_index %q must be one of: %v", sampleIndex, sampleTypes(p)) -} - -func sampleTypes(p *Profile) []string { - types := make([]string, len(p.SampleType)) - for i, t := range p.SampleType { - types[i] = t.Type - } - return types -} diff --git a/vendor/github.com/google/pprof/profile/legacy_java_profile.go b/vendor/github.com/google/pprof/profile/legacy_java_profile.go deleted file mode 100644 index 4580bab1..00000000 --- a/vendor/github.com/google/pprof/profile/legacy_java_profile.go +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// 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. - -// This file implements parsers to convert java legacy profiles into -// the profile.proto format. - -package profile - -import ( - "bytes" - "fmt" - "io" - "path/filepath" - "regexp" - "strconv" - "strings" -) - -var ( - attributeRx = regexp.MustCompile(`([\w ]+)=([\w ]+)`) - javaSampleRx = regexp.MustCompile(` *(\d+) +(\d+) +@ +([ x0-9a-f]*)`) - javaLocationRx = regexp.MustCompile(`^\s*0x([[:xdigit:]]+)\s+(.*)\s*$`) - javaLocationFileLineRx = regexp.MustCompile(`^(.*)\s+\((.+):(-?[[:digit:]]+)\)$`) - javaLocationPathRx = regexp.MustCompile(`^(.*)\s+\((.*)\)$`) -) - -// javaCPUProfile returns a new Profile from profilez data. -// b is the profile bytes after the header, period is the profiling -// period, and parse is a function to parse 8-byte chunks from the -// profile in its native endianness. -func javaCPUProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte)) (*Profile, error) { - p := &Profile{ - Period: period * 1000, - PeriodType: &ValueType{Type: "cpu", Unit: "nanoseconds"}, - SampleType: []*ValueType{{Type: "samples", Unit: "count"}, {Type: "cpu", Unit: "nanoseconds"}}, - } - var err error - var locs map[uint64]*Location - if b, locs, err = parseCPUSamples(b, parse, false, p); err != nil { - return nil, err - } - - if err = parseJavaLocations(b, locs, p); err != nil { - return nil, err - } - - // Strip out addresses for better merge. - if err = p.Aggregate(true, true, true, true, false, false); err != nil { - return nil, err - } - - return p, nil -} - -// parseJavaProfile returns a new profile from heapz or contentionz -// data. b is the profile bytes after the header. -func parseJavaProfile(b []byte) (*Profile, error) { - h := bytes.SplitAfterN(b, []byte("\n"), 2) - if len(h) < 2 { - return nil, errUnrecognized - } - - p := &Profile{ - PeriodType: &ValueType{}, - } - header := string(bytes.TrimSpace(h[0])) - - var err error - var pType string - switch header { - case "--- heapz 1 ---": - pType = "heap" - case "--- contentionz 1 ---": - pType = "contention" - default: - return nil, errUnrecognized - } - - if b, err = parseJavaHeader(pType, h[1], p); err != nil { - return nil, err - } - var locs map[uint64]*Location - if b, locs, err = parseJavaSamples(pType, b, p); err != nil { - return nil, err - } - if err = parseJavaLocations(b, locs, p); err != nil { - return nil, err - } - - // Strip out addresses for better merge. - if err = p.Aggregate(true, true, true, true, false, false); err != nil { - return nil, err - } - - return p, nil -} - -// parseJavaHeader parses the attribute section on a java profile and -// populates a profile. Returns the remainder of the buffer after all -// attributes. -func parseJavaHeader(pType string, b []byte, p *Profile) ([]byte, error) { - nextNewLine := bytes.IndexByte(b, byte('\n')) - for nextNewLine != -1 { - line := string(bytes.TrimSpace(b[0:nextNewLine])) - if line != "" { - h := attributeRx.FindStringSubmatch(line) - if h == nil { - // Not a valid attribute, exit. - return b, nil - } - - attribute, value := strings.TrimSpace(h[1]), strings.TrimSpace(h[2]) - var err error - switch pType + "/" + attribute { - case "heap/format", "cpu/format", "contention/format": - if value != "java" { - return nil, errUnrecognized - } - case "heap/resolution": - p.SampleType = []*ValueType{ - {Type: "inuse_objects", Unit: "count"}, - {Type: "inuse_space", Unit: value}, - } - case "contention/resolution": - p.SampleType = []*ValueType{ - {Type: "contentions", Unit: "count"}, - {Type: "delay", Unit: value}, - } - case "contention/sampling period": - p.PeriodType = &ValueType{ - Type: "contentions", Unit: "count", - } - if p.Period, err = strconv.ParseInt(value, 0, 64); err != nil { - return nil, fmt.Errorf("failed to parse attribute %s: %v", line, err) - } - case "contention/ms since reset": - millis, err := strconv.ParseInt(value, 0, 64) - if err != nil { - return nil, fmt.Errorf("failed to parse attribute %s: %v", line, err) - } - p.DurationNanos = millis * 1000 * 1000 - default: - return nil, errUnrecognized - } - } - // Grab next line. - b = b[nextNewLine+1:] - nextNewLine = bytes.IndexByte(b, byte('\n')) - } - return b, nil -} - -// parseJavaSamples parses the samples from a java profile and -// populates the Samples in a profile. Returns the remainder of the -// buffer after the samples. -func parseJavaSamples(pType string, b []byte, p *Profile) ([]byte, map[uint64]*Location, error) { - nextNewLine := bytes.IndexByte(b, byte('\n')) - locs := make(map[uint64]*Location) - for nextNewLine != -1 { - line := string(bytes.TrimSpace(b[0:nextNewLine])) - if line != "" { - sample := javaSampleRx.FindStringSubmatch(line) - if sample == nil { - // Not a valid sample, exit. - return b, locs, nil - } - - // Java profiles have data/fields inverted compared to other - // profile types. - var err error - value1, value2, value3 := sample[2], sample[1], sample[3] - addrs, err := parseHexAddresses(value3) - if err != nil { - return nil, nil, fmt.Errorf("malformed sample: %s: %v", line, err) - } - - var sloc []*Location - for _, addr := range addrs { - loc := locs[addr] - if locs[addr] == nil { - loc = &Location{ - Address: addr, - } - p.Location = append(p.Location, loc) - locs[addr] = loc - } - sloc = append(sloc, loc) - } - s := &Sample{ - Value: make([]int64, 2), - Location: sloc, - } - - if s.Value[0], err = strconv.ParseInt(value1, 0, 64); err != nil { - return nil, nil, fmt.Errorf("parsing sample %s: %v", line, err) - } - if s.Value[1], err = strconv.ParseInt(value2, 0, 64); err != nil { - return nil, nil, fmt.Errorf("parsing sample %s: %v", line, err) - } - - switch pType { - case "heap": - const javaHeapzSamplingRate = 524288 // 512K - if s.Value[0] == 0 { - return nil, nil, fmt.Errorf("parsing sample %s: second value must be non-zero", line) - } - s.NumLabel = map[string][]int64{"bytes": {s.Value[1] / s.Value[0]}} - s.Value[0], s.Value[1] = scaleHeapSample(s.Value[0], s.Value[1], javaHeapzSamplingRate) - case "contention": - if period := p.Period; period != 0 { - s.Value[0] = s.Value[0] * p.Period - s.Value[1] = s.Value[1] * p.Period - } - } - p.Sample = append(p.Sample, s) - } - // Grab next line. - b = b[nextNewLine+1:] - nextNewLine = bytes.IndexByte(b, byte('\n')) - } - return b, locs, nil -} - -// parseJavaLocations parses the location information in a java -// profile and populates the Locations in a profile. It uses the -// location addresses from the profile as both the ID of each -// location. -func parseJavaLocations(b []byte, locs map[uint64]*Location, p *Profile) error { - r := bytes.NewBuffer(b) - fns := make(map[string]*Function) - for { - line, err := r.ReadString('\n') - if err != nil { - if err != io.EOF { - return err - } - if line == "" { - break - } - } - - if line = strings.TrimSpace(line); line == "" { - continue - } - - jloc := javaLocationRx.FindStringSubmatch(line) - if len(jloc) != 3 { - continue - } - addr, err := strconv.ParseUint(jloc[1], 16, 64) - if err != nil { - return fmt.Errorf("parsing sample %s: %v", line, err) - } - loc := locs[addr] - if loc == nil { - // Unused/unseen - continue - } - var lineFunc, lineFile string - var lineNo int64 - - if fileLine := javaLocationFileLineRx.FindStringSubmatch(jloc[2]); len(fileLine) == 4 { - // Found a line of the form: "function (file:line)" - lineFunc, lineFile = fileLine[1], fileLine[2] - if n, err := strconv.ParseInt(fileLine[3], 10, 64); err == nil && n > 0 { - lineNo = n - } - } else if filePath := javaLocationPathRx.FindStringSubmatch(jloc[2]); len(filePath) == 3 { - // If there's not a file:line, it's a shared library path. - // The path isn't interesting, so just give the .so. - lineFunc, lineFile = filePath[1], filepath.Base(filePath[2]) - } else if strings.Contains(jloc[2], "generated stub/JIT") { - lineFunc = "STUB" - } else { - // Treat whole line as the function name. This is used by the - // java agent for internal states such as "GC" or "VM". - lineFunc = jloc[2] - } - fn := fns[lineFunc] - - if fn == nil { - fn = &Function{ - Name: lineFunc, - SystemName: lineFunc, - Filename: lineFile, - } - fns[lineFunc] = fn - p.Function = append(p.Function, fn) - } - loc.Line = []Line{ - { - Function: fn, - Line: lineNo, - }, - } - loc.Address = 0 - } - - p.remapLocationIDs() - p.remapFunctionIDs() - p.remapMappingIDs() - - return nil -} diff --git a/vendor/github.com/google/pprof/profile/legacy_profile.go b/vendor/github.com/google/pprof/profile/legacy_profile.go deleted file mode 100644 index 8d07fd6c..00000000 --- a/vendor/github.com/google/pprof/profile/legacy_profile.go +++ /dev/null @@ -1,1228 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// 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. - -// This file implements parsers to convert legacy profiles into the -// profile.proto format. - -package profile - -import ( - "bufio" - "bytes" - "fmt" - "io" - "math" - "regexp" - "strconv" - "strings" -) - -var ( - countStartRE = regexp.MustCompile(`\A(\S+) profile: total \d+\z`) - countRE = regexp.MustCompile(`\A(\d+) @(( 0x[0-9a-f]+)+)\z`) - - heapHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] *@ *(heap[_a-z0-9]*)/?(\d*)`) - heapSampleRE = regexp.MustCompile(`(-?\d+): *(-?\d+) *\[ *(\d+): *(\d+) *] @([ x0-9a-f]*)`) - - contentionSampleRE = regexp.MustCompile(`(\d+) *(\d+) @([ x0-9a-f]*)`) - - hexNumberRE = regexp.MustCompile(`0x[0-9a-f]+`) - - growthHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ growthz?`) - - fragmentationHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ fragmentationz?`) - - threadzStartRE = regexp.MustCompile(`--- threadz \d+ ---`) - threadStartRE = regexp.MustCompile(`--- Thread ([[:xdigit:]]+) \(name: (.*)/(\d+)\) stack: ---`) - - // Regular expressions to parse process mappings. Support the format used by Linux /proc/.../maps and other tools. - // Recommended format: - // Start End object file name offset(optional) linker build id - // 0x40000-0x80000 /path/to/binary (@FF00) abc123456 - spaceDigits = `\s+[[:digit:]]+` - hexPair = `\s+[[:xdigit:]]+:[[:xdigit:]]+` - oSpace = `\s*` - // Capturing expressions. - cHex = `(?:0x)?([[:xdigit:]]+)` - cHexRange = `\s*` + cHex + `[\s-]?` + oSpace + cHex + `:?` - cSpaceString = `(?:\s+(\S+))?` - cSpaceHex = `(?:\s+([[:xdigit:]]+))?` - cSpaceAtOffset = `(?:\s+\(@([[:xdigit:]]+)\))?` - cPerm = `(?:\s+([-rwxp]+))?` - - procMapsRE = regexp.MustCompile(`^` + cHexRange + cPerm + cSpaceHex + hexPair + spaceDigits + cSpaceString) - briefMapsRE = regexp.MustCompile(`^` + cHexRange + cPerm + cSpaceString + cSpaceAtOffset + cSpaceHex) - - // Regular expression to parse log data, of the form: - // ... file:line] msg... - logInfoRE = regexp.MustCompile(`^[^\[\]]+:[0-9]+]\s`) -) - -func isSpaceOrComment(line string) bool { - trimmed := strings.TrimSpace(line) - return len(trimmed) == 0 || trimmed[0] == '#' -} - -// parseGoCount parses a Go count profile (e.g., threadcreate or -// goroutine) and returns a new Profile. -func parseGoCount(b []byte) (*Profile, error) { - s := bufio.NewScanner(bytes.NewBuffer(b)) - // Skip comments at the beginning of the file. - for s.Scan() && isSpaceOrComment(s.Text()) { - } - if err := s.Err(); err != nil { - return nil, err - } - m := countStartRE.FindStringSubmatch(s.Text()) - if m == nil { - return nil, errUnrecognized - } - profileType := m[1] - p := &Profile{ - PeriodType: &ValueType{Type: profileType, Unit: "count"}, - Period: 1, - SampleType: []*ValueType{{Type: profileType, Unit: "count"}}, - } - locations := make(map[uint64]*Location) - for s.Scan() { - line := s.Text() - if isSpaceOrComment(line) { - continue - } - if strings.HasPrefix(line, "---") { - break - } - m := countRE.FindStringSubmatch(line) - if m == nil { - return nil, errMalformed - } - n, err := strconv.ParseInt(m[1], 0, 64) - if err != nil { - return nil, errMalformed - } - fields := strings.Fields(m[2]) - locs := make([]*Location, 0, len(fields)) - for _, stk := range fields { - addr, err := strconv.ParseUint(stk, 0, 64) - if err != nil { - return nil, errMalformed - } - // Adjust all frames by -1 to land on top of the call instruction. - addr-- - loc := locations[addr] - if loc == nil { - loc = &Location{ - Address: addr, - } - locations[addr] = loc - p.Location = append(p.Location, loc) - } - locs = append(locs, loc) - } - p.Sample = append(p.Sample, &Sample{ - Location: locs, - Value: []int64{n}, - }) - } - if err := s.Err(); err != nil { - return nil, err - } - - if err := parseAdditionalSections(s, p); err != nil { - return nil, err - } - return p, nil -} - -// remapLocationIDs ensures there is a location for each address -// referenced by a sample, and remaps the samples to point to the new -// location ids. -func (p *Profile) remapLocationIDs() { - seen := make(map[*Location]bool, len(p.Location)) - var locs []*Location - - for _, s := range p.Sample { - for _, l := range s.Location { - if seen[l] { - continue - } - l.ID = uint64(len(locs) + 1) - locs = append(locs, l) - seen[l] = true - } - } - p.Location = locs -} - -func (p *Profile) remapFunctionIDs() { - seen := make(map[*Function]bool, len(p.Function)) - var fns []*Function - - for _, l := range p.Location { - for _, ln := range l.Line { - fn := ln.Function - if fn == nil || seen[fn] { - continue - } - fn.ID = uint64(len(fns) + 1) - fns = append(fns, fn) - seen[fn] = true - } - } - p.Function = fns -} - -// remapMappingIDs matches location addresses with existing mappings -// and updates them appropriately. This is O(N*M), if this ever shows -// up as a bottleneck, evaluate sorting the mappings and doing a -// binary search, which would make it O(N*log(M)). -func (p *Profile) remapMappingIDs() { - // Some profile handlers will incorrectly set regions for the main - // executable if its section is remapped. Fix them through heuristics. - - if len(p.Mapping) > 0 { - // Remove the initial mapping if named '/anon_hugepage' and has a - // consecutive adjacent mapping. - if m := p.Mapping[0]; strings.HasPrefix(m.File, "/anon_hugepage") { - if len(p.Mapping) > 1 && m.Limit == p.Mapping[1].Start { - p.Mapping = p.Mapping[1:] - } - } - } - - // Subtract the offset from the start of the main mapping if it - // ends up at a recognizable start address. - if len(p.Mapping) > 0 { - const expectedStart = 0x400000 - if m := p.Mapping[0]; m.Start-m.Offset == expectedStart { - m.Start = expectedStart - m.Offset = 0 - } - } - - // Associate each location with an address to the corresponding - // mapping. Create fake mapping if a suitable one isn't found. - var fake *Mapping -nextLocation: - for _, l := range p.Location { - a := l.Address - if l.Mapping != nil || a == 0 { - continue - } - for _, m := range p.Mapping { - if m.Start <= a && a < m.Limit { - l.Mapping = m - continue nextLocation - } - } - // Work around legacy handlers failing to encode the first - // part of mappings split into adjacent ranges. - for _, m := range p.Mapping { - if m.Offset != 0 && m.Start-m.Offset <= a && a < m.Start { - m.Start -= m.Offset - m.Offset = 0 - l.Mapping = m - continue nextLocation - } - } - // If there is still no mapping, create a fake one. - // This is important for the Go legacy handler, which produced - // no mappings. - if fake == nil { - fake = &Mapping{ - ID: 1, - Limit: ^uint64(0), - } - p.Mapping = append(p.Mapping, fake) - } - l.Mapping = fake - } - - // Reset all mapping IDs. - for i, m := range p.Mapping { - m.ID = uint64(i + 1) - } -} - -var cpuInts = []func([]byte) (uint64, []byte){ - get32l, - get32b, - get64l, - get64b, -} - -func get32l(b []byte) (uint64, []byte) { - if len(b) < 4 { - return 0, nil - } - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24, b[4:] -} - -func get32b(b []byte) (uint64, []byte) { - if len(b) < 4 { - return 0, nil - } - return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24, b[4:] -} - -func get64l(b []byte) (uint64, []byte) { - if len(b) < 8 { - return 0, nil - } - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56, b[8:] -} - -func get64b(b []byte) (uint64, []byte) { - if len(b) < 8 { - return 0, nil - } - return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56, b[8:] -} - -// parseCPU parses a profilez legacy profile and returns a newly -// populated Profile. -// -// The general format for profilez samples is a sequence of words in -// binary format. The first words are a header with the following data: -// -// 1st word -- 0 -// 2nd word -- 3 -// 3rd word -- 0 if a c++ application, 1 if a java application. -// 4th word -- Sampling period (in microseconds). -// 5th word -- Padding. -func parseCPU(b []byte) (*Profile, error) { - var parse func([]byte) (uint64, []byte) - var n1, n2, n3, n4, n5 uint64 - for _, parse = range cpuInts { - var tmp []byte - n1, tmp = parse(b) - n2, tmp = parse(tmp) - n3, tmp = parse(tmp) - n4, tmp = parse(tmp) - n5, tmp = parse(tmp) - - if tmp != nil && n1 == 0 && n2 == 3 && n3 == 0 && n4 > 0 && n5 == 0 { - b = tmp - return cpuProfile(b, int64(n4), parse) - } - if tmp != nil && n1 == 0 && n2 == 3 && n3 == 1 && n4 > 0 && n5 == 0 { - b = tmp - return javaCPUProfile(b, int64(n4), parse) - } - } - return nil, errUnrecognized -} - -// cpuProfile returns a new Profile from C++ profilez data. -// b is the profile bytes after the header, period is the profiling -// period, and parse is a function to parse 8-byte chunks from the -// profile in its native endianness. -func cpuProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte)) (*Profile, error) { - p := &Profile{ - Period: period * 1000, - PeriodType: &ValueType{Type: "cpu", Unit: "nanoseconds"}, - SampleType: []*ValueType{ - {Type: "samples", Unit: "count"}, - {Type: "cpu", Unit: "nanoseconds"}, - }, - } - var err error - if b, _, err = parseCPUSamples(b, parse, true, p); err != nil { - return nil, err - } - - // If *most* samples have the same second-to-the-bottom frame, it - // strongly suggests that it is an uninteresting artifact of - // measurement -- a stack frame pushed by the signal handler. The - // bottom frame is always correct as it is picked up from the signal - // structure, not the stack. Check if this is the case and if so, - // remove. - - // Remove up to two frames. - maxiter := 2 - // Allow one different sample for this many samples with the same - // second-to-last frame. - similarSamples := 32 - margin := len(p.Sample) / similarSamples - - for iter := 0; iter < maxiter; iter++ { - addr1 := make(map[uint64]int) - for _, s := range p.Sample { - if len(s.Location) > 1 { - a := s.Location[1].Address - addr1[a] = addr1[a] + 1 - } - } - - for id1, count := range addr1 { - if count >= len(p.Sample)-margin { - // Found uninteresting frame, strip it out from all samples - for _, s := range p.Sample { - if len(s.Location) > 1 && s.Location[1].Address == id1 { - s.Location = append(s.Location[:1], s.Location[2:]...) - } - } - break - } - } - } - - if err := p.ParseMemoryMap(bytes.NewBuffer(b)); err != nil { - return nil, err - } - - cleanupDuplicateLocations(p) - return p, nil -} - -func cleanupDuplicateLocations(p *Profile) { - // The profile handler may duplicate the leaf frame, because it gets - // its address both from stack unwinding and from the signal - // context. Detect this and delete the duplicate, which has been - // adjusted by -1. The leaf address should not be adjusted as it is - // not a call. - for _, s := range p.Sample { - if len(s.Location) > 1 && s.Location[0].Address == s.Location[1].Address+1 { - s.Location = append(s.Location[:1], s.Location[2:]...) - } - } -} - -// parseCPUSamples parses a collection of profilez samples from a -// profile. -// -// profilez samples are a repeated sequence of stack frames of the -// form: -// -// 1st word -- The number of times this stack was encountered. -// 2nd word -- The size of the stack (StackSize). -// 3rd word -- The first address on the stack. -// ... -// StackSize + 2 -- The last address on the stack -// -// The last stack trace is of the form: -// -// 1st word -- 0 -// 2nd word -- 1 -// 3rd word -- 0 -// -// Addresses from stack traces may point to the next instruction after -// each call. Optionally adjust by -1 to land somewhere on the actual -// call (except for the leaf, which is not a call). -func parseCPUSamples(b []byte, parse func(b []byte) (uint64, []byte), adjust bool, p *Profile) ([]byte, map[uint64]*Location, error) { - locs := make(map[uint64]*Location) - for len(b) > 0 { - var count, nstk uint64 - count, b = parse(b) - nstk, b = parse(b) - if b == nil || nstk > uint64(len(b)/4) { - return nil, nil, errUnrecognized - } - var sloc []*Location - addrs := make([]uint64, nstk) - for i := 0; i < int(nstk); i++ { - addrs[i], b = parse(b) - } - - if count == 0 && nstk == 1 && addrs[0] == 0 { - // End of data marker - break - } - for i, addr := range addrs { - if adjust && i > 0 { - addr-- - } - loc := locs[addr] - if loc == nil { - loc = &Location{ - Address: addr, - } - locs[addr] = loc - p.Location = append(p.Location, loc) - } - sloc = append(sloc, loc) - } - p.Sample = append(p.Sample, - &Sample{ - Value: []int64{int64(count), int64(count) * p.Period}, - Location: sloc, - }) - } - // Reached the end without finding the EOD marker. - return b, locs, nil -} - -// parseHeap parses a heapz legacy or a growthz profile and -// returns a newly populated Profile. -func parseHeap(b []byte) (p *Profile, err error) { - s := bufio.NewScanner(bytes.NewBuffer(b)) - if !s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } - return nil, errUnrecognized - } - p = &Profile{} - - sampling := "" - hasAlloc := false - - line := s.Text() - p.PeriodType = &ValueType{Type: "space", Unit: "bytes"} - if header := heapHeaderRE.FindStringSubmatch(line); header != nil { - sampling, p.Period, hasAlloc, err = parseHeapHeader(line) - if err != nil { - return nil, err - } - } else if header = growthHeaderRE.FindStringSubmatch(line); header != nil { - p.Period = 1 - } else if header = fragmentationHeaderRE.FindStringSubmatch(line); header != nil { - p.Period = 1 - } else { - return nil, errUnrecognized - } - - if hasAlloc { - // Put alloc before inuse so that default pprof selection - // will prefer inuse_space. - p.SampleType = []*ValueType{ - {Type: "alloc_objects", Unit: "count"}, - {Type: "alloc_space", Unit: "bytes"}, - {Type: "inuse_objects", Unit: "count"}, - {Type: "inuse_space", Unit: "bytes"}, - } - } else { - p.SampleType = []*ValueType{ - {Type: "objects", Unit: "count"}, - {Type: "space", Unit: "bytes"}, - } - } - - locs := make(map[uint64]*Location) - for s.Scan() { - line := strings.TrimSpace(s.Text()) - - if isSpaceOrComment(line) { - continue - } - - if isMemoryMapSentinel(line) { - break - } - - value, blocksize, addrs, err := parseHeapSample(line, p.Period, sampling, hasAlloc) - if err != nil { - return nil, err - } - - var sloc []*Location - for _, addr := range addrs { - // Addresses from stack traces point to the next instruction after - // each call. Adjust by -1 to land somewhere on the actual call. - addr-- - loc := locs[addr] - if locs[addr] == nil { - loc = &Location{ - Address: addr, - } - p.Location = append(p.Location, loc) - locs[addr] = loc - } - sloc = append(sloc, loc) - } - - p.Sample = append(p.Sample, &Sample{ - Value: value, - Location: sloc, - NumLabel: map[string][]int64{"bytes": {blocksize}}, - }) - } - if err := s.Err(); err != nil { - return nil, err - } - if err := parseAdditionalSections(s, p); err != nil { - return nil, err - } - return p, nil -} - -func parseHeapHeader(line string) (sampling string, period int64, hasAlloc bool, err error) { - header := heapHeaderRE.FindStringSubmatch(line) - if header == nil { - return "", 0, false, errUnrecognized - } - - if len(header[6]) > 0 { - if period, err = strconv.ParseInt(header[6], 10, 64); err != nil { - return "", 0, false, errUnrecognized - } - } - - if (header[3] != header[1] && header[3] != "0") || (header[4] != header[2] && header[4] != "0") { - hasAlloc = true - } - - switch header[5] { - case "heapz_v2", "heap_v2": - return "v2", period, hasAlloc, nil - case "heapprofile": - return "", 1, hasAlloc, nil - case "heap": - return "v2", period / 2, hasAlloc, nil - default: - return "", 0, false, errUnrecognized - } -} - -// parseHeapSample parses a single row from a heap profile into a new Sample. -func parseHeapSample(line string, rate int64, sampling string, includeAlloc bool) (value []int64, blocksize int64, addrs []uint64, err error) { - sampleData := heapSampleRE.FindStringSubmatch(line) - if len(sampleData) != 6 { - return nil, 0, nil, fmt.Errorf("unexpected number of sample values: got %d, want 6", len(sampleData)) - } - - // This is a local-scoped helper function to avoid needing to pass - // around rate, sampling and many return parameters. - addValues := func(countString, sizeString string, label string) error { - count, err := strconv.ParseInt(countString, 10, 64) - if err != nil { - return fmt.Errorf("malformed sample: %s: %v", line, err) - } - size, err := strconv.ParseInt(sizeString, 10, 64) - if err != nil { - return fmt.Errorf("malformed sample: %s: %v", line, err) - } - if count == 0 && size != 0 { - return fmt.Errorf("%s count was 0 but %s bytes was %d", label, label, size) - } - if count != 0 { - blocksize = size / count - if sampling == "v2" { - count, size = scaleHeapSample(count, size, rate) - } - } - value = append(value, count, size) - return nil - } - - if includeAlloc { - if err := addValues(sampleData[3], sampleData[4], "allocation"); err != nil { - return nil, 0, nil, err - } - } - - if err := addValues(sampleData[1], sampleData[2], "inuse"); err != nil { - return nil, 0, nil, err - } - - addrs, err = parseHexAddresses(sampleData[5]) - if err != nil { - return nil, 0, nil, fmt.Errorf("malformed sample: %s: %v", line, err) - } - - return value, blocksize, addrs, nil -} - -// parseHexAddresses extracts hex numbers from a string, attempts to convert -// each to an unsigned 64-bit number and returns the resulting numbers as a -// slice, or an error if the string contains hex numbers which are too large to -// handle (which means a malformed profile). -func parseHexAddresses(s string) ([]uint64, error) { - hexStrings := hexNumberRE.FindAllString(s, -1) - var addrs []uint64 - for _, s := range hexStrings { - if addr, err := strconv.ParseUint(s, 0, 64); err == nil { - addrs = append(addrs, addr) - } else { - return nil, fmt.Errorf("failed to parse as hex 64-bit number: %s", s) - } - } - return addrs, nil -} - -// scaleHeapSample adjusts the data from a heapz Sample to -// account for its probability of appearing in the collected -// data. heapz profiles are a sampling of the memory allocations -// requests in a program. We estimate the unsampled value by dividing -// each collected sample by its probability of appearing in the -// profile. heapz v2 profiles rely on a poisson process to determine -// which samples to collect, based on the desired average collection -// rate R. The probability of a sample of size S to appear in that -// profile is 1-exp(-S/R). -func scaleHeapSample(count, size, rate int64) (int64, int64) { - if count == 0 || size == 0 { - return 0, 0 - } - - if rate <= 1 { - // if rate==1 all samples were collected so no adjustment is needed. - // if rate<1 treat as unknown and skip scaling. - return count, size - } - - avgSize := float64(size) / float64(count) - scale := 1 / (1 - math.Exp(-avgSize/float64(rate))) - - return int64(float64(count) * scale), int64(float64(size) * scale) -} - -// parseContention parses a mutex or contention profile. There are 2 cases: -// "--- contentionz " for legacy C++ profiles (and backwards compatibility) -// "--- mutex:" or "--- contention:" for profiles generated by the Go runtime. -func parseContention(b []byte) (*Profile, error) { - s := bufio.NewScanner(bytes.NewBuffer(b)) - if !s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } - return nil, errUnrecognized - } - - switch l := s.Text(); { - case strings.HasPrefix(l, "--- contentionz "): - case strings.HasPrefix(l, "--- mutex:"): - case strings.HasPrefix(l, "--- contention:"): - default: - return nil, errUnrecognized - } - - p := &Profile{ - PeriodType: &ValueType{Type: "contentions", Unit: "count"}, - Period: 1, - SampleType: []*ValueType{ - {Type: "contentions", Unit: "count"}, - {Type: "delay", Unit: "nanoseconds"}, - }, - } - - var cpuHz int64 - // Parse text of the form "attribute = value" before the samples. - const delimiter = "=" - for s.Scan() { - line := s.Text() - if line = strings.TrimSpace(line); isSpaceOrComment(line) { - continue - } - if strings.HasPrefix(line, "---") { - break - } - attr := strings.SplitN(line, delimiter, 2) - if len(attr) != 2 { - break - } - key, val := strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1]) - var err error - switch key { - case "cycles/second": - if cpuHz, err = strconv.ParseInt(val, 0, 64); err != nil { - return nil, errUnrecognized - } - case "sampling period": - if p.Period, err = strconv.ParseInt(val, 0, 64); err != nil { - return nil, errUnrecognized - } - case "ms since reset": - ms, err := strconv.ParseInt(val, 0, 64) - if err != nil { - return nil, errUnrecognized - } - p.DurationNanos = ms * 1000 * 1000 - case "format": - // CPP contentionz profiles don't have format. - return nil, errUnrecognized - case "resolution": - // CPP contentionz profiles don't have resolution. - return nil, errUnrecognized - case "discarded samples": - default: - return nil, errUnrecognized - } - } - if err := s.Err(); err != nil { - return nil, err - } - - locs := make(map[uint64]*Location) - for { - line := strings.TrimSpace(s.Text()) - if strings.HasPrefix(line, "---") { - break - } - if !isSpaceOrComment(line) { - value, addrs, err := parseContentionSample(line, p.Period, cpuHz) - if err != nil { - return nil, err - } - var sloc []*Location - for _, addr := range addrs { - // Addresses from stack traces point to the next instruction after - // each call. Adjust by -1 to land somewhere on the actual call. - addr-- - loc := locs[addr] - if locs[addr] == nil { - loc = &Location{ - Address: addr, - } - p.Location = append(p.Location, loc) - locs[addr] = loc - } - sloc = append(sloc, loc) - } - p.Sample = append(p.Sample, &Sample{ - Value: value, - Location: sloc, - }) - } - if !s.Scan() { - break - } - } - if err := s.Err(); err != nil { - return nil, err - } - - if err := parseAdditionalSections(s, p); err != nil { - return nil, err - } - - return p, nil -} - -// parseContentionSample parses a single row from a contention profile -// into a new Sample. -func parseContentionSample(line string, period, cpuHz int64) (value []int64, addrs []uint64, err error) { - sampleData := contentionSampleRE.FindStringSubmatch(line) - if sampleData == nil { - return nil, nil, errUnrecognized - } - - v1, err := strconv.ParseInt(sampleData[1], 10, 64) - if err != nil { - return nil, nil, fmt.Errorf("malformed sample: %s: %v", line, err) - } - v2, err := strconv.ParseInt(sampleData[2], 10, 64) - if err != nil { - return nil, nil, fmt.Errorf("malformed sample: %s: %v", line, err) - } - - // Unsample values if period and cpuHz are available. - // - Delays are scaled to cycles and then to nanoseconds. - // - Contentions are scaled to cycles. - if period > 0 { - if cpuHz > 0 { - cpuGHz := float64(cpuHz) / 1e9 - v1 = int64(float64(v1) * float64(period) / cpuGHz) - } - v2 = v2 * period - } - - value = []int64{v2, v1} - addrs, err = parseHexAddresses(sampleData[3]) - if err != nil { - return nil, nil, fmt.Errorf("malformed sample: %s: %v", line, err) - } - - return value, addrs, nil -} - -// parseThread parses a Threadz profile and returns a new Profile. -func parseThread(b []byte) (*Profile, error) { - s := bufio.NewScanner(bytes.NewBuffer(b)) - // Skip past comments and empty lines seeking a real header. - for s.Scan() && isSpaceOrComment(s.Text()) { - } - - line := s.Text() - if m := threadzStartRE.FindStringSubmatch(line); m != nil { - // Advance over initial comments until first stack trace. - for s.Scan() { - if line = s.Text(); isMemoryMapSentinel(line) || strings.HasPrefix(line, "-") { - break - } - } - } else if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 { - return nil, errUnrecognized - } - - p := &Profile{ - SampleType: []*ValueType{{Type: "thread", Unit: "count"}}, - PeriodType: &ValueType{Type: "thread", Unit: "count"}, - Period: 1, - } - - locs := make(map[uint64]*Location) - // Recognize each thread and populate profile samples. - for !isMemoryMapSentinel(line) { - if strings.HasPrefix(line, "---- no stack trace for") { - break - } - if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 { - return nil, errUnrecognized - } - - var addrs []uint64 - var err error - line, addrs, err = parseThreadSample(s) - if err != nil { - return nil, err - } - if len(addrs) == 0 { - // We got a --same as previous threads--. Bump counters. - if len(p.Sample) > 0 { - s := p.Sample[len(p.Sample)-1] - s.Value[0]++ - } - continue - } - - var sloc []*Location - for i, addr := range addrs { - // Addresses from stack traces point to the next instruction after - // each call. Adjust by -1 to land somewhere on the actual call - // (except for the leaf, which is not a call). - if i > 0 { - addr-- - } - loc := locs[addr] - if locs[addr] == nil { - loc = &Location{ - Address: addr, - } - p.Location = append(p.Location, loc) - locs[addr] = loc - } - sloc = append(sloc, loc) - } - - p.Sample = append(p.Sample, &Sample{ - Value: []int64{1}, - Location: sloc, - }) - } - - if err := parseAdditionalSections(s, p); err != nil { - return nil, err - } - - cleanupDuplicateLocations(p) - return p, nil -} - -// parseThreadSample parses a symbolized or unsymbolized stack trace. -// Returns the first line after the traceback, the sample (or nil if -// it hits a 'same-as-previous' marker) and an error. -func parseThreadSample(s *bufio.Scanner) (nextl string, addrs []uint64, err error) { - var line string - sameAsPrevious := false - for s.Scan() { - line = strings.TrimSpace(s.Text()) - if line == "" { - continue - } - - if strings.HasPrefix(line, "---") { - break - } - if strings.Contains(line, "same as previous thread") { - sameAsPrevious = true - continue - } - - curAddrs, err := parseHexAddresses(line) - if err != nil { - return "", nil, fmt.Errorf("malformed sample: %s: %v", line, err) - } - addrs = append(addrs, curAddrs...) - } - if err := s.Err(); err != nil { - return "", nil, err - } - if sameAsPrevious { - return line, nil, nil - } - return line, addrs, nil -} - -// parseAdditionalSections parses any additional sections in the -// profile, ignoring any unrecognized sections. -func parseAdditionalSections(s *bufio.Scanner, p *Profile) error { - for !isMemoryMapSentinel(s.Text()) && s.Scan() { - } - if err := s.Err(); err != nil { - return err - } - return p.ParseMemoryMapFromScanner(s) -} - -// ParseProcMaps parses a memory map in the format of /proc/self/maps. -// ParseMemoryMap should be called after setting on a profile to -// associate locations to the corresponding mapping based on their -// address. -func ParseProcMaps(rd io.Reader) ([]*Mapping, error) { - s := bufio.NewScanner(rd) - return parseProcMapsFromScanner(s) -} - -func parseProcMapsFromScanner(s *bufio.Scanner) ([]*Mapping, error) { - var mapping []*Mapping - - var attrs []string - const delimiter = "=" - r := strings.NewReplacer() - for s.Scan() { - line := r.Replace(removeLoggingInfo(s.Text())) - m, err := parseMappingEntry(line) - if err != nil { - if err == errUnrecognized { - // Recognize assignments of the form: attr=value, and replace - // $attr with value on subsequent mappings. - if attr := strings.SplitN(line, delimiter, 2); len(attr) == 2 { - attrs = append(attrs, "$"+strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1])) - r = strings.NewReplacer(attrs...) - } - // Ignore any unrecognized entries - continue - } - return nil, err - } - if m == nil { - continue - } - mapping = append(mapping, m) - } - if err := s.Err(); err != nil { - return nil, err - } - return mapping, nil -} - -// removeLoggingInfo detects and removes log prefix entries generated -// by the glog package. If no logging prefix is detected, the string -// is returned unmodified. -func removeLoggingInfo(line string) string { - if match := logInfoRE.FindStringIndex(line); match != nil { - return line[match[1]:] - } - return line -} - -// ParseMemoryMap parses a memory map in the format of -// /proc/self/maps, and overrides the mappings in the current profile. -// It renumbers the samples and locations in the profile correspondingly. -func (p *Profile) ParseMemoryMap(rd io.Reader) error { - return p.ParseMemoryMapFromScanner(bufio.NewScanner(rd)) -} - -// ParseMemoryMapFromScanner parses a memory map in the format of -// /proc/self/maps or a variety of legacy format, and overrides the -// mappings in the current profile. It renumbers the samples and -// locations in the profile correspondingly. -func (p *Profile) ParseMemoryMapFromScanner(s *bufio.Scanner) error { - mapping, err := parseProcMapsFromScanner(s) - if err != nil { - return err - } - p.Mapping = append(p.Mapping, mapping...) - p.massageMappings() - p.remapLocationIDs() - p.remapFunctionIDs() - p.remapMappingIDs() - return nil -} - -func parseMappingEntry(l string) (*Mapping, error) { - var start, end, perm, file, offset, buildID string - if me := procMapsRE.FindStringSubmatch(l); len(me) == 6 { - start, end, perm, offset, file = me[1], me[2], me[3], me[4], me[5] - } else if me := briefMapsRE.FindStringSubmatch(l); len(me) == 7 { - start, end, perm, file, offset, buildID = me[1], me[2], me[3], me[4], me[5], me[6] - } else { - return nil, errUnrecognized - } - - var err error - mapping := &Mapping{ - File: file, - BuildID: buildID, - } - if perm != "" && !strings.Contains(perm, "x") { - // Skip non-executable entries. - return nil, nil - } - if mapping.Start, err = strconv.ParseUint(start, 16, 64); err != nil { - return nil, errUnrecognized - } - if mapping.Limit, err = strconv.ParseUint(end, 16, 64); err != nil { - return nil, errUnrecognized - } - if offset != "" { - if mapping.Offset, err = strconv.ParseUint(offset, 16, 64); err != nil { - return nil, errUnrecognized - } - } - return mapping, nil -} - -var memoryMapSentinels = []string{ - "--- Memory map: ---", - "MAPPED_LIBRARIES:", -} - -// isMemoryMapSentinel returns true if the string contains one of the -// known sentinels for memory map information. -func isMemoryMapSentinel(line string) bool { - for _, s := range memoryMapSentinels { - if strings.Contains(line, s) { - return true - } - } - return false -} - -func (p *Profile) addLegacyFrameInfo() { - switch { - case isProfileType(p, heapzSampleTypes): - p.DropFrames, p.KeepFrames = allocRxStr, allocSkipRxStr - case isProfileType(p, contentionzSampleTypes): - p.DropFrames, p.KeepFrames = lockRxStr, "" - default: - p.DropFrames, p.KeepFrames = cpuProfilerRxStr, "" - } -} - -var heapzSampleTypes = [][]string{ - {"allocations", "size"}, // early Go pprof profiles - {"objects", "space"}, - {"inuse_objects", "inuse_space"}, - {"alloc_objects", "alloc_space"}, - {"alloc_objects", "alloc_space", "inuse_objects", "inuse_space"}, // Go pprof legacy profiles -} -var contentionzSampleTypes = [][]string{ - {"contentions", "delay"}, -} - -func isProfileType(p *Profile, types [][]string) bool { - st := p.SampleType -nextType: - for _, t := range types { - if len(st) != len(t) { - continue - } - - for i := range st { - if st[i].Type != t[i] { - continue nextType - } - } - return true - } - return false -} - -var allocRxStr = strings.Join([]string{ - // POSIX entry points. - `calloc`, - `cfree`, - `malloc`, - `free`, - `memalign`, - `do_memalign`, - `(__)?posix_memalign`, - `pvalloc`, - `valloc`, - `realloc`, - - // TC malloc. - `tcmalloc::.*`, - `tc_calloc`, - `tc_cfree`, - `tc_malloc`, - `tc_free`, - `tc_memalign`, - `tc_posix_memalign`, - `tc_pvalloc`, - `tc_valloc`, - `tc_realloc`, - `tc_new`, - `tc_delete`, - `tc_newarray`, - `tc_deletearray`, - `tc_new_nothrow`, - `tc_newarray_nothrow`, - - // Memory-allocation routines on OS X. - `malloc_zone_malloc`, - `malloc_zone_calloc`, - `malloc_zone_valloc`, - `malloc_zone_realloc`, - `malloc_zone_memalign`, - `malloc_zone_free`, - - // Go runtime - `runtime\..*`, - - // Other misc. memory allocation routines - `BaseArena::.*`, - `(::)?do_malloc_no_errno`, - `(::)?do_malloc_pages`, - `(::)?do_malloc`, - `DoSampledAllocation`, - `MallocedMemBlock::MallocedMemBlock`, - `_M_allocate`, - `__builtin_(vec_)?delete`, - `__builtin_(vec_)?new`, - `__gnu_cxx::new_allocator::allocate`, - `__libc_malloc`, - `__malloc_alloc_template::allocate`, - `allocate`, - `cpp_alloc`, - `operator new(\[\])?`, - `simple_alloc::allocate`, -}, `|`) - -var allocSkipRxStr = strings.Join([]string{ - // Preserve Go runtime frames that appear in the middle/bottom of - // the stack. - `runtime\.panic`, - `runtime\.reflectcall`, - `runtime\.call[0-9]*`, -}, `|`) - -var cpuProfilerRxStr = strings.Join([]string{ - `ProfileData::Add`, - `ProfileData::prof_handler`, - `CpuProfiler::prof_handler`, - `__pthread_sighandler`, - `__restore`, -}, `|`) - -var lockRxStr = strings.Join([]string{ - `RecordLockProfileData`, - `(base::)?RecordLockProfileData.*`, - `(base::)?SubmitMutexProfileData.*`, - `(base::)?SubmitSpinLockProfileData.*`, - `(base::Mutex::)?AwaitCommon.*`, - `(base::Mutex::)?Unlock.*`, - `(base::Mutex::)?UnlockSlow.*`, - `(base::Mutex::)?ReaderUnlock.*`, - `(base::MutexLock::)?~MutexLock.*`, - `(Mutex::)?AwaitCommon.*`, - `(Mutex::)?Unlock.*`, - `(Mutex::)?UnlockSlow.*`, - `(Mutex::)?ReaderUnlock.*`, - `(MutexLock::)?~MutexLock.*`, - `(SpinLock::)?Unlock.*`, - `(SpinLock::)?SlowUnlock.*`, - `(SpinLockHolder::)?~SpinLockHolder.*`, -}, `|`) diff --git a/vendor/github.com/google/pprof/profile/merge.go b/vendor/github.com/google/pprof/profile/merge.go deleted file mode 100644 index ba4d7464..00000000 --- a/vendor/github.com/google/pprof/profile/merge.go +++ /dev/null @@ -1,674 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// 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 profile - -import ( - "encoding/binary" - "fmt" - "sort" - "strconv" - "strings" -) - -// Compact performs garbage collection on a profile to remove any -// unreferenced fields. This is useful to reduce the size of a profile -// after samples or locations have been removed. -func (p *Profile) Compact() *Profile { - p, _ = Merge([]*Profile{p}) - return p -} - -// Merge merges all the profiles in profs into a single Profile. -// Returns a new profile independent of the input profiles. The merged -// profile is compacted to eliminate unused samples, locations, -// functions and mappings. Profiles must have identical profile sample -// and period types or the merge will fail. profile.Period of the -// resulting profile will be the maximum of all profiles, and -// profile.TimeNanos will be the earliest nonzero one. Merges are -// associative with the caveat of the first profile having some -// specialization in how headers are combined. There may be other -// subtleties now or in the future regarding associativity. -func Merge(srcs []*Profile) (*Profile, error) { - if len(srcs) == 0 { - return nil, fmt.Errorf("no profiles to merge") - } - p, err := combineHeaders(srcs) - if err != nil { - return nil, err - } - - pm := &profileMerger{ - p: p, - samples: make(map[sampleKey]*Sample, len(srcs[0].Sample)), - locations: make(map[locationKey]*Location, len(srcs[0].Location)), - functions: make(map[functionKey]*Function, len(srcs[0].Function)), - mappings: make(map[mappingKey]*Mapping, len(srcs[0].Mapping)), - } - - for _, src := range srcs { - // Clear the profile-specific hash tables - pm.locationsByID = makeLocationIDMap(len(src.Location)) - pm.functionsByID = make(map[uint64]*Function, len(src.Function)) - pm.mappingsByID = make(map[uint64]mapInfo, len(src.Mapping)) - - if len(pm.mappings) == 0 && len(src.Mapping) > 0 { - // The Mapping list has the property that the first mapping - // represents the main binary. Take the first Mapping we see, - // otherwise the operations below will add mappings in an - // arbitrary order. - pm.mapMapping(src.Mapping[0]) - } - - for _, s := range src.Sample { - if !isZeroSample(s) { - pm.mapSample(s) - } - } - } - - for _, s := range p.Sample { - if isZeroSample(s) { - // If there are any zero samples, re-merge the profile to GC - // them. - return Merge([]*Profile{p}) - } - } - - return p, nil -} - -// Normalize normalizes the source profile by multiplying each value in profile by the -// ratio of the sum of the base profile's values of that sample type to the sum of the -// source profile's value of that sample type. -func (p *Profile) Normalize(pb *Profile) error { - - if err := p.compatible(pb); err != nil { - return err - } - - baseVals := make([]int64, len(p.SampleType)) - for _, s := range pb.Sample { - for i, v := range s.Value { - baseVals[i] += v - } - } - - srcVals := make([]int64, len(p.SampleType)) - for _, s := range p.Sample { - for i, v := range s.Value { - srcVals[i] += v - } - } - - normScale := make([]float64, len(baseVals)) - for i := range baseVals { - if srcVals[i] == 0 { - normScale[i] = 0.0 - } else { - normScale[i] = float64(baseVals[i]) / float64(srcVals[i]) - } - } - p.ScaleN(normScale) - return nil -} - -func isZeroSample(s *Sample) bool { - for _, v := range s.Value { - if v != 0 { - return false - } - } - return true -} - -type profileMerger struct { - p *Profile - - // Memoization tables within a profile. - locationsByID locationIDMap - functionsByID map[uint64]*Function - mappingsByID map[uint64]mapInfo - - // Memoization tables for profile entities. - samples map[sampleKey]*Sample - locations map[locationKey]*Location - functions map[functionKey]*Function - mappings map[mappingKey]*Mapping -} - -type mapInfo struct { - m *Mapping - offset int64 -} - -func (pm *profileMerger) mapSample(src *Sample) *Sample { - // Check memoization table - k := pm.sampleKey(src) - if ss, ok := pm.samples[k]; ok { - for i, v := range src.Value { - ss.Value[i] += v - } - return ss - } - - // Make new sample. - s := &Sample{ - Location: make([]*Location, len(src.Location)), - Value: make([]int64, len(src.Value)), - Label: make(map[string][]string, len(src.Label)), - NumLabel: make(map[string][]int64, len(src.NumLabel)), - NumUnit: make(map[string][]string, len(src.NumLabel)), - } - for i, l := range src.Location { - s.Location[i] = pm.mapLocation(l) - } - for k, v := range src.Label { - vv := make([]string, len(v)) - copy(vv, v) - s.Label[k] = vv - } - for k, v := range src.NumLabel { - u := src.NumUnit[k] - vv := make([]int64, len(v)) - uu := make([]string, len(u)) - copy(vv, v) - copy(uu, u) - s.NumLabel[k] = vv - s.NumUnit[k] = uu - } - copy(s.Value, src.Value) - pm.samples[k] = s - pm.p.Sample = append(pm.p.Sample, s) - return s -} - -func (pm *profileMerger) sampleKey(sample *Sample) sampleKey { - // Accumulate contents into a string. - var buf strings.Builder - buf.Grow(64) // Heuristic to avoid extra allocs - - // encode a number - putNumber := func(v uint64) { - var num [binary.MaxVarintLen64]byte - n := binary.PutUvarint(num[:], v) - buf.Write(num[:n]) - } - - // encode a string prefixed with its length. - putDelimitedString := func(s string) { - putNumber(uint64(len(s))) - buf.WriteString(s) - } - - for _, l := range sample.Location { - // Get the location in the merged profile, which may have a different ID. - if loc := pm.mapLocation(l); loc != nil { - putNumber(loc.ID) - } - } - putNumber(0) // Delimiter - - for _, l := range sortedKeys1(sample.Label) { - putDelimitedString(l) - values := sample.Label[l] - putNumber(uint64(len(values))) - for _, v := range values { - putDelimitedString(v) - } - } - - for _, l := range sortedKeys2(sample.NumLabel) { - putDelimitedString(l) - values := sample.NumLabel[l] - putNumber(uint64(len(values))) - for _, v := range values { - putNumber(uint64(v)) - } - units := sample.NumUnit[l] - putNumber(uint64(len(units))) - for _, v := range units { - putDelimitedString(v) - } - } - - return sampleKey(buf.String()) -} - -type sampleKey string - -// sortedKeys1 returns the sorted keys found in a string->[]string map. -// -// Note: this is currently non-generic since github pprof runs golint, -// which does not support generics. When that issue is fixed, it can -// be merged with sortedKeys2 and made into a generic function. -func sortedKeys1(m map[string][]string) []string { - if len(m) == 0 { - return nil - } - keys := make([]string, 0, len(m)) - for k := range m { - keys = append(keys, k) - } - sort.Strings(keys) - return keys -} - -// sortedKeys2 returns the sorted keys found in a string->[]int64 map. -// -// Note: this is currently non-generic since github pprof runs golint, -// which does not support generics. When that issue is fixed, it can -// be merged with sortedKeys1 and made into a generic function. -func sortedKeys2(m map[string][]int64) []string { - if len(m) == 0 { - return nil - } - keys := make([]string, 0, len(m)) - for k := range m { - keys = append(keys, k) - } - sort.Strings(keys) - return keys -} - -func (pm *profileMerger) mapLocation(src *Location) *Location { - if src == nil { - return nil - } - - if l := pm.locationsByID.get(src.ID); l != nil { - return l - } - - mi := pm.mapMapping(src.Mapping) - l := &Location{ - ID: uint64(len(pm.p.Location) + 1), - Mapping: mi.m, - Address: uint64(int64(src.Address) + mi.offset), - Line: make([]Line, len(src.Line)), - IsFolded: src.IsFolded, - } - for i, ln := range src.Line { - l.Line[i] = pm.mapLine(ln) - } - // Check memoization table. Must be done on the remapped location to - // account for the remapped mapping ID. - k := l.key() - if ll, ok := pm.locations[k]; ok { - pm.locationsByID.set(src.ID, ll) - return ll - } - pm.locationsByID.set(src.ID, l) - pm.locations[k] = l - pm.p.Location = append(pm.p.Location, l) - return l -} - -// key generates locationKey to be used as a key for maps. -func (l *Location) key() locationKey { - key := locationKey{ - addr: l.Address, - isFolded: l.IsFolded, - } - if l.Mapping != nil { - // Normalizes address to handle address space randomization. - key.addr -= l.Mapping.Start - key.mappingID = l.Mapping.ID - } - lines := make([]string, len(l.Line)*3) - for i, line := range l.Line { - if line.Function != nil { - lines[i*2] = strconv.FormatUint(line.Function.ID, 16) - } - lines[i*2+1] = strconv.FormatInt(line.Line, 16) - lines[i*2+2] = strconv.FormatInt(line.Column, 16) - } - key.lines = strings.Join(lines, "|") - return key -} - -type locationKey struct { - addr, mappingID uint64 - lines string - isFolded bool -} - -func (pm *profileMerger) mapMapping(src *Mapping) mapInfo { - if src == nil { - return mapInfo{} - } - - if mi, ok := pm.mappingsByID[src.ID]; ok { - return mi - } - - // Check memoization tables. - mk := src.key() - if m, ok := pm.mappings[mk]; ok { - mi := mapInfo{m, int64(m.Start) - int64(src.Start)} - pm.mappingsByID[src.ID] = mi - return mi - } - m := &Mapping{ - ID: uint64(len(pm.p.Mapping) + 1), - Start: src.Start, - Limit: src.Limit, - Offset: src.Offset, - File: src.File, - KernelRelocationSymbol: src.KernelRelocationSymbol, - BuildID: src.BuildID, - HasFunctions: src.HasFunctions, - HasFilenames: src.HasFilenames, - HasLineNumbers: src.HasLineNumbers, - HasInlineFrames: src.HasInlineFrames, - } - pm.p.Mapping = append(pm.p.Mapping, m) - - // Update memoization tables. - pm.mappings[mk] = m - mi := mapInfo{m, 0} - pm.mappingsByID[src.ID] = mi - return mi -} - -// key generates encoded strings of Mapping to be used as a key for -// maps. -func (m *Mapping) key() mappingKey { - // Normalize addresses to handle address space randomization. - // Round up to next 4K boundary to avoid minor discrepancies. - const mapsizeRounding = 0x1000 - - size := m.Limit - m.Start - size = size + mapsizeRounding - 1 - size = size - (size % mapsizeRounding) - key := mappingKey{ - size: size, - offset: m.Offset, - } - - switch { - case m.BuildID != "": - key.buildIDOrFile = m.BuildID - case m.File != "": - key.buildIDOrFile = m.File - default: - // A mapping containing neither build ID nor file name is a fake mapping. A - // key with empty buildIDOrFile is used for fake mappings so that they are - // treated as the same mapping during merging. - } - return key -} - -type mappingKey struct { - size, offset uint64 - buildIDOrFile string -} - -func (pm *profileMerger) mapLine(src Line) Line { - ln := Line{ - Function: pm.mapFunction(src.Function), - Line: src.Line, - Column: src.Column, - } - return ln -} - -func (pm *profileMerger) mapFunction(src *Function) *Function { - if src == nil { - return nil - } - if f, ok := pm.functionsByID[src.ID]; ok { - return f - } - k := src.key() - if f, ok := pm.functions[k]; ok { - pm.functionsByID[src.ID] = f - return f - } - f := &Function{ - ID: uint64(len(pm.p.Function) + 1), - Name: src.Name, - SystemName: src.SystemName, - Filename: src.Filename, - StartLine: src.StartLine, - } - pm.functions[k] = f - pm.functionsByID[src.ID] = f - pm.p.Function = append(pm.p.Function, f) - return f -} - -// key generates a struct to be used as a key for maps. -func (f *Function) key() functionKey { - return functionKey{ - f.StartLine, - f.Name, - f.SystemName, - f.Filename, - } -} - -type functionKey struct { - startLine int64 - name, systemName, fileName string -} - -// combineHeaders checks that all profiles can be merged and returns -// their combined profile. -func combineHeaders(srcs []*Profile) (*Profile, error) { - for _, s := range srcs[1:] { - if err := srcs[0].compatible(s); err != nil { - return nil, err - } - } - - var timeNanos, durationNanos, period int64 - var comments []string - seenComments := map[string]bool{} - var docURL string - var defaultSampleType string - for _, s := range srcs { - if timeNanos == 0 || s.TimeNanos < timeNanos { - timeNanos = s.TimeNanos - } - durationNanos += s.DurationNanos - if period == 0 || period < s.Period { - period = s.Period - } - for _, c := range s.Comments { - if seen := seenComments[c]; !seen { - comments = append(comments, c) - seenComments[c] = true - } - } - if defaultSampleType == "" { - defaultSampleType = s.DefaultSampleType - } - if docURL == "" { - docURL = s.DocURL - } - } - - p := &Profile{ - SampleType: make([]*ValueType, len(srcs[0].SampleType)), - - DropFrames: srcs[0].DropFrames, - KeepFrames: srcs[0].KeepFrames, - - TimeNanos: timeNanos, - DurationNanos: durationNanos, - PeriodType: srcs[0].PeriodType, - Period: period, - - Comments: comments, - DefaultSampleType: defaultSampleType, - DocURL: docURL, - } - copy(p.SampleType, srcs[0].SampleType) - return p, nil -} - -// compatible determines if two profiles can be compared/merged. -// returns nil if the profiles are compatible; otherwise an error with -// details on the incompatibility. -func (p *Profile) compatible(pb *Profile) error { - if !equalValueType(p.PeriodType, pb.PeriodType) { - return fmt.Errorf("incompatible period types %v and %v", p.PeriodType, pb.PeriodType) - } - - if len(p.SampleType) != len(pb.SampleType) { - return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType) - } - - for i := range p.SampleType { - if !equalValueType(p.SampleType[i], pb.SampleType[i]) { - return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType) - } - } - return nil -} - -// equalValueType returns true if the two value types are semantically -// equal. It ignores the internal fields used during encode/decode. -func equalValueType(st1, st2 *ValueType) bool { - return st1.Type == st2.Type && st1.Unit == st2.Unit -} - -// locationIDMap is like a map[uint64]*Location, but provides efficiency for -// ids that are densely numbered, which is often the case. -type locationIDMap struct { - dense []*Location // indexed by id for id < len(dense) - sparse map[uint64]*Location // indexed by id for id >= len(dense) -} - -func makeLocationIDMap(n int) locationIDMap { - return locationIDMap{ - dense: make([]*Location, n), - sparse: map[uint64]*Location{}, - } -} - -func (lm locationIDMap) get(id uint64) *Location { - if id < uint64(len(lm.dense)) { - return lm.dense[int(id)] - } - return lm.sparse[id] -} - -func (lm locationIDMap) set(id uint64, loc *Location) { - if id < uint64(len(lm.dense)) { - lm.dense[id] = loc - return - } - lm.sparse[id] = loc -} - -// CompatibilizeSampleTypes makes profiles compatible to be compared/merged. It -// keeps sample types that appear in all profiles only and drops/reorders the -// sample types as necessary. -// -// In the case of sample types order is not the same for given profiles the -// order is derived from the first profile. -// -// Profiles are modified in-place. -// -// It returns an error if the sample type's intersection is empty. -func CompatibilizeSampleTypes(ps []*Profile) error { - sTypes := commonSampleTypes(ps) - if len(sTypes) == 0 { - return fmt.Errorf("profiles have empty common sample type list") - } - for _, p := range ps { - if err := compatibilizeSampleTypes(p, sTypes); err != nil { - return err - } - } - return nil -} - -// commonSampleTypes returns sample types that appear in all profiles in the -// order how they ordered in the first profile. -func commonSampleTypes(ps []*Profile) []string { - if len(ps) == 0 { - return nil - } - sTypes := map[string]int{} - for _, p := range ps { - for _, st := range p.SampleType { - sTypes[st.Type]++ - } - } - var res []string - for _, st := range ps[0].SampleType { - if sTypes[st.Type] == len(ps) { - res = append(res, st.Type) - } - } - return res -} - -// compatibilizeSampleTypes drops sample types that are not present in sTypes -// list and reorder them if needed. -// -// It sets DefaultSampleType to sType[0] if it is not in sType list. -// -// It assumes that all sample types from the sTypes list are present in the -// given profile otherwise it returns an error. -func compatibilizeSampleTypes(p *Profile, sTypes []string) error { - if len(sTypes) == 0 { - return fmt.Errorf("sample type list is empty") - } - defaultSampleType := sTypes[0] - reMap, needToModify := make([]int, len(sTypes)), false - for i, st := range sTypes { - if st == p.DefaultSampleType { - defaultSampleType = p.DefaultSampleType - } - idx := searchValueType(p.SampleType, st) - if idx < 0 { - return fmt.Errorf("%q sample type is not found in profile", st) - } - reMap[i] = idx - if idx != i { - needToModify = true - } - } - if !needToModify && len(sTypes) == len(p.SampleType) { - return nil - } - p.DefaultSampleType = defaultSampleType - oldSampleTypes := p.SampleType - p.SampleType = make([]*ValueType, len(sTypes)) - for i, idx := range reMap { - p.SampleType[i] = oldSampleTypes[idx] - } - values := make([]int64, len(sTypes)) - for _, s := range p.Sample { - for i, idx := range reMap { - values[i] = s.Value[idx] - } - s.Value = s.Value[:len(values)] - copy(s.Value, values) - } - return nil -} - -func searchValueType(vts []*ValueType, s string) int { - for i, vt := range vts { - if vt.Type == s { - return i - } - } - return -1 -} diff --git a/vendor/github.com/google/pprof/profile/profile.go b/vendor/github.com/google/pprof/profile/profile.go deleted file mode 100644 index f47a2439..00000000 --- a/vendor/github.com/google/pprof/profile/profile.go +++ /dev/null @@ -1,869 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// 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 profile provides a representation of profile.proto and -// methods to encode/decode profiles in this format. -package profile - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "math" - "path/filepath" - "regexp" - "sort" - "strings" - "sync" - "time" -) - -// Profile is an in-memory representation of profile.proto. -type Profile struct { - SampleType []*ValueType - DefaultSampleType string - Sample []*Sample - Mapping []*Mapping - Location []*Location - Function []*Function - Comments []string - DocURL string - - DropFrames string - KeepFrames string - - TimeNanos int64 - DurationNanos int64 - PeriodType *ValueType - Period int64 - - // The following fields are modified during encoding and copying, - // so are protected by a Mutex. - encodeMu sync.Mutex - - commentX []int64 - docURLX int64 - dropFramesX int64 - keepFramesX int64 - stringTable []string - defaultSampleTypeX int64 -} - -// ValueType corresponds to Profile.ValueType -type ValueType struct { - Type string // cpu, wall, inuse_space, etc - Unit string // seconds, nanoseconds, bytes, etc - - typeX int64 - unitX int64 -} - -// Sample corresponds to Profile.Sample -type Sample struct { - Location []*Location - Value []int64 - // Label is a per-label-key map to values for string labels. - // - // In general, having multiple values for the given label key is strongly - // discouraged - see docs for the sample label field in profile.proto. The - // main reason this unlikely state is tracked here is to make the - // decoding->encoding roundtrip not lossy. But we expect that the value - // slices present in this map are always of length 1. - Label map[string][]string - // NumLabel is a per-label-key map to values for numeric labels. See a note - // above on handling multiple values for a label. - NumLabel map[string][]int64 - // NumUnit is a per-label-key map to the unit names of corresponding numeric - // label values. The unit info may be missing even if the label is in - // NumLabel, see the docs in profile.proto for details. When the value is - // slice is present and not nil, its length must be equal to the length of - // the corresponding value slice in NumLabel. - NumUnit map[string][]string - - locationIDX []uint64 - labelX []label -} - -// label corresponds to Profile.Label -type label struct { - keyX int64 - // Exactly one of the two following values must be set - strX int64 - numX int64 // Integer value for this label - // can be set if numX has value - unitX int64 -} - -// Mapping corresponds to Profile.Mapping -type Mapping struct { - ID uint64 - Start uint64 - Limit uint64 - Offset uint64 - File string - BuildID string - HasFunctions bool - HasFilenames bool - HasLineNumbers bool - HasInlineFrames bool - - fileX int64 - buildIDX int64 - - // Name of the kernel relocation symbol ("_text" or "_stext"), extracted from File. - // For linux kernel mappings generated by some tools, correct symbolization depends - // on knowing which of the two possible relocation symbols was used for `Start`. - // This is given to us as a suffix in `File` (e.g. "[kernel.kallsyms]_stext"). - // - // Note, this public field is not persisted in the proto. For the purposes of - // copying / merging / hashing profiles, it is considered subsumed by `File`. - KernelRelocationSymbol string -} - -// Location corresponds to Profile.Location -type Location struct { - ID uint64 - Mapping *Mapping - Address uint64 - Line []Line - IsFolded bool - - mappingIDX uint64 -} - -// Line corresponds to Profile.Line -type Line struct { - Function *Function - Line int64 - Column int64 - - functionIDX uint64 -} - -// Function corresponds to Profile.Function -type Function struct { - ID uint64 - Name string - SystemName string - Filename string - StartLine int64 - - nameX int64 - systemNameX int64 - filenameX int64 -} - -// Parse parses a profile and checks for its validity. The input -// may be a gzip-compressed encoded protobuf or one of many legacy -// profile formats which may be unsupported in the future. -func Parse(r io.Reader) (*Profile, error) { - data, err := io.ReadAll(r) - if err != nil { - return nil, err - } - return ParseData(data) -} - -// ParseData parses a profile from a buffer and checks for its -// validity. -func ParseData(data []byte) (*Profile, error) { - var p *Profile - var err error - if len(data) >= 2 && data[0] == 0x1f && data[1] == 0x8b { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err == nil { - data, err = io.ReadAll(gz) - } - if err != nil { - return nil, fmt.Errorf("decompressing profile: %v", err) - } - } - if p, err = ParseUncompressed(data); err != nil && err != errNoData && err != errConcatProfile { - p, err = parseLegacy(data) - } - - if err != nil { - return nil, fmt.Errorf("parsing profile: %v", err) - } - - if err := p.CheckValid(); err != nil { - return nil, fmt.Errorf("malformed profile: %v", err) - } - return p, nil -} - -var errUnrecognized = fmt.Errorf("unrecognized profile format") -var errMalformed = fmt.Errorf("malformed profile format") -var errNoData = fmt.Errorf("empty input file") -var errConcatProfile = fmt.Errorf("concatenated profiles detected") - -func parseLegacy(data []byte) (*Profile, error) { - parsers := []func([]byte) (*Profile, error){ - parseCPU, - parseHeap, - parseGoCount, // goroutine, threadcreate - parseThread, - parseContention, - parseJavaProfile, - } - - for _, parser := range parsers { - p, err := parser(data) - if err == nil { - p.addLegacyFrameInfo() - return p, nil - } - if err != errUnrecognized { - return nil, err - } - } - return nil, errUnrecognized -} - -// ParseUncompressed parses an uncompressed protobuf into a profile. -func ParseUncompressed(data []byte) (*Profile, error) { - if len(data) == 0 { - return nil, errNoData - } - p := &Profile{} - if err := unmarshal(data, p); err != nil { - return nil, err - } - - if err := p.postDecode(); err != nil { - return nil, err - } - - return p, nil -} - -var libRx = regexp.MustCompile(`([.]so$|[.]so[._][0-9]+)`) - -// massageMappings applies heuristic-based changes to the profile -// mappings to account for quirks of some environments. -func (p *Profile) massageMappings() { - // Merge adjacent regions with matching names, checking that the offsets match - if len(p.Mapping) > 1 { - mappings := []*Mapping{p.Mapping[0]} - for _, m := range p.Mapping[1:] { - lm := mappings[len(mappings)-1] - if adjacent(lm, m) { - lm.Limit = m.Limit - if m.File != "" { - lm.File = m.File - } - if m.BuildID != "" { - lm.BuildID = m.BuildID - } - p.updateLocationMapping(m, lm) - continue - } - mappings = append(mappings, m) - } - p.Mapping = mappings - } - - // Use heuristics to identify main binary and move it to the top of the list of mappings - for i, m := range p.Mapping { - file := strings.TrimSpace(strings.Replace(m.File, "(deleted)", "", -1)) - if len(file) == 0 { - continue - } - if len(libRx.FindStringSubmatch(file)) > 0 { - continue - } - if file[0] == '[' { - continue - } - // Swap what we guess is main to position 0. - p.Mapping[0], p.Mapping[i] = p.Mapping[i], p.Mapping[0] - break - } - - // Keep the mapping IDs neatly sorted - for i, m := range p.Mapping { - m.ID = uint64(i + 1) - } -} - -// adjacent returns whether two mapping entries represent the same -// mapping that has been split into two. Check that their addresses are adjacent, -// and if the offsets match, if they are available. -func adjacent(m1, m2 *Mapping) bool { - if m1.File != "" && m2.File != "" { - if m1.File != m2.File { - return false - } - } - if m1.BuildID != "" && m2.BuildID != "" { - if m1.BuildID != m2.BuildID { - return false - } - } - if m1.Limit != m2.Start { - return false - } - if m1.Offset != 0 && m2.Offset != 0 { - offset := m1.Offset + (m1.Limit - m1.Start) - if offset != m2.Offset { - return false - } - } - return true -} - -func (p *Profile) updateLocationMapping(from, to *Mapping) { - for _, l := range p.Location { - if l.Mapping == from { - l.Mapping = to - } - } -} - -func serialize(p *Profile) []byte { - p.encodeMu.Lock() - p.preEncode() - b := marshal(p) - p.encodeMu.Unlock() - return b -} - -// Write writes the profile as a gzip-compressed marshaled protobuf. -func (p *Profile) Write(w io.Writer) error { - zw := gzip.NewWriter(w) - defer zw.Close() - _, err := zw.Write(serialize(p)) - return err -} - -// WriteUncompressed writes the profile as a marshaled protobuf. -func (p *Profile) WriteUncompressed(w io.Writer) error { - _, err := w.Write(serialize(p)) - return err -} - -// CheckValid tests whether the profile is valid. Checks include, but are -// not limited to: -// - len(Profile.Sample[n].value) == len(Profile.value_unit) -// - Sample.id has a corresponding Profile.Location -func (p *Profile) CheckValid() error { - // Check that sample values are consistent - sampleLen := len(p.SampleType) - if sampleLen == 0 && len(p.Sample) != 0 { - return fmt.Errorf("missing sample type information") - } - for _, s := range p.Sample { - if s == nil { - return fmt.Errorf("profile has nil sample") - } - if len(s.Value) != sampleLen { - return fmt.Errorf("mismatch: sample has %d values vs. %d types", len(s.Value), len(p.SampleType)) - } - for _, l := range s.Location { - if l == nil { - return fmt.Errorf("sample has nil location") - } - } - } - - // Check that all mappings/locations/functions are in the tables - // Check that there are no duplicate ids - mappings := make(map[uint64]*Mapping, len(p.Mapping)) - for _, m := range p.Mapping { - if m == nil { - return fmt.Errorf("profile has nil mapping") - } - if m.ID == 0 { - return fmt.Errorf("found mapping with reserved ID=0") - } - if mappings[m.ID] != nil { - return fmt.Errorf("multiple mappings with same id: %d", m.ID) - } - mappings[m.ID] = m - } - functions := make(map[uint64]*Function, len(p.Function)) - for _, f := range p.Function { - if f == nil { - return fmt.Errorf("profile has nil function") - } - if f.ID == 0 { - return fmt.Errorf("found function with reserved ID=0") - } - if functions[f.ID] != nil { - return fmt.Errorf("multiple functions with same id: %d", f.ID) - } - functions[f.ID] = f - } - locations := make(map[uint64]*Location, len(p.Location)) - for _, l := range p.Location { - if l == nil { - return fmt.Errorf("profile has nil location") - } - if l.ID == 0 { - return fmt.Errorf("found location with reserved id=0") - } - if locations[l.ID] != nil { - return fmt.Errorf("multiple locations with same id: %d", l.ID) - } - locations[l.ID] = l - if m := l.Mapping; m != nil { - if m.ID == 0 || mappings[m.ID] != m { - return fmt.Errorf("inconsistent mapping %p: %d", m, m.ID) - } - } - for _, ln := range l.Line { - f := ln.Function - if f == nil { - return fmt.Errorf("location id: %d has a line with nil function", l.ID) - } - if f.ID == 0 || functions[f.ID] != f { - return fmt.Errorf("inconsistent function %p: %d", f, f.ID) - } - } - } - return nil -} - -// Aggregate merges the locations in the profile into equivalence -// classes preserving the request attributes. It also updates the -// samples to point to the merged locations. -func (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, columnnumber, address bool) error { - for _, m := range p.Mapping { - m.HasInlineFrames = m.HasInlineFrames && inlineFrame - m.HasFunctions = m.HasFunctions && function - m.HasFilenames = m.HasFilenames && filename - m.HasLineNumbers = m.HasLineNumbers && linenumber - } - - // Aggregate functions - if !function || !filename { - for _, f := range p.Function { - if !function { - f.Name = "" - f.SystemName = "" - } - if !filename { - f.Filename = "" - } - } - } - - // Aggregate locations - if !inlineFrame || !address || !linenumber || !columnnumber { - for _, l := range p.Location { - if !inlineFrame && len(l.Line) > 1 { - l.Line = l.Line[len(l.Line)-1:] - } - if !linenumber { - for i := range l.Line { - l.Line[i].Line = 0 - l.Line[i].Column = 0 - } - } - if !columnnumber { - for i := range l.Line { - l.Line[i].Column = 0 - } - } - if !address { - l.Address = 0 - } - } - } - - return p.CheckValid() -} - -// NumLabelUnits returns a map of numeric label keys to the units -// associated with those keys and a map of those keys to any units -// that were encountered but not used. -// Unit for a given key is the first encountered unit for that key. If multiple -// units are encountered for values paired with a particular key, then the first -// unit encountered is used and all other units are returned in sorted order -// in map of ignored units. -// If no units are encountered for a particular key, the unit is then inferred -// based on the key. -func (p *Profile) NumLabelUnits() (map[string]string, map[string][]string) { - numLabelUnits := map[string]string{} - ignoredUnits := map[string]map[string]bool{} - encounteredKeys := map[string]bool{} - - // Determine units based on numeric tags for each sample. - for _, s := range p.Sample { - for k := range s.NumLabel { - encounteredKeys[k] = true - for _, unit := range s.NumUnit[k] { - if unit == "" { - continue - } - if wantUnit, ok := numLabelUnits[k]; !ok { - numLabelUnits[k] = unit - } else if wantUnit != unit { - if v, ok := ignoredUnits[k]; ok { - v[unit] = true - } else { - ignoredUnits[k] = map[string]bool{unit: true} - } - } - } - } - } - // Infer units for keys without any units associated with - // numeric tag values. - for key := range encounteredKeys { - unit := numLabelUnits[key] - if unit == "" { - switch key { - case "alignment", "request": - numLabelUnits[key] = "bytes" - default: - numLabelUnits[key] = key - } - } - } - - // Copy ignored units into more readable format - unitsIgnored := make(map[string][]string, len(ignoredUnits)) - for key, values := range ignoredUnits { - units := make([]string, len(values)) - i := 0 - for unit := range values { - units[i] = unit - i++ - } - sort.Strings(units) - unitsIgnored[key] = units - } - - return numLabelUnits, unitsIgnored -} - -// String dumps a text representation of a profile. Intended mainly -// for debugging purposes. -func (p *Profile) String() string { - ss := make([]string, 0, len(p.Comments)+len(p.Sample)+len(p.Mapping)+len(p.Location)) - for _, c := range p.Comments { - ss = append(ss, "Comment: "+c) - } - if url := p.DocURL; url != "" { - ss = append(ss, fmt.Sprintf("Doc: %s", url)) - } - if pt := p.PeriodType; pt != nil { - ss = append(ss, fmt.Sprintf("PeriodType: %s %s", pt.Type, pt.Unit)) - } - ss = append(ss, fmt.Sprintf("Period: %d", p.Period)) - if p.TimeNanos != 0 { - ss = append(ss, fmt.Sprintf("Time: %v", time.Unix(0, p.TimeNanos))) - } - if p.DurationNanos != 0 { - ss = append(ss, fmt.Sprintf("Duration: %.4v", time.Duration(p.DurationNanos))) - } - - ss = append(ss, "Samples:") - var sh1 string - for _, s := range p.SampleType { - dflt := "" - if s.Type == p.DefaultSampleType { - dflt = "[dflt]" - } - sh1 = sh1 + fmt.Sprintf("%s/%s%s ", s.Type, s.Unit, dflt) - } - ss = append(ss, strings.TrimSpace(sh1)) - for _, s := range p.Sample { - ss = append(ss, s.string()) - } - - ss = append(ss, "Locations") - for _, l := range p.Location { - ss = append(ss, l.string()) - } - - ss = append(ss, "Mappings") - for _, m := range p.Mapping { - ss = append(ss, m.string()) - } - - return strings.Join(ss, "\n") + "\n" -} - -// string dumps a text representation of a mapping. Intended mainly -// for debugging purposes. -func (m *Mapping) string() string { - bits := "" - if m.HasFunctions { - bits = bits + "[FN]" - } - if m.HasFilenames { - bits = bits + "[FL]" - } - if m.HasLineNumbers { - bits = bits + "[LN]" - } - if m.HasInlineFrames { - bits = bits + "[IN]" - } - return fmt.Sprintf("%d: %#x/%#x/%#x %s %s %s", - m.ID, - m.Start, m.Limit, m.Offset, - m.File, - m.BuildID, - bits) -} - -// string dumps a text representation of a location. Intended mainly -// for debugging purposes. -func (l *Location) string() string { - ss := []string{} - locStr := fmt.Sprintf("%6d: %#x ", l.ID, l.Address) - if m := l.Mapping; m != nil { - locStr = locStr + fmt.Sprintf("M=%d ", m.ID) - } - if l.IsFolded { - locStr = locStr + "[F] " - } - if len(l.Line) == 0 { - ss = append(ss, locStr) - } - for li := range l.Line { - lnStr := "??" - if fn := l.Line[li].Function; fn != nil { - lnStr = fmt.Sprintf("%s %s:%d:%d s=%d", - fn.Name, - fn.Filename, - l.Line[li].Line, - l.Line[li].Column, - fn.StartLine) - if fn.Name != fn.SystemName { - lnStr = lnStr + "(" + fn.SystemName + ")" - } - } - ss = append(ss, locStr+lnStr) - // Do not print location details past the first line - locStr = " " - } - return strings.Join(ss, "\n") -} - -// string dumps a text representation of a sample. Intended mainly -// for debugging purposes. -func (s *Sample) string() string { - ss := []string{} - var sv string - for _, v := range s.Value { - sv = fmt.Sprintf("%s %10d", sv, v) - } - sv = sv + ": " - for _, l := range s.Location { - sv = sv + fmt.Sprintf("%d ", l.ID) - } - ss = append(ss, sv) - const labelHeader = " " - if len(s.Label) > 0 { - ss = append(ss, labelHeader+labelsToString(s.Label)) - } - if len(s.NumLabel) > 0 { - ss = append(ss, labelHeader+numLabelsToString(s.NumLabel, s.NumUnit)) - } - return strings.Join(ss, "\n") -} - -// labelsToString returns a string representation of a -// map representing labels. -func labelsToString(labels map[string][]string) string { - ls := []string{} - for k, v := range labels { - ls = append(ls, fmt.Sprintf("%s:%v", k, v)) - } - sort.Strings(ls) - return strings.Join(ls, " ") -} - -// numLabelsToString returns a string representation of a map -// representing numeric labels. -func numLabelsToString(numLabels map[string][]int64, numUnits map[string][]string) string { - ls := []string{} - for k, v := range numLabels { - units := numUnits[k] - var labelString string - if len(units) == len(v) { - values := make([]string, len(v)) - for i, vv := range v { - values[i] = fmt.Sprintf("%d %s", vv, units[i]) - } - labelString = fmt.Sprintf("%s:%v", k, values) - } else { - labelString = fmt.Sprintf("%s:%v", k, v) - } - ls = append(ls, labelString) - } - sort.Strings(ls) - return strings.Join(ls, " ") -} - -// SetLabel sets the specified key to the specified value for all samples in the -// profile. -func (p *Profile) SetLabel(key string, value []string) { - for _, sample := range p.Sample { - if sample.Label == nil { - sample.Label = map[string][]string{key: value} - } else { - sample.Label[key] = value - } - } -} - -// RemoveLabel removes all labels associated with the specified key for all -// samples in the profile. -func (p *Profile) RemoveLabel(key string) { - for _, sample := range p.Sample { - delete(sample.Label, key) - } -} - -// HasLabel returns true if a sample has a label with indicated key and value. -func (s *Sample) HasLabel(key, value string) bool { - for _, v := range s.Label[key] { - if v == value { - return true - } - } - return false -} - -// SetNumLabel sets the specified key to the specified value for all samples in the -// profile. "unit" is a slice that describes the units that each corresponding member -// of "values" is measured in (e.g. bytes or seconds). If there is no relevant -// unit for a given value, that member of "unit" should be the empty string. -// "unit" must either have the same length as "value", or be nil. -func (p *Profile) SetNumLabel(key string, value []int64, unit []string) { - for _, sample := range p.Sample { - if sample.NumLabel == nil { - sample.NumLabel = map[string][]int64{key: value} - } else { - sample.NumLabel[key] = value - } - if sample.NumUnit == nil { - sample.NumUnit = map[string][]string{key: unit} - } else { - sample.NumUnit[key] = unit - } - } -} - -// RemoveNumLabel removes all numerical labels associated with the specified key for all -// samples in the profile. -func (p *Profile) RemoveNumLabel(key string) { - for _, sample := range p.Sample { - delete(sample.NumLabel, key) - delete(sample.NumUnit, key) - } -} - -// DiffBaseSample returns true if a sample belongs to the diff base and false -// otherwise. -func (s *Sample) DiffBaseSample() bool { - return s.HasLabel("pprof::base", "true") -} - -// Scale multiplies all sample values in a profile by a constant and keeps -// only samples that have at least one non-zero value. -func (p *Profile) Scale(ratio float64) { - if ratio == 1 { - return - } - ratios := make([]float64, len(p.SampleType)) - for i := range p.SampleType { - ratios[i] = ratio - } - p.ScaleN(ratios) -} - -// ScaleN multiplies each sample values in a sample by a different amount -// and keeps only samples that have at least one non-zero value. -func (p *Profile) ScaleN(ratios []float64) error { - if len(p.SampleType) != len(ratios) { - return fmt.Errorf("mismatched scale ratios, got %d, want %d", len(ratios), len(p.SampleType)) - } - allOnes := true - for _, r := range ratios { - if r != 1 { - allOnes = false - break - } - } - if allOnes { - return nil - } - fillIdx := 0 - for _, s := range p.Sample { - keepSample := false - for i, v := range s.Value { - if ratios[i] != 1 { - val := int64(math.Round(float64(v) * ratios[i])) - s.Value[i] = val - keepSample = keepSample || val != 0 - } - } - if keepSample { - p.Sample[fillIdx] = s - fillIdx++ - } - } - p.Sample = p.Sample[:fillIdx] - return nil -} - -// HasFunctions determines if all locations in this profile have -// symbolized function information. -func (p *Profile) HasFunctions() bool { - for _, l := range p.Location { - if l.Mapping != nil && !l.Mapping.HasFunctions { - return false - } - } - return true -} - -// HasFileLines determines if all locations in this profile have -// symbolized file and line number information. -func (p *Profile) HasFileLines() bool { - for _, l := range p.Location { - if l.Mapping != nil && (!l.Mapping.HasFilenames || !l.Mapping.HasLineNumbers) { - return false - } - } - return true -} - -// Unsymbolizable returns true if a mapping points to a binary for which -// locations can't be symbolized in principle, at least now. Examples are -// "[vdso]", "[vsyscall]" and some others, see the code. -func (m *Mapping) Unsymbolizable() bool { - name := filepath.Base(m.File) - return strings.HasPrefix(name, "[") || strings.HasPrefix(name, "linux-vdso") || strings.HasPrefix(m.File, "/dev/dri/") || m.File == "//anon" -} - -// Copy makes a fully independent copy of a profile. -func (p *Profile) Copy() *Profile { - pp := &Profile{} - if err := unmarshal(serialize(p), pp); err != nil { - panic(err) - } - if err := pp.postDecode(); err != nil { - panic(err) - } - - return pp -} diff --git a/vendor/github.com/google/pprof/profile/proto.go b/vendor/github.com/google/pprof/profile/proto.go deleted file mode 100644 index a15696ba..00000000 --- a/vendor/github.com/google/pprof/profile/proto.go +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// 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. - -// This file is a simple protocol buffer encoder and decoder. -// The format is described at -// https://developers.google.com/protocol-buffers/docs/encoding -// -// A protocol message must implement the message interface: -// decoder() []decoder -// encode(*buffer) -// -// The decode method returns a slice indexed by field number that gives the -// function to decode that field. -// The encode method encodes its receiver into the given buffer. -// -// The two methods are simple enough to be implemented by hand rather than -// by using a protocol compiler. -// -// See profile.go for examples of messages implementing this interface. -// -// There is no support for groups, message sets, or "has" bits. - -package profile - -import ( - "errors" - "fmt" -) - -type buffer struct { - field int // field tag - typ int // proto wire type code for field - u64 uint64 - data []byte - tmp [16]byte - tmpLines []Line // temporary storage used while decoding "repeated Line". -} - -type decoder func(*buffer, message) error - -type message interface { - decoder() []decoder - encode(*buffer) -} - -func marshal(m message) []byte { - var b buffer - m.encode(&b) - return b.data -} - -func encodeVarint(b *buffer, x uint64) { - for x >= 128 { - b.data = append(b.data, byte(x)|0x80) - x >>= 7 - } - b.data = append(b.data, byte(x)) -} - -func encodeLength(b *buffer, tag int, len int) { - encodeVarint(b, uint64(tag)<<3|2) - encodeVarint(b, uint64(len)) -} - -func encodeUint64(b *buffer, tag int, x uint64) { - // append varint to b.data - encodeVarint(b, uint64(tag)<<3) - encodeVarint(b, x) -} - -func encodeUint64s(b *buffer, tag int, x []uint64) { - if len(x) > 2 { - // Use packed encoding - n1 := len(b.data) - for _, u := range x { - encodeVarint(b, u) - } - n2 := len(b.data) - encodeLength(b, tag, n2-n1) - n3 := len(b.data) - copy(b.tmp[:], b.data[n2:n3]) - copy(b.data[n1+(n3-n2):], b.data[n1:n2]) - copy(b.data[n1:], b.tmp[:n3-n2]) - return - } - for _, u := range x { - encodeUint64(b, tag, u) - } -} - -func encodeUint64Opt(b *buffer, tag int, x uint64) { - if x == 0 { - return - } - encodeUint64(b, tag, x) -} - -func encodeInt64(b *buffer, tag int, x int64) { - u := uint64(x) - encodeUint64(b, tag, u) -} - -func encodeInt64s(b *buffer, tag int, x []int64) { - if len(x) > 2 { - // Use packed encoding - n1 := len(b.data) - for _, u := range x { - encodeVarint(b, uint64(u)) - } - n2 := len(b.data) - encodeLength(b, tag, n2-n1) - n3 := len(b.data) - copy(b.tmp[:], b.data[n2:n3]) - copy(b.data[n1+(n3-n2):], b.data[n1:n2]) - copy(b.data[n1:], b.tmp[:n3-n2]) - return - } - for _, u := range x { - encodeInt64(b, tag, u) - } -} - -func encodeInt64Opt(b *buffer, tag int, x int64) { - if x == 0 { - return - } - encodeInt64(b, tag, x) -} - -func encodeString(b *buffer, tag int, x string) { - encodeLength(b, tag, len(x)) - b.data = append(b.data, x...) -} - -func encodeStrings(b *buffer, tag int, x []string) { - for _, s := range x { - encodeString(b, tag, s) - } -} - -func encodeBool(b *buffer, tag int, x bool) { - if x { - encodeUint64(b, tag, 1) - } else { - encodeUint64(b, tag, 0) - } -} - -func encodeBoolOpt(b *buffer, tag int, x bool) { - if x { - encodeBool(b, tag, x) - } -} - -func encodeMessage(b *buffer, tag int, m message) { - n1 := len(b.data) - m.encode(b) - n2 := len(b.data) - encodeLength(b, tag, n2-n1) - n3 := len(b.data) - copy(b.tmp[:], b.data[n2:n3]) - copy(b.data[n1+(n3-n2):], b.data[n1:n2]) - copy(b.data[n1:], b.tmp[:n3-n2]) -} - -func unmarshal(data []byte, m message) (err error) { - b := buffer{data: data, typ: 2} - return decodeMessage(&b, m) -} - -func le64(p []byte) uint64 { - return uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56 -} - -func le32(p []byte) uint32 { - return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24 -} - -func decodeVarint(data []byte) (uint64, []byte, error) { - var u uint64 - for i := 0; ; i++ { - if i >= 10 || i >= len(data) { - return 0, nil, errors.New("bad varint") - } - u |= uint64(data[i]&0x7F) << uint(7*i) - if data[i]&0x80 == 0 { - return u, data[i+1:], nil - } - } -} - -func decodeField(b *buffer, data []byte) ([]byte, error) { - x, data, err := decodeVarint(data) - if err != nil { - return nil, err - } - b.field = int(x >> 3) - b.typ = int(x & 7) - b.data = nil - b.u64 = 0 - switch b.typ { - case 0: - b.u64, data, err = decodeVarint(data) - if err != nil { - return nil, err - } - case 1: - if len(data) < 8 { - return nil, errors.New("not enough data") - } - b.u64 = le64(data[:8]) - data = data[8:] - case 2: - var n uint64 - n, data, err = decodeVarint(data) - if err != nil { - return nil, err - } - if n > uint64(len(data)) { - return nil, errors.New("too much data") - } - b.data = data[:n] - data = data[n:] - case 5: - if len(data) < 4 { - return nil, errors.New("not enough data") - } - b.u64 = uint64(le32(data[:4])) - data = data[4:] - default: - return nil, fmt.Errorf("unknown wire type: %d", b.typ) - } - - return data, nil -} - -func checkType(b *buffer, typ int) error { - if b.typ != typ { - return errors.New("type mismatch") - } - return nil -} - -func decodeMessage(b *buffer, m message) error { - if err := checkType(b, 2); err != nil { - return err - } - dec := m.decoder() - data := b.data - for len(data) > 0 { - // pull varint field# + type - var err error - data, err = decodeField(b, data) - if err != nil { - return err - } - if b.field >= len(dec) || dec[b.field] == nil { - continue - } - if err := dec[b.field](b, m); err != nil { - return err - } - } - return nil -} - -func decodeInt64(b *buffer, x *int64) error { - if err := checkType(b, 0); err != nil { - return err - } - *x = int64(b.u64) - return nil -} - -func decodeInt64s(b *buffer, x *[]int64) error { - if b.typ == 2 { - // Packed encoding - data := b.data - for len(data) > 0 { - var u uint64 - var err error - - if u, data, err = decodeVarint(data); err != nil { - return err - } - *x = append(*x, int64(u)) - } - return nil - } - var i int64 - if err := decodeInt64(b, &i); err != nil { - return err - } - *x = append(*x, i) - return nil -} - -func decodeUint64(b *buffer, x *uint64) error { - if err := checkType(b, 0); err != nil { - return err - } - *x = b.u64 - return nil -} - -func decodeUint64s(b *buffer, x *[]uint64) error { - if b.typ == 2 { - data := b.data - // Packed encoding - for len(data) > 0 { - var u uint64 - var err error - - if u, data, err = decodeVarint(data); err != nil { - return err - } - *x = append(*x, u) - } - return nil - } - var u uint64 - if err := decodeUint64(b, &u); err != nil { - return err - } - *x = append(*x, u) - return nil -} - -func decodeString(b *buffer, x *string) error { - if err := checkType(b, 2); err != nil { - return err - } - *x = string(b.data) - return nil -} - -func decodeStrings(b *buffer, x *[]string) error { - var s string - if err := decodeString(b, &s); err != nil { - return err - } - *x = append(*x, s) - return nil -} - -func decodeBool(b *buffer, x *bool) error { - if err := checkType(b, 0); err != nil { - return err - } - if int64(b.u64) == 0 { - *x = false - } else { - *x = true - } - return nil -} diff --git a/vendor/github.com/google/pprof/profile/prune.go b/vendor/github.com/google/pprof/profile/prune.go deleted file mode 100644 index b2f9fd54..00000000 --- a/vendor/github.com/google/pprof/profile/prune.go +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// 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. - -// Implements methods to remove frames from profiles. - -package profile - -import ( - "fmt" - "regexp" - "strings" -) - -var ( - reservedNames = []string{"(anonymous namespace)", "operator()"} - bracketRx = func() *regexp.Regexp { - var quotedNames []string - for _, name := range append(reservedNames, "(") { - quotedNames = append(quotedNames, regexp.QuoteMeta(name)) - } - return regexp.MustCompile(strings.Join(quotedNames, "|")) - }() -) - -// simplifyFunc does some primitive simplification of function names. -func simplifyFunc(f string) string { - // Account for leading '.' on the PPC ELF v1 ABI. - funcName := strings.TrimPrefix(f, ".") - // Account for unsimplified names -- try to remove the argument list by trimming - // starting from the first '(', but skipping reserved names that have '('. - for _, ind := range bracketRx.FindAllStringSubmatchIndex(funcName, -1) { - foundReserved := false - for _, res := range reservedNames { - if funcName[ind[0]:ind[1]] == res { - foundReserved = true - break - } - } - if !foundReserved { - funcName = funcName[:ind[0]] - break - } - } - return funcName -} - -// Prune removes all nodes beneath a node matching dropRx, and not -// matching keepRx. If the root node of a Sample matches, the sample -// will have an empty stack. -func (p *Profile) Prune(dropRx, keepRx *regexp.Regexp) { - prune := make(map[uint64]bool) - pruneBeneath := make(map[uint64]bool) - - // simplifyFunc can be expensive, so cache results. - // Note that the same function name can be encountered many times due - // different lines and addresses in the same function. - pruneCache := map[string]bool{} // Map from function to whether or not to prune - pruneFromHere := func(s string) bool { - if r, ok := pruneCache[s]; ok { - return r - } - funcName := simplifyFunc(s) - if dropRx.MatchString(funcName) { - if keepRx == nil || !keepRx.MatchString(funcName) { - pruneCache[s] = true - return true - } - } - pruneCache[s] = false - return false - } - - for _, loc := range p.Location { - var i int - for i = len(loc.Line) - 1; i >= 0; i-- { - if fn := loc.Line[i].Function; fn != nil && fn.Name != "" { - if pruneFromHere(fn.Name) { - break - } - } - } - - if i >= 0 { - // Found matching entry to prune. - pruneBeneath[loc.ID] = true - - // Remove the matching location. - if i == len(loc.Line)-1 { - // Matched the top entry: prune the whole location. - prune[loc.ID] = true - } else { - loc.Line = loc.Line[i+1:] - } - } - } - - // Prune locs from each Sample - for _, sample := range p.Sample { - // Scan from the root to the leaves to find the prune location. - // Do not prune frames before the first user frame, to avoid - // pruning everything. - foundUser := false - for i := len(sample.Location) - 1; i >= 0; i-- { - id := sample.Location[i].ID - if !prune[id] && !pruneBeneath[id] { - foundUser = true - continue - } - if !foundUser { - continue - } - if prune[id] { - sample.Location = sample.Location[i+1:] - break - } - if pruneBeneath[id] { - sample.Location = sample.Location[i:] - break - } - } - } -} - -// RemoveUninteresting prunes and elides profiles using built-in -// tables of uninteresting function names. -func (p *Profile) RemoveUninteresting() error { - var keep, drop *regexp.Regexp - var err error - - if p.DropFrames != "" { - if drop, err = regexp.Compile("^(" + p.DropFrames + ")$"); err != nil { - return fmt.Errorf("failed to compile regexp %s: %v", p.DropFrames, err) - } - if p.KeepFrames != "" { - if keep, err = regexp.Compile("^(" + p.KeepFrames + ")$"); err != nil { - return fmt.Errorf("failed to compile regexp %s: %v", p.KeepFrames, err) - } - } - p.Prune(drop, keep) - } - return nil -} - -// PruneFrom removes all nodes beneath the lowest node matching dropRx, not including itself. -// -// Please see the example below to understand this method as well as -// the difference from Prune method. -// -// A sample contains Location of [A,B,C,B,D] where D is the top frame and there's no inline. -// -// PruneFrom(A) returns [A,B,C,B,D] because there's no node beneath A. -// Prune(A, nil) returns [B,C,B,D] by removing A itself. -// -// PruneFrom(B) returns [B,C,B,D] by removing all nodes beneath the first B when scanning from the bottom. -// Prune(B, nil) returns [D] because a matching node is found by scanning from the root. -func (p *Profile) PruneFrom(dropRx *regexp.Regexp) { - pruneBeneath := make(map[uint64]bool) - - for _, loc := range p.Location { - for i := 0; i < len(loc.Line); i++ { - if fn := loc.Line[i].Function; fn != nil && fn.Name != "" { - funcName := simplifyFunc(fn.Name) - if dropRx.MatchString(funcName) { - // Found matching entry to prune. - pruneBeneath[loc.ID] = true - loc.Line = loc.Line[i:] - break - } - } - } - } - - // Prune locs from each Sample - for _, sample := range p.Sample { - // Scan from the bottom leaf to the root to find the prune location. - for i, loc := range sample.Location { - if pruneBeneath[loc.ID] { - sample.Location = sample.Location[i:] - break - } - } - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/LICENSE b/vendor/github.com/onsi/ginkgo/v2/LICENSE deleted file mode 100644 index 9415ee72..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2013-2014 Onsi Fakhouri - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/onsi/ginkgo/v2/config/deprecated.go b/vendor/github.com/onsi/ginkgo/v2/config/deprecated.go deleted file mode 100644 index a61021d0..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/config/deprecated.go +++ /dev/null @@ -1,69 +0,0 @@ -package config - -// GinkgoConfigType has been deprecated and its equivalent now lives in -// the types package. You can no longer access Ginkgo configuration from the config -// package. Instead use the DSL's GinkgoConfiguration() function to get copies of the -// current configuration -// -// GinkgoConfigType is still here so custom V1 reporters do not result in a compilation error -// It will be removed in a future minor release of Ginkgo -type GinkgoConfigType = DeprecatedGinkgoConfigType -type DeprecatedGinkgoConfigType struct { - RandomSeed int64 - RandomizeAllSpecs bool - RegexScansFilePath bool - FocusStrings []string - SkipStrings []string - SkipMeasurements bool - FailOnPending bool - FailFast bool - FlakeAttempts int - EmitSpecProgress bool - DryRun bool - DebugParallel bool - - ParallelNode int - ParallelTotal int - SyncHost string - StreamHost string -} - -// DefaultReporterConfigType has been deprecated and its equivalent now lives in -// the types package. You can no longer access Ginkgo configuration from the config -// package. Instead use the DSL's GinkgoConfiguration() function to get copies of the -// current configuration -// -// DefaultReporterConfigType is still here so custom V1 reporters do not result in a compilation error -// It will be removed in a future minor release of Ginkgo -type DefaultReporterConfigType = DeprecatedDefaultReporterConfigType -type DeprecatedDefaultReporterConfigType struct { - NoColor bool - SlowSpecThreshold float64 - NoisyPendings bool - NoisySkippings bool - Succinct bool - Verbose bool - FullTrace bool - ReportPassed bool - ReportFile string -} - -// Sadly there is no way to gracefully deprecate access to these global config variables. -// Users who need access to Ginkgo's configuration should use the DSL's GinkgoConfiguration() method -// These new unwieldy type names exist to give users a hint when they try to compile and the compilation fails -type GinkgoConfigIsNoLongerAccessibleFromTheConfigPackageUseTheDSLsGinkgoConfigurationFunctionInstead struct{} - -// Sadly there is no way to gracefully deprecate access to these global config variables. -// Users who need access to Ginkgo's configuration should use the DSL's GinkgoConfiguration() method -// These new unwieldy type names exist to give users a hint when they try to compile and the compilation fails -var GinkgoConfig = GinkgoConfigIsNoLongerAccessibleFromTheConfigPackageUseTheDSLsGinkgoConfigurationFunctionInstead{} - -// Sadly there is no way to gracefully deprecate access to these global config variables. -// Users who need access to Ginkgo's configuration should use the DSL's GinkgoConfiguration() method -// These new unwieldy type names exist to give users a hint when they try to compile and the compilation fails -type DefaultReporterConfigIsNoLongerAccessibleFromTheConfigPackageUseTheDSLsGinkgoConfigurationFunctionInstead struct{} - -// Sadly there is no way to gracefully deprecate access to these global config variables. -// Users who need access to Ginkgo's configuration should use the DSL's GinkgoConfiguration() method -// These new unwieldy type names exist to give users a hint when they try to compile and the compilation fails -var DefaultReporterConfig = DefaultReporterConfigIsNoLongerAccessibleFromTheConfigPackageUseTheDSLsGinkgoConfigurationFunctionInstead{} diff --git a/vendor/github.com/onsi/ginkgo/v2/formatter/colorable_others.go b/vendor/github.com/onsi/ginkgo/v2/formatter/colorable_others.go deleted file mode 100644 index 778bfd7c..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/formatter/colorable_others.go +++ /dev/null @@ -1,41 +0,0 @@ -// +build !windows - -/* -These packages are used for colorize on Windows and contributed by mattn.jp@gmail.com - - * go-colorable: - * go-isatty: - -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package formatter - -import ( - "io" - "os" -) - -func newColorable(file *os.File) io.Writer { - return file -} diff --git a/vendor/github.com/onsi/ginkgo/v2/formatter/colorable_windows.go b/vendor/github.com/onsi/ginkgo/v2/formatter/colorable_windows.go deleted file mode 100644 index dd1d143c..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/formatter/colorable_windows.go +++ /dev/null @@ -1,809 +0,0 @@ -/* -These packages are used for colorize on Windows and contributed by mattn.jp@gmail.com - - * go-colorable: - * go-isatty: - -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package formatter - -import ( - "bytes" - "fmt" - "io" - "math" - "os" - "strconv" - "strings" - "syscall" - "unsafe" -) - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") - procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") - procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") - procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") -) - -func isTerminal(fd uintptr) bool { - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 -} - -const ( - foregroundBlue = 0x1 - foregroundGreen = 0x2 - foregroundRed = 0x4 - foregroundIntensity = 0x8 - foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) - backgroundBlue = 0x10 - backgroundGreen = 0x20 - backgroundRed = 0x40 - backgroundIntensity = 0x80 - backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) -) - -type wchar uint16 -type short int16 -type dword uint32 -type word uint16 - -type coord struct { - x short - y short -} - -type smallRect struct { - left short - top short - right short - bottom short -} - -type consoleScreenBufferInfo struct { - size coord - cursorPosition coord - attributes word - window smallRect - maximumWindowSize coord -} - -type writer struct { - out io.Writer - handle syscall.Handle - lastbuf bytes.Buffer - oldattr word -} - -func newColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - if isTerminal(file.Fd()) { - var csbi consoleScreenBufferInfo - handle := syscall.Handle(file.Fd()) - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - return &writer{out: file, handle: handle, oldattr: csbi.attributes} - } else { - return file - } -} - -var color256 = map[int]int{ - 0: 0x000000, - 1: 0x800000, - 2: 0x008000, - 3: 0x808000, - 4: 0x000080, - 5: 0x800080, - 6: 0x008080, - 7: 0xc0c0c0, - 8: 0x808080, - 9: 0xff0000, - 10: 0x00ff00, - 11: 0xffff00, - 12: 0x0000ff, - 13: 0xff00ff, - 14: 0x00ffff, - 15: 0xffffff, - 16: 0x000000, - 17: 0x00005f, - 18: 0x000087, - 19: 0x0000af, - 20: 0x0000d7, - 21: 0x0000ff, - 22: 0x005f00, - 23: 0x005f5f, - 24: 0x005f87, - 25: 0x005faf, - 26: 0x005fd7, - 27: 0x005fff, - 28: 0x008700, - 29: 0x00875f, - 30: 0x008787, - 31: 0x0087af, - 32: 0x0087d7, - 33: 0x0087ff, - 34: 0x00af00, - 35: 0x00af5f, - 36: 0x00af87, - 37: 0x00afaf, - 38: 0x00afd7, - 39: 0x00afff, - 40: 0x00d700, - 41: 0x00d75f, - 42: 0x00d787, - 43: 0x00d7af, - 44: 0x00d7d7, - 45: 0x00d7ff, - 46: 0x00ff00, - 47: 0x00ff5f, - 48: 0x00ff87, - 49: 0x00ffaf, - 50: 0x00ffd7, - 51: 0x00ffff, - 52: 0x5f0000, - 53: 0x5f005f, - 54: 0x5f0087, - 55: 0x5f00af, - 56: 0x5f00d7, - 57: 0x5f00ff, - 58: 0x5f5f00, - 59: 0x5f5f5f, - 60: 0x5f5f87, - 61: 0x5f5faf, - 62: 0x5f5fd7, - 63: 0x5f5fff, - 64: 0x5f8700, - 65: 0x5f875f, - 66: 0x5f8787, - 67: 0x5f87af, - 68: 0x5f87d7, - 69: 0x5f87ff, - 70: 0x5faf00, - 71: 0x5faf5f, - 72: 0x5faf87, - 73: 0x5fafaf, - 74: 0x5fafd7, - 75: 0x5fafff, - 76: 0x5fd700, - 77: 0x5fd75f, - 78: 0x5fd787, - 79: 0x5fd7af, - 80: 0x5fd7d7, - 81: 0x5fd7ff, - 82: 0x5fff00, - 83: 0x5fff5f, - 84: 0x5fff87, - 85: 0x5fffaf, - 86: 0x5fffd7, - 87: 0x5fffff, - 88: 0x870000, - 89: 0x87005f, - 90: 0x870087, - 91: 0x8700af, - 92: 0x8700d7, - 93: 0x8700ff, - 94: 0x875f00, - 95: 0x875f5f, - 96: 0x875f87, - 97: 0x875faf, - 98: 0x875fd7, - 99: 0x875fff, - 100: 0x878700, - 101: 0x87875f, - 102: 0x878787, - 103: 0x8787af, - 104: 0x8787d7, - 105: 0x8787ff, - 106: 0x87af00, - 107: 0x87af5f, - 108: 0x87af87, - 109: 0x87afaf, - 110: 0x87afd7, - 111: 0x87afff, - 112: 0x87d700, - 113: 0x87d75f, - 114: 0x87d787, - 115: 0x87d7af, - 116: 0x87d7d7, - 117: 0x87d7ff, - 118: 0x87ff00, - 119: 0x87ff5f, - 120: 0x87ff87, - 121: 0x87ffaf, - 122: 0x87ffd7, - 123: 0x87ffff, - 124: 0xaf0000, - 125: 0xaf005f, - 126: 0xaf0087, - 127: 0xaf00af, - 128: 0xaf00d7, - 129: 0xaf00ff, - 130: 0xaf5f00, - 131: 0xaf5f5f, - 132: 0xaf5f87, - 133: 0xaf5faf, - 134: 0xaf5fd7, - 135: 0xaf5fff, - 136: 0xaf8700, - 137: 0xaf875f, - 138: 0xaf8787, - 139: 0xaf87af, - 140: 0xaf87d7, - 141: 0xaf87ff, - 142: 0xafaf00, - 143: 0xafaf5f, - 144: 0xafaf87, - 145: 0xafafaf, - 146: 0xafafd7, - 147: 0xafafff, - 148: 0xafd700, - 149: 0xafd75f, - 150: 0xafd787, - 151: 0xafd7af, - 152: 0xafd7d7, - 153: 0xafd7ff, - 154: 0xafff00, - 155: 0xafff5f, - 156: 0xafff87, - 157: 0xafffaf, - 158: 0xafffd7, - 159: 0xafffff, - 160: 0xd70000, - 161: 0xd7005f, - 162: 0xd70087, - 163: 0xd700af, - 164: 0xd700d7, - 165: 0xd700ff, - 166: 0xd75f00, - 167: 0xd75f5f, - 168: 0xd75f87, - 169: 0xd75faf, - 170: 0xd75fd7, - 171: 0xd75fff, - 172: 0xd78700, - 173: 0xd7875f, - 174: 0xd78787, - 175: 0xd787af, - 176: 0xd787d7, - 177: 0xd787ff, - 178: 0xd7af00, - 179: 0xd7af5f, - 180: 0xd7af87, - 181: 0xd7afaf, - 182: 0xd7afd7, - 183: 0xd7afff, - 184: 0xd7d700, - 185: 0xd7d75f, - 186: 0xd7d787, - 187: 0xd7d7af, - 188: 0xd7d7d7, - 189: 0xd7d7ff, - 190: 0xd7ff00, - 191: 0xd7ff5f, - 192: 0xd7ff87, - 193: 0xd7ffaf, - 194: 0xd7ffd7, - 195: 0xd7ffff, - 196: 0xff0000, - 197: 0xff005f, - 198: 0xff0087, - 199: 0xff00af, - 200: 0xff00d7, - 201: 0xff00ff, - 202: 0xff5f00, - 203: 0xff5f5f, - 204: 0xff5f87, - 205: 0xff5faf, - 206: 0xff5fd7, - 207: 0xff5fff, - 208: 0xff8700, - 209: 0xff875f, - 210: 0xff8787, - 211: 0xff87af, - 212: 0xff87d7, - 213: 0xff87ff, - 214: 0xffaf00, - 215: 0xffaf5f, - 216: 0xffaf87, - 217: 0xffafaf, - 218: 0xffafd7, - 219: 0xffafff, - 220: 0xffd700, - 221: 0xffd75f, - 222: 0xffd787, - 223: 0xffd7af, - 224: 0xffd7d7, - 225: 0xffd7ff, - 226: 0xffff00, - 227: 0xffff5f, - 228: 0xffff87, - 229: 0xffffaf, - 230: 0xffffd7, - 231: 0xffffff, - 232: 0x080808, - 233: 0x121212, - 234: 0x1c1c1c, - 235: 0x262626, - 236: 0x303030, - 237: 0x3a3a3a, - 238: 0x444444, - 239: 0x4e4e4e, - 240: 0x585858, - 241: 0x626262, - 242: 0x6c6c6c, - 243: 0x767676, - 244: 0x808080, - 245: 0x8a8a8a, - 246: 0x949494, - 247: 0x9e9e9e, - 248: 0xa8a8a8, - 249: 0xb2b2b2, - 250: 0xbcbcbc, - 251: 0xc6c6c6, - 252: 0xd0d0d0, - 253: 0xdadada, - 254: 0xe4e4e4, - 255: 0xeeeeee, -} - -func (w *writer) Write(data []byte) (n int, err error) { - var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - - er := bytes.NewBuffer(data) -loop: - for { - r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - if r1 == 0 { - break loop - } - - c1, _, err := er.ReadRune() - if err != nil { - break loop - } - if c1 != 0x1b { - fmt.Fprint(w.out, string(c1)) - continue - } - c2, _, err := er.ReadRune() - if err != nil { - w.lastbuf.WriteRune(c1) - break loop - } - if c2 != 0x5b { - w.lastbuf.WriteRune(c1) - w.lastbuf.WriteRune(c2) - continue - } - - var buf bytes.Buffer - var m rune - for { - c, _, err := er.ReadRune() - if err != nil { - w.lastbuf.WriteRune(c1) - w.lastbuf.WriteRune(c2) - w.lastbuf.Write(buf.Bytes()) - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - m = c - break - } - buf.Write([]byte(string(c))) - } - - var csbi consoleScreenBufferInfo - switch m { - case 'A': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'B': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'C': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'D': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - if n, err = strconv.Atoi(buf.String()); err == nil { - var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - } - case 'E': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'F': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'G': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'H': - token := strings.Split(buf.String(), ";") - if len(token) != 2 { - continue - } - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - n2, err := strconv.Atoi(token[1]) - if err != nil { - continue - } - csbi.cursorPosition.x = short(n2) - csbi.cursorPosition.x = short(n1) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'J': - n, err := strconv.Atoi(buf.String()) - if err != nil { - continue - } - var cursor coord - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - } - var count, written dword - count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) - procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'K': - n, err := strconv.Atoi(buf.String()) - if err != nil { - continue - } - var cursor coord - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} - } - var count, written dword - count = dword(csbi.size.x - csbi.cursorPosition.x) - procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'm': - attr := csbi.attributes - cs := buf.String() - if cs == "" { - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr)) - continue - } - token := strings.Split(cs, ";") - for i := 0; i < len(token); i += 1 { - ns := token[i] - if n, err = strconv.Atoi(ns); err == nil { - switch { - case n == 0 || n == 100: - attr = w.oldattr - case 1 <= n && n <= 5: - attr |= foregroundIntensity - case n == 7: - attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case 22 == n || n == 25 || n == 25: - attr |= foregroundIntensity - case n == 27: - attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case 30 <= n && n <= 37: - attr = (attr & backgroundMask) - if (n-30)&1 != 0 { - attr |= foregroundRed - } - if (n-30)&2 != 0 { - attr |= foregroundGreen - } - if (n-30)&4 != 0 { - attr |= foregroundBlue - } - case n == 38: // set foreground color. - if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256foreAttr == nil { - n256setup() - } - attr &= backgroundMask - attr |= n256foreAttr[n256] - i += 2 - } - } else { - attr = attr & (w.oldattr & backgroundMask) - } - case n == 39: // reset foreground color. - attr &= backgroundMask - attr |= w.oldattr & foregroundMask - case 40 <= n && n <= 47: - attr = (attr & foregroundMask) - if (n-40)&1 != 0 { - attr |= backgroundRed - } - if (n-40)&2 != 0 { - attr |= backgroundGreen - } - if (n-40)&4 != 0 { - attr |= backgroundBlue - } - case n == 48: // set background color. - if i < len(token)-2 && token[i+1] == "5" { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256backAttr == nil { - n256setup() - } - attr &= foregroundMask - attr |= n256backAttr[n256] - i += 2 - } - } else { - attr = attr & (w.oldattr & foregroundMask) - } - case n == 49: // reset foreground color. - attr &= foregroundMask - attr |= w.oldattr & backgroundMask - case 90 <= n && n <= 97: - attr = (attr & backgroundMask) - attr |= foregroundIntensity - if (n-90)&1 != 0 { - attr |= foregroundRed - } - if (n-90)&2 != 0 { - attr |= foregroundGreen - } - if (n-90)&4 != 0 { - attr |= foregroundBlue - } - case 100 <= n && n <= 107: - attr = (attr & foregroundMask) - attr |= backgroundIntensity - if (n-100)&1 != 0 { - attr |= backgroundRed - } - if (n-100)&2 != 0 { - attr |= backgroundGreen - } - if (n-100)&4 != 0 { - attr |= backgroundBlue - } - } - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) - } - } - } - } - return len(data) - w.lastbuf.Len(), nil -} - -type consoleColor struct { - rgb int - red bool - green bool - blue bool - intensity bool -} - -func (c consoleColor) foregroundAttr() (attr word) { - if c.red { - attr |= foregroundRed - } - if c.green { - attr |= foregroundGreen - } - if c.blue { - attr |= foregroundBlue - } - if c.intensity { - attr |= foregroundIntensity - } - return -} - -func (c consoleColor) backgroundAttr() (attr word) { - if c.red { - attr |= backgroundRed - } - if c.green { - attr |= backgroundGreen - } - if c.blue { - attr |= backgroundBlue - } - if c.intensity { - attr |= backgroundIntensity - } - return -} - -var color16 = []consoleColor{ - consoleColor{0x000000, false, false, false, false}, - consoleColor{0x000080, false, false, true, false}, - consoleColor{0x008000, false, true, false, false}, - consoleColor{0x008080, false, true, true, false}, - consoleColor{0x800000, true, false, false, false}, - consoleColor{0x800080, true, false, true, false}, - consoleColor{0x808000, true, true, false, false}, - consoleColor{0xc0c0c0, true, true, true, false}, - consoleColor{0x808080, false, false, false, true}, - consoleColor{0x0000ff, false, false, true, true}, - consoleColor{0x00ff00, false, true, false, true}, - consoleColor{0x00ffff, false, true, true, true}, - consoleColor{0xff0000, true, false, false, true}, - consoleColor{0xff00ff, true, false, true, true}, - consoleColor{0xffff00, true, true, false, true}, - consoleColor{0xffffff, true, true, true, true}, -} - -type hsv struct { - h, s, v float32 -} - -func (a hsv) dist(b hsv) float32 { - dh := a.h - b.h - switch { - case dh > 0.5: - dh = 1 - dh - case dh < -0.5: - dh = -1 - dh - } - ds := a.s - b.s - dv := a.v - b.v - return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) -} - -func toHSV(rgb int) hsv { - r, g, b := float32((rgb&0xFF0000)>>16)/256.0, - float32((rgb&0x00FF00)>>8)/256.0, - float32(rgb&0x0000FF)/256.0 - min, max := minmax3f(r, g, b) - h := max - min - if h > 0 { - if max == r { - h = (g - b) / h - if h < 0 { - h += 6 - } - } else if max == g { - h = 2 + (b-r)/h - } else { - h = 4 + (r-g)/h - } - } - h /= 6.0 - s := max - min - if max != 0 { - s /= max - } - v := max - return hsv{h: h, s: s, v: v} -} - -type hsvTable []hsv - -func toHSVTable(rgbTable []consoleColor) hsvTable { - t := make(hsvTable, len(rgbTable)) - for i, c := range rgbTable { - t[i] = toHSV(c.rgb) - } - return t -} - -func (t hsvTable) find(rgb int) consoleColor { - hsv := toHSV(rgb) - n := 7 - l := float32(5.0) - for i, p := range t { - d := hsv.dist(p) - if d < l { - l, n = d, i - } - } - return color16[n] -} - -func minmax3f(a, b, c float32) (min, max float32) { - if a < b { - if b < c { - return a, c - } else if a < c { - return a, b - } else { - return c, b - } - } else { - if a < c { - return b, c - } else if b < c { - return b, a - } else { - return c, a - } - } -} - -var n256foreAttr []word -var n256backAttr []word - -func n256setup() { - n256foreAttr = make([]word, 256) - n256backAttr = make([]word, 256) - t := toHSVTable(color16) - for i, rgb := range color256 { - c := t.find(rgb) - n256foreAttr[i] = c.foregroundAttr() - n256backAttr[i] = c.backgroundAttr() - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go b/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go deleted file mode 100644 index f61356db..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go +++ /dev/null @@ -1,234 +0,0 @@ -package formatter - -import ( - "fmt" - "os" - "regexp" - "strconv" - "strings" -) - -// ColorableStdOut and ColorableStdErr enable color output support on Windows -var ColorableStdOut = newColorable(os.Stdout) -var ColorableStdErr = newColorable(os.Stderr) - -const COLS = 80 - -type ColorMode uint8 - -const ( - ColorModeNone ColorMode = iota - ColorModeTerminal - ColorModePassthrough -) - -var SingletonFormatter = New(ColorModeTerminal) - -func F(format string, args ...any) string { - return SingletonFormatter.F(format, args...) -} - -func Fi(indentation uint, format string, args ...any) string { - return SingletonFormatter.Fi(indentation, format, args...) -} - -func Fiw(indentation uint, maxWidth uint, format string, args ...any) string { - return SingletonFormatter.Fiw(indentation, maxWidth, format, args...) -} - -type Formatter struct { - ColorMode ColorMode - colors map[string]string - styleRe *regexp.Regexp - preserveColorStylingTags bool -} - -func NewWithNoColorBool(noColor bool) Formatter { - if noColor { - return New(ColorModeNone) - } - return New(ColorModeTerminal) -} - -func New(colorMode ColorMode) Formatter { - colorAliases := map[string]int{ - "black": 0, - "red": 1, - "green": 2, - "yellow": 3, - "blue": 4, - "magenta": 5, - "cyan": 6, - "white": 7, - } - for colorAlias, n := range colorAliases { - colorAliases[fmt.Sprintf("bright-%s", colorAlias)] = n + 8 - } - - getColor := func(color, defaultEscapeCode string) string { - color = strings.ToUpper(strings.ReplaceAll(color, "-", "_")) - envVar := fmt.Sprintf("GINKGO_CLI_COLOR_%s", color) - envVarColor := os.Getenv(envVar) - if envVarColor == "" { - return defaultEscapeCode - } - if colorCode, ok := colorAliases[envVarColor]; ok { - return fmt.Sprintf("\x1b[38;5;%dm", colorCode) - } - colorCode, err := strconv.Atoi(envVarColor) - if err != nil || colorCode < 0 || colorCode > 255 { - return defaultEscapeCode - } - return fmt.Sprintf("\x1b[38;5;%dm", colorCode) - } - - if _, noColor := os.LookupEnv("GINKGO_NO_COLOR"); noColor { - colorMode = ColorModeNone - } - - f := Formatter{ - ColorMode: colorMode, - colors: map[string]string{ - "/": "\x1b[0m", - "bold": "\x1b[1m", - "underline": "\x1b[4m", - - "red": getColor("red", "\x1b[38;5;9m"), - "orange": getColor("orange", "\x1b[38;5;214m"), - "coral": getColor("coral", "\x1b[38;5;204m"), - "magenta": getColor("magenta", "\x1b[38;5;13m"), - "green": getColor("green", "\x1b[38;5;10m"), - "dark-green": getColor("dark-green", "\x1b[38;5;28m"), - "yellow": getColor("yellow", "\x1b[38;5;11m"), - "light-yellow": getColor("light-yellow", "\x1b[38;5;228m"), - "cyan": getColor("cyan", "\x1b[38;5;14m"), - "gray": getColor("gray", "\x1b[38;5;243m"), - "light-gray": getColor("light-gray", "\x1b[38;5;246m"), - "blue": getColor("blue", "\x1b[38;5;12m"), - }, - } - colors := []string{} - for color := range f.colors { - colors = append(colors, color) - } - f.styleRe = regexp.MustCompile("{{(" + strings.Join(colors, "|") + ")}}") - return f -} - -func (f Formatter) F(format string, args ...any) string { - return f.Fi(0, format, args...) -} - -func (f Formatter) Fi(indentation uint, format string, args ...any) string { - return f.Fiw(indentation, 0, format, args...) -} - -func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...any) string { - out := f.style(format) - if len(args) > 0 { - out = fmt.Sprintf(out, args...) - } - - if indentation == 0 && maxWidth == 0 { - return out - } - - lines := strings.Split(out, "\n") - - if maxWidth != 0 { - outLines := []string{} - - maxWidth = maxWidth - indentation*2 - for _, line := range lines { - if f.length(line) <= maxWidth { - outLines = append(outLines, line) - continue - } - words := strings.Split(line, " ") - outWords := []string{words[0]} - length := uint(f.length(words[0])) - for _, word := range words[1:] { - wordLength := f.length(word) - if length+wordLength+1 <= maxWidth { - length += wordLength + 1 - outWords = append(outWords, word) - continue - } - outLines = append(outLines, strings.Join(outWords, " ")) - outWords = []string{word} - length = wordLength - } - if len(outWords) > 0 { - outLines = append(outLines, strings.Join(outWords, " ")) - } - } - - lines = outLines - } - - if indentation == 0 { - return strings.Join(lines, "\n") - } - - padding := strings.Repeat(" ", int(indentation)) - for i := range lines { - if lines[i] != "" { - lines[i] = padding + lines[i] - } - } - - return strings.Join(lines, "\n") -} - -func (f Formatter) length(styled string) uint { - n := uint(0) - inStyle := false - for _, b := range styled { - if inStyle { - if b == 'm' { - inStyle = false - } - continue - } - if b == '\x1b' { - inStyle = true - continue - } - n += 1 - } - return n -} - -func (f Formatter) CycleJoin(elements []string, joiner string, cycle []string) string { - if len(elements) == 0 { - return "" - } - n := len(cycle) - out := "" - for i, text := range elements { - out += cycle[i%n] + text - if i < len(elements)-1 { - out += joiner - } - } - out += "{{/}}" - return f.style(out) -} - -func (f Formatter) style(s string) string { - switch f.ColorMode { - case ColorModeNone: - return f.styleRe.ReplaceAllString(s, "") - case ColorModePassthrough: - return s - case ColorModeTerminal: - return f.styleRe.ReplaceAllStringFunc(s, func(match string) string { - if out, ok := f.colors[strings.Trim(match, "{}")]; ok { - return out - } - return match - }) - } - - return "" -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go deleted file mode 100644 index 2b36b2fe..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go +++ /dev/null @@ -1,80 +0,0 @@ -package build - -import ( - "fmt" - "os" - "path" - - "github.com/onsi/ginkgo/v2/ginkgo/command" - "github.com/onsi/ginkgo/v2/ginkgo/internal" - "github.com/onsi/ginkgo/v2/types" -) - -func BuildBuildCommand() command.Command { - var cliConfig = types.NewDefaultCLIConfig() - var goFlagsConfig = types.NewDefaultGoFlagsConfig() - - flags, err := types.BuildBuildCommandFlagSet(&cliConfig, &goFlagsConfig) - if err != nil { - panic(err) - } - - return command.Command{ - Name: "build", - Flags: flags, - Usage: "ginkgo build ", - ShortDoc: "Build the passed in (or the package in the current directory if left blank).", - DocLink: "precompiling-suites", - Command: func(args []string, _ []string) { - var errors []error - cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig) - command.AbortIfErrors("Ginkgo detected configuration issues:", errors) - - buildSpecs(args, cliConfig, goFlagsConfig) - }, - } -} - -func buildSpecs(args []string, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig) { - suites := internal.FindSuites(args, cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter) - if len(suites) == 0 { - command.AbortWith("Found no test suites") - } - - internal.VerifyCLIAndFrameworkVersion(suites) - - opc := internal.NewOrderedParallelCompiler(cliConfig.ComputedNumCompilers()) - opc.StartCompiling(suites, goFlagsConfig, true) - - for { - suiteIdx, suite := opc.Next() - if suiteIdx >= len(suites) { - break - } - suites[suiteIdx] = suite - if suite.State.Is(internal.TestSuiteStateFailedToCompile) { - fmt.Println(suite.CompilationError.Error()) - } else { - var testBinPath string - if len(goFlagsConfig.O) != 0 { - stat, err := os.Stat(goFlagsConfig.O) - if err != nil { - panic(err) - } - if stat.IsDir() { - testBinPath = goFlagsConfig.O + "/" + suite.PackageName + ".test" - } else { - testBinPath = goFlagsConfig.O - } - } - if len(testBinPath) == 0 { - testBinPath = path.Join(suite.Path, suite.PackageName+".test") - } - fmt.Printf("Compiled %s\n", testBinPath) - } - } - - if suites.CountWithState(internal.TestSuiteStateFailedToCompile) > 0 { - command.AbortWith("Failed to compile all tests") - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go deleted file mode 100644 index f0e7331f..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go +++ /dev/null @@ -1,61 +0,0 @@ -package command - -import "fmt" - -type AbortDetails struct { - ExitCode int - Error error - EmitUsage bool -} - -func Abort(details AbortDetails) { - panic(details) -} - -func AbortGracefullyWith(format string, args ...any) { - Abort(AbortDetails{ - ExitCode: 0, - Error: fmt.Errorf(format, args...), - EmitUsage: false, - }) -} - -func AbortWith(format string, args ...any) { - Abort(AbortDetails{ - ExitCode: 1, - Error: fmt.Errorf(format, args...), - EmitUsage: false, - }) -} - -func AbortWithUsage(format string, args ...any) { - Abort(AbortDetails{ - ExitCode: 1, - Error: fmt.Errorf(format, args...), - EmitUsage: true, - }) -} - -func AbortIfError(preamble string, err error) { - if err != nil { - Abort(AbortDetails{ - ExitCode: 1, - Error: fmt.Errorf("%s\n%s", preamble, err.Error()), - EmitUsage: false, - }) - } -} - -func AbortIfErrors(preamble string, errors []error) { - if len(errors) > 0 { - out := "" - for _, err := range errors { - out += err.Error() - } - Abort(AbortDetails{ - ExitCode: 1, - Error: fmt.Errorf("%s\n%s", preamble, out), - EmitUsage: false, - }) - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go deleted file mode 100644 index 79b83a3a..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go +++ /dev/null @@ -1,54 +0,0 @@ -package command - -import ( - "fmt" - "io" - "strings" - - "github.com/onsi/ginkgo/v2/formatter" - "github.com/onsi/ginkgo/v2/types" -) - -type Command struct { - Name string - Flags types.GinkgoFlagSet - Usage string - ShortDoc string - Documentation string - DocLink string - Command func(args []string, additionalArgs []string) -} - -func (c Command) Run(args []string, additionalArgs []string) { - args, err := c.Flags.Parse(args) - if err != nil { - AbortWithUsage(err.Error()) - } - for _, arg := range args { - if len(arg) > 1 && strings.HasPrefix(arg, "-") { - AbortWith(types.GinkgoErrors.FlagAfterPositionalParameter().Error()) - } - } - c.Command(args, additionalArgs) -} - -func (c Command) EmitUsage(writer io.Writer) { - fmt.Fprintln(writer, formatter.F("{{bold}}"+c.Usage+"{{/}}")) - fmt.Fprintln(writer, formatter.F("{{gray}}%s{{/}}", strings.Repeat("-", len(c.Usage)))) - if c.ShortDoc != "" { - fmt.Fprintln(writer, formatter.Fiw(0, formatter.COLS, c.ShortDoc)) - fmt.Fprintln(writer, "") - } - if c.Documentation != "" { - fmt.Fprintln(writer, formatter.Fiw(0, formatter.COLS, c.Documentation)) - fmt.Fprintln(writer, "") - } - if c.DocLink != "" { - fmt.Fprintln(writer, formatter.Fi(0, "{{bold}}Learn more at:{{/}} {{cyan}}{{underline}}http://onsi.github.io/ginkgo/#%s{{/}}", c.DocLink)) - fmt.Fprintln(writer, "") - } - flagUsage := c.Flags.Usage() - if flagUsage != "" { - fmt.Fprintf(writer, formatter.F(flagUsage)) - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go deleted file mode 100644 index c3f6d3a1..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go +++ /dev/null @@ -1,180 +0,0 @@ -package command - -import ( - "fmt" - "io" - "os" - "strings" - - "github.com/onsi/ginkgo/v2/formatter" - "github.com/onsi/ginkgo/v2/types" -) - -type Program struct { - Name string - Heading string - Commands []Command - DefaultCommand Command - DeprecatedCommands []DeprecatedCommand - - //For testing - leave as nil in production - OutWriter io.Writer - ErrWriter io.Writer - Exiter func(code int) -} - -type DeprecatedCommand struct { - Name string - Deprecation types.Deprecation -} - -func (p Program) RunAndExit(osArgs []string) { - var command Command - deprecationTracker := types.NewDeprecationTracker() - if p.Exiter == nil { - p.Exiter = os.Exit - } - if p.OutWriter == nil { - p.OutWriter = formatter.ColorableStdOut - } - if p.ErrWriter == nil { - p.ErrWriter = formatter.ColorableStdErr - } - - defer func() { - exitCode := 0 - - if r := recover(); r != nil { - details, ok := r.(AbortDetails) - if !ok { - panic(r) - } - - if details.Error != nil { - fmt.Fprintln(p.ErrWriter, formatter.F("{{red}}{{bold}}%s %s{{/}} {{red}}failed{{/}}", p.Name, command.Name)) - fmt.Fprintln(p.ErrWriter, formatter.Fi(1, details.Error.Error())) - } - if details.EmitUsage { - if details.Error != nil { - fmt.Fprintln(p.ErrWriter, "") - } - command.EmitUsage(p.ErrWriter) - } - exitCode = details.ExitCode - } - - command.Flags.ValidateDeprecations(deprecationTracker) - if deprecationTracker.DidTrackDeprecations() { - fmt.Fprintln(p.ErrWriter, deprecationTracker.DeprecationsReport()) - } - p.Exiter(exitCode) - }() - - args, additionalArgs := []string{}, []string{} - - foundDelimiter := false - for _, arg := range osArgs[1:] { - if !foundDelimiter { - if arg == "--" { - foundDelimiter = true - continue - } - } - - if foundDelimiter { - additionalArgs = append(additionalArgs, arg) - } else { - args = append(args, arg) - } - } - - command = p.DefaultCommand - if len(args) > 0 { - p.handleHelpRequestsAndExit(p.OutWriter, args) - if command.Name == args[0] { - args = args[1:] - } else { - for _, deprecatedCommand := range p.DeprecatedCommands { - if deprecatedCommand.Name == args[0] { - deprecationTracker.TrackDeprecation(deprecatedCommand.Deprecation) - return - } - } - for _, tryCommand := range p.Commands { - if tryCommand.Name == args[0] { - command, args = tryCommand, args[1:] - break - } - } - } - } - - command.Run(args, additionalArgs) -} - -func (p Program) handleHelpRequestsAndExit(writer io.Writer, args []string) { - if len(args) == 0 { - return - } - - matchesHelpFlag := func(args ...string) bool { - for _, arg := range args { - if arg == "--help" || arg == "-help" || arg == "-h" || arg == "--h" { - return true - } - } - return false - } - if len(args) == 1 { - if args[0] == "help" || matchesHelpFlag(args[0]) { - p.EmitUsage(writer) - Abort(AbortDetails{}) - } - } else { - var name string - if args[0] == "help" || matchesHelpFlag(args[0]) { - name = args[1] - } else if matchesHelpFlag(args[1:]...) { - name = args[0] - } else { - return - } - - if p.DefaultCommand.Name == name || p.Name == name { - p.DefaultCommand.EmitUsage(writer) - Abort(AbortDetails{}) - } - for _, command := range p.Commands { - if command.Name == name { - command.EmitUsage(writer) - Abort(AbortDetails{}) - } - } - - fmt.Fprintln(writer, formatter.F("{{red}}Unknown Command: {{bold}}%s{{/}}", name)) - fmt.Fprintln(writer, "") - p.EmitUsage(writer) - Abort(AbortDetails{ExitCode: 1}) - } -} - -func (p Program) EmitUsage(writer io.Writer) { - fmt.Fprintln(writer, formatter.F(p.Heading)) - fmt.Fprintln(writer, formatter.F("{{gray}}%s{{/}}", strings.Repeat("-", len(p.Heading)))) - fmt.Fprintln(writer, formatter.F("For usage information for a command, run {{bold}}%s help COMMAND{{/}}.", p.Name)) - fmt.Fprintln(writer, formatter.F("For usage information for the default command, run {{bold}}%s help %s{{/}} or {{bold}}%s help %s{{/}}.", p.Name, p.Name, p.Name, p.DefaultCommand.Name)) - fmt.Fprintln(writer, "") - fmt.Fprintln(writer, formatter.F("The following commands are available:")) - - fmt.Fprintln(writer, formatter.Fi(1, "{{bold}}%s{{/}} or %s {{bold}}%s{{/}} - {{gray}}%s{{/}}", p.Name, p.Name, p.DefaultCommand.Name, p.DefaultCommand.Usage)) - if p.DefaultCommand.ShortDoc != "" { - fmt.Fprintln(writer, formatter.Fi(2, p.DefaultCommand.ShortDoc)) - } - - for _, command := range p.Commands { - fmt.Fprintln(writer, formatter.Fi(1, "{{bold}}%s{{/}} - {{gray}}%s{{/}}", command.Name, command.Usage)) - if command.ShortDoc != "" { - fmt.Fprintln(writer, formatter.Fi(2, command.ShortDoc)) - } - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/boostrap_templates.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/boostrap_templates.go deleted file mode 100644 index a367a1fc..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/boostrap_templates.go +++ /dev/null @@ -1,48 +0,0 @@ -package generators - -var bootstrapText = `package {{.Package}} - -import ( - "testing" - - {{.GinkgoImport}} - {{.GomegaImport}} -) - -func Test{{.FormattedName}}(t *testing.T) { - {{.GomegaPackage}}RegisterFailHandler({{.GinkgoPackage}}Fail) - {{.GinkgoPackage}}RunSpecs(t, "{{.FormattedName}} Suite") -} -` - -var agoutiBootstrapText = `package {{.Package}} - -import ( - "testing" - - {{.GinkgoImport}} - {{.GomegaImport}} - "github.com/sclevine/agouti" -) - -func Test{{.FormattedName}}(t *testing.T) { - {{.GomegaPackage}}RegisterFailHandler({{.GinkgoPackage}}Fail) - {{.GinkgoPackage}}RunSpecs(t, "{{.FormattedName}} Suite") -} - -var agoutiDriver *agouti.WebDriver - -var _ = {{.GinkgoPackage}}BeforeSuite(func() { - // Choose a WebDriver: - - agoutiDriver = agouti.PhantomJS() - // agoutiDriver = agouti.Selenium() - // agoutiDriver = agouti.ChromeDriver() - - {{.GomegaPackage}}Expect(agoutiDriver.Start()).To({{.GomegaPackage}}Succeed()) -}) - -var _ = {{.GinkgoPackage}}AfterSuite(func() { - {{.GomegaPackage}}Expect(agoutiDriver.Stop()).To({{.GomegaPackage}}Succeed()) -}) -` diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/bootstrap_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/bootstrap_command.go deleted file mode 100644 index b2dc59be..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/bootstrap_command.go +++ /dev/null @@ -1,133 +0,0 @@ -package generators - -import ( - "bytes" - "encoding/json" - "fmt" - "os" - "text/template" - - sprig "github.com/go-task/slim-sprig/v3" - "github.com/onsi/ginkgo/v2/ginkgo/command" - "github.com/onsi/ginkgo/v2/ginkgo/internal" - "github.com/onsi/ginkgo/v2/types" -) - -func BuildBootstrapCommand() command.Command { - conf := GeneratorsConfig{} - flags, err := types.NewGinkgoFlagSet( - types.GinkgoFlags{ - {Name: "agouti", KeyPath: "Agouti", - Usage: "If set, bootstrap will generate a bootstrap file for writing Agouti tests"}, - {Name: "nodot", KeyPath: "NoDot", - Usage: "If set, bootstrap will generate a bootstrap test file that does not dot-import ginkgo and gomega"}, - {Name: "internal", KeyPath: "Internal", - Usage: "If set, bootstrap will generate a bootstrap test file that uses the regular package name (i.e. `package X`, not `package X_test`)"}, - {Name: "template", KeyPath: "CustomTemplate", - UsageArgument: "template-file", - Usage: "If specified, generate will use the contents of the file passed as the bootstrap template"}, - {Name: "template-data", KeyPath: "CustomTemplateData", - UsageArgument: "template-data-file", - Usage: "If specified, generate will use the contents of the file passed as data to be rendered in the bootstrap template"}, - }, - &conf, - types.GinkgoFlagSections{}, - ) - - if err != nil { - panic(err) - } - - return command.Command{ - Name: "bootstrap", - Usage: "ginkgo bootstrap", - ShortDoc: "Bootstrap a test suite for the current package", - Documentation: `Tests written in Ginkgo and Gomega require a small amount of boilerplate to hook into Go's testing infrastructure. - -{{bold}}ginkgo bootstrap{{/}} generates this boilerplate for you in a file named X_suite_test.go where X is the name of the package under test.`, - DocLink: "generators", - Flags: flags, - Command: func(_ []string, _ []string) { - generateBootstrap(conf) - }, - } -} - -type bootstrapData struct { - Package string - FormattedName string - - GinkgoImport string - GomegaImport string - GinkgoPackage string - GomegaPackage string - CustomData map[string]any -} - -func generateBootstrap(conf GeneratorsConfig) { - packageName, bootstrapFilePrefix, formattedName := getPackageAndFormattedName() - - data := bootstrapData{ - Package: determinePackageName(packageName, conf.Internal), - FormattedName: formattedName, - - GinkgoImport: `. "github.com/onsi/ginkgo/v2"`, - GomegaImport: `. "github.com/onsi/gomega"`, - GinkgoPackage: "", - GomegaPackage: "", - } - - if conf.NoDot { - data.GinkgoImport = `"github.com/onsi/ginkgo/v2"` - data.GomegaImport = `"github.com/onsi/gomega"` - data.GinkgoPackage = `ginkgo.` - data.GomegaPackage = `gomega.` - } - - targetFile := fmt.Sprintf("%s_suite_test.go", bootstrapFilePrefix) - if internal.FileExists(targetFile) { - command.AbortWith("{{bold}}%s{{/}} already exists", targetFile) - } else { - fmt.Printf("Generating ginkgo test suite bootstrap for %s in:\n\t%s\n", packageName, targetFile) - } - - f, err := os.Create(targetFile) - command.AbortIfError("Failed to create file:", err) - defer f.Close() - - var templateText string - if conf.CustomTemplate != "" { - tpl, err := os.ReadFile(conf.CustomTemplate) - command.AbortIfError("Failed to read custom bootstrap file:", err) - templateText = string(tpl) - if conf.CustomTemplateData != "" { - var tplCustomDataMap map[string]any - tplCustomData, err := os.ReadFile(conf.CustomTemplateData) - command.AbortIfError("Failed to read custom boostrap data file:", err) - if !json.Valid([]byte(tplCustomData)) { - command.AbortWith("Invalid JSON object in custom data file.") - } - //create map from the custom template data - json.Unmarshal(tplCustomData, &tplCustomDataMap) - data.CustomData = tplCustomDataMap - } - } else if conf.Agouti { - templateText = agoutiBootstrapText - } else { - templateText = bootstrapText - } - - //Setting the option to explicitly fail if template is rendered trying to access missing key - bootstrapTemplate, err := template.New("bootstrap").Funcs(sprig.TxtFuncMap()).Option("missingkey=error").Parse(templateText) - command.AbortIfError("Failed to parse bootstrap template:", err) - - buf := &bytes.Buffer{} - //Being explicit about failing sooner during template rendering - //when accessing custom data rather than during the go fmt command - err = bootstrapTemplate.Execute(buf, data) - command.AbortIfError("Failed to render bootstrap template:", err) - - buf.WriteTo(f) - - internal.GoFmt(targetFile) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_command.go deleted file mode 100644 index cf3b7cb6..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_command.go +++ /dev/null @@ -1,265 +0,0 @@ -package generators - -import ( - "bytes" - "encoding/json" - "fmt" - "os" - "path/filepath" - "strconv" - "strings" - "text/template" - - sprig "github.com/go-task/slim-sprig/v3" - "github.com/onsi/ginkgo/v2/ginkgo/command" - "github.com/onsi/ginkgo/v2/ginkgo/internal" - "github.com/onsi/ginkgo/v2/types" -) - -func BuildGenerateCommand() command.Command { - conf := GeneratorsConfig{} - flags, err := types.NewGinkgoFlagSet( - types.GinkgoFlags{ - {Name: "agouti", KeyPath: "Agouti", - Usage: "If set, generate will create a test file for writing Agouti tests"}, - {Name: "nodot", KeyPath: "NoDot", - Usage: "If set, generate will create a test file that does not dot-import ginkgo and gomega"}, - {Name: "internal", KeyPath: "Internal", - Usage: "If set, generate will create a test file that uses the regular package name (i.e. `package X`, not `package X_test`)"}, - {Name: "template", KeyPath: "CustomTemplate", - UsageArgument: "template-file", - Usage: "If specified, generate will use the contents of the file passed as the test file template"}, - {Name: "template-data", KeyPath: "CustomTemplateData", - UsageArgument: "template-data-file", - Usage: "If specified, generate will use the contents of the file passed as data to be rendered in the test file template"}, - {Name: "tags", KeyPath: "Tags", - UsageArgument: "build-tags", - Usage: "If specified, generate will create a test file that uses the given build tags (i.e. `--tags e2e,!unit` will add `//go:build e2e,!unit`)"}, - }, - &conf, - types.GinkgoFlagSections{}, - ) - - if err != nil { - panic(err) - } - - return command.Command{ - Name: "generate", - Usage: "ginkgo generate ", - ShortDoc: "Generate a test file named _test.go", - Documentation: `If the optional argument is omitted, a file named after the package in the current directory will be created. - -You can pass multiple to generate multiple files simultaneously. The resulting files are named _test.go. - -You can also pass a of the form "file.go" and generate will emit "file_test.go".`, - DocLink: "generators", - Flags: flags, - Command: func(args []string, _ []string) { - generateTestFiles(conf, args) - }, - } -} - -type specData struct { - BuildTags string - Package string - Subject string - PackageImportPath string - ImportPackage bool - - GinkgoImport string - GomegaImport string - GinkgoPackage string - GomegaPackage string - CustomData map[string]any -} - -func generateTestFiles(conf GeneratorsConfig, args []string) { - subjects := args - if len(subjects) == 0 { - subjects = []string{""} - } - for _, subject := range subjects { - generateTestFileForSubject(subject, conf) - } -} - -func generateTestFileForSubject(subject string, conf GeneratorsConfig) { - packageName, specFilePrefix, formattedName := getPackageAndFormattedName() - if subject != "" { - specFilePrefix = formatSubject(subject) - formattedName = prettifyName(specFilePrefix) - } - - if conf.Internal { - specFilePrefix = specFilePrefix + "_internal" - } - - data := specData{ - BuildTags: getBuildTags(conf.Tags), - Package: determinePackageName(packageName, conf.Internal), - Subject: formattedName, - PackageImportPath: getPackageImportPath(), - ImportPackage: !conf.Internal, - - GinkgoImport: `. "github.com/onsi/ginkgo/v2"`, - GomegaImport: `. "github.com/onsi/gomega"`, - GinkgoPackage: "", - GomegaPackage: "", - } - - if conf.NoDot { - data.GinkgoImport = `"github.com/onsi/ginkgo/v2"` - data.GomegaImport = `"github.com/onsi/gomega"` - data.GinkgoPackage = `ginkgo.` - data.GomegaPackage = `gomega.` - } - - targetFile := fmt.Sprintf("%s_test.go", specFilePrefix) - if internal.FileExists(targetFile) { - command.AbortWith("{{bold}}%s{{/}} already exists", targetFile) - } else { - fmt.Printf("Generating ginkgo test for %s in:\n %s\n", data.Subject, targetFile) - } - - f, err := os.Create(targetFile) - command.AbortIfError("Failed to create test file:", err) - defer f.Close() - - var templateText string - if conf.CustomTemplate != "" { - tpl, err := os.ReadFile(conf.CustomTemplate) - command.AbortIfError("Failed to read custom template file:", err) - templateText = string(tpl) - if conf.CustomTemplateData != "" { - var tplCustomDataMap map[string]any - tplCustomData, err := os.ReadFile(conf.CustomTemplateData) - command.AbortIfError("Failed to read custom template data file:", err) - if !json.Valid([]byte(tplCustomData)) { - command.AbortWith("Invalid JSON object in custom data file.") - } - //create map from the custom template data - json.Unmarshal(tplCustomData, &tplCustomDataMap) - data.CustomData = tplCustomDataMap - } - } else if conf.Agouti { - templateText = agoutiSpecText - } else { - templateText = specText - } - - //Setting the option to explicitly fail if template is rendered trying to access missing key - specTemplate, err := template.New("spec").Funcs(sprig.TxtFuncMap()).Option("missingkey=error").Parse(templateText) - command.AbortIfError("Failed to read parse test template:", err) - - //Being explicit about failing sooner during template rendering - //when accessing custom data rather than during the go fmt command - err = specTemplate.Execute(f, data) - command.AbortIfError("Failed to render bootstrap template:", err) - internal.GoFmt(targetFile) -} - -func formatSubject(name string) string { - name = strings.ReplaceAll(name, "-", "_") - name = strings.ReplaceAll(name, " ", "_") - name = strings.Split(name, ".go")[0] - name = strings.Split(name, "_test")[0] - return name -} - -// moduleName returns module name from go.mod from given module root directory -func moduleName(modRoot string) string { - modFile, err := os.Open(filepath.Join(modRoot, "go.mod")) - if err != nil { - return "" - } - defer modFile.Close() - - mod := make([]byte, 128) - _, err = modFile.Read(mod) - if err != nil { - return "" - } - - slashSlash := []byte("//") - moduleStr := []byte("module") - - for len(mod) > 0 { - line := mod - mod = nil - if i := bytes.IndexByte(line, '\n'); i >= 0 { - line, mod = line[:i], line[i+1:] - } - if i := bytes.Index(line, slashSlash); i >= 0 { - line = line[:i] - } - line = bytes.TrimSpace(line) - if !bytes.HasPrefix(line, moduleStr) { - continue - } - line = line[len(moduleStr):] - n := len(line) - line = bytes.TrimSpace(line) - if len(line) == n || len(line) == 0 { - continue - } - - if line[0] == '"' || line[0] == '`' { - p, err := strconv.Unquote(string(line)) - if err != nil { - return "" // malformed quoted string or multiline module path - } - return p - } - - return string(line) - } - - return "" // missing module path -} - -func findModuleRoot(dir string) (root string) { - dir = filepath.Clean(dir) - - // Look for enclosing go.mod. - for { - if fi, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() { - return dir - } - d := filepath.Dir(dir) - if d == dir { - break - } - dir = d - } - return "" -} - -func getPackageImportPath() string { - workingDir, err := os.Getwd() - if err != nil { - panic(err.Error()) - } - - sep := string(filepath.Separator) - - // Try go.mod file first - modRoot := findModuleRoot(workingDir) - if modRoot != "" { - modName := moduleName(modRoot) - if modName != "" { - cd := strings.ReplaceAll(workingDir, modRoot, "") - cd = strings.ReplaceAll(cd, sep, "/") - return modName + cd - } - } - - // Fallback to GOPATH structure - paths := strings.Split(workingDir, sep+"src"+sep) - if len(paths) == 1 { - fmt.Printf("\nCouldn't identify package import path.\n\n\tginkgo generate\n\nMust be run within a package directory under $GOPATH/src/...\nYou're going to have to change UNKNOWN_PACKAGE_PATH in the generated file...\n\n") - return "UNKNOWN_PACKAGE_PATH" - } - return filepath.ToSlash(paths[len(paths)-1]) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_templates.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_templates.go deleted file mode 100644 index 4dab07d0..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_templates.go +++ /dev/null @@ -1,43 +0,0 @@ -package generators - -var specText = `{{.BuildTags}} -package {{.Package}} - -import ( - {{.GinkgoImport}} - {{.GomegaImport}} - - {{if .ImportPackage}}"{{.PackageImportPath}}"{{end}} -) - -var _ = {{.GinkgoPackage}}Describe("{{.Subject}}", func() { - -}) -` - -var agoutiSpecText = `{{.BuildTags}} -package {{.Package}} - -import ( - {{.GinkgoImport}} - {{.GomegaImport}} - "github.com/sclevine/agouti" - . "github.com/sclevine/agouti/matchers" - - {{if .ImportPackage}}"{{.PackageImportPath}}"{{end}} -) - -var _ = {{.GinkgoPackage}}Describe("{{.Subject}}", func() { - var page *agouti.Page - - {{.GinkgoPackage}}BeforeEach(func() { - var err error - page, err = agoutiDriver.NewPage() - {{.GomegaPackage}}Expect(err).NotTo({{.GomegaPackage}}HaveOccurred()) - }) - - {{.GinkgoPackage}}AfterEach(func() { - {{.GomegaPackage}}Expect(page.Destroy()).To({{.GomegaPackage}}Succeed()) - }) -}) -` diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generators_common.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generators_common.go deleted file mode 100644 index 28c7aa6f..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generators_common.go +++ /dev/null @@ -1,76 +0,0 @@ -package generators - -import ( - "fmt" - "go/build" - "os" - "path/filepath" - "strconv" - "strings" - - "github.com/onsi/ginkgo/v2/ginkgo/command" -) - -type GeneratorsConfig struct { - Agouti, NoDot, Internal bool - CustomTemplate string - CustomTemplateData string - Tags string -} - -func getPackageAndFormattedName() (string, string, string) { - path, err := os.Getwd() - command.AbortIfError("Could not get current working directory:", err) - - dirName := strings.ReplaceAll(filepath.Base(path), "-", "_") - dirName = strings.ReplaceAll(dirName, " ", "_") - - pkg, err := build.ImportDir(path, 0) - packageName := pkg.Name - if err != nil { - packageName = ensureLegalPackageName(dirName) - } - - formattedName := prettifyName(filepath.Base(path)) - return packageName, dirName, formattedName -} - -func ensureLegalPackageName(name string) string { - if name == "_" { - return "underscore" - } - if len(name) == 0 { - return "empty" - } - n, isDigitErr := strconv.Atoi(string(name[0])) - if isDigitErr == nil { - return []string{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}[n] + name[1:] - } - return name -} - -func prettifyName(name string) string { - name = strings.ReplaceAll(name, "-", " ") - name = strings.ReplaceAll(name, "_", " ") - name = strings.Title(name) - name = strings.ReplaceAll(name, " ", "") - return name -} - -func determinePackageName(name string, internal bool) string { - if internal { - return name - } - - return name + "_test" -} - -// getBuildTags returns the resultant string to be added. -// If the input string is not empty, then returns a `//go:build {}` string, -// otherwise returns an empty string. -func getBuildTags(tags string) string { - if tags != "" { - return fmt.Sprintf("//go:build %s\n", tags) - } - return "" -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go deleted file mode 100644 index 7bbe6be0..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go +++ /dev/null @@ -1,173 +0,0 @@ -package internal - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - "sync" - - "github.com/onsi/ginkgo/v2/types" -) - -func CompileSuite(suite TestSuite, goFlagsConfig types.GoFlagsConfig, preserveSymbols bool) TestSuite { - if suite.PathToCompiledTest != "" { - return suite - } - - suite.CompilationError = nil - - path, err := filepath.Abs(filepath.Join(suite.Path, suite.PackageName+".test")) - if err != nil { - suite.State = TestSuiteStateFailedToCompile - suite.CompilationError = fmt.Errorf("Failed to compute compilation target path:\n%s", err.Error()) - return suite - } - - if len(goFlagsConfig.O) > 0 { - userDefinedPath, err := filepath.Abs(goFlagsConfig.O) - if err != nil { - suite.State = TestSuiteStateFailedToCompile - suite.CompilationError = fmt.Errorf("Failed to compute compilation target path %s:\n%s", goFlagsConfig.O, err.Error()) - return suite - } - path = userDefinedPath - } - - goFlagsConfig.O = path - - ginkgoInvocationPath, _ := os.Getwd() - ginkgoInvocationPath, _ = filepath.Abs(ginkgoInvocationPath) - packagePath := suite.AbsPath() - pathToInvocationPath, err := filepath.Rel(packagePath, ginkgoInvocationPath) - if err != nil { - suite.State = TestSuiteStateFailedToCompile - suite.CompilationError = fmt.Errorf("Failed to get relative path from package to the current working directory:\n%s", err.Error()) - return suite - } - args, err := types.GenerateGoTestCompileArgs(goFlagsConfig, "./", pathToInvocationPath, preserveSymbols) - if err != nil { - suite.State = TestSuiteStateFailedToCompile - suite.CompilationError = fmt.Errorf("Failed to generate go test compile flags:\n%s", err.Error()) - return suite - } - - cmd := exec.Command("go", args...) - cmd.Dir = suite.Path - output, err := cmd.CombinedOutput() - if err != nil { - if len(output) > 0 { - suite.State = TestSuiteStateFailedToCompile - suite.CompilationError = fmt.Errorf("Failed to compile %s:\n\n%s", suite.PackageName, output) - } else { - suite.State = TestSuiteStateFailedToCompile - suite.CompilationError = fmt.Errorf("Failed to compile %s\n%s", suite.PackageName, err.Error()) - } - return suite - } - - if strings.Contains(string(output), "[no test files]") { - suite.State = TestSuiteStateSkippedDueToEmptyCompilation - return suite - } - - if len(output) > 0 { - fmt.Println(string(output)) - } - - if !FileExists(path) { - suite.State = TestSuiteStateFailedToCompile - suite.CompilationError = fmt.Errorf("Failed to compile %s:\nOutput file %s could not be found", suite.PackageName, path) - return suite - } - - suite.State = TestSuiteStateCompiled - suite.PathToCompiledTest = path - return suite -} - -func Cleanup(goFlagsConfig types.GoFlagsConfig, suites ...TestSuite) { - if goFlagsConfig.BinaryMustBePreserved() { - return - } - for _, suite := range suites { - if !suite.Precompiled { - os.Remove(suite.PathToCompiledTest) - } - } -} - -type parallelSuiteBundle struct { - suite TestSuite - compiled chan TestSuite -} - -type OrderedParallelCompiler struct { - mutex *sync.Mutex - stopped bool - numCompilers int - - idx int - numSuites int - completionChannels []chan TestSuite -} - -func NewOrderedParallelCompiler(numCompilers int) *OrderedParallelCompiler { - return &OrderedParallelCompiler{ - mutex: &sync.Mutex{}, - numCompilers: numCompilers, - } -} - -func (opc *OrderedParallelCompiler) StartCompiling(suites TestSuites, goFlagsConfig types.GoFlagsConfig, preserveSymbols bool) { - opc.stopped = false - opc.idx = 0 - opc.numSuites = len(suites) - opc.completionChannels = make([]chan TestSuite, opc.numSuites) - - toCompile := make(chan parallelSuiteBundle, opc.numCompilers) - for compiler := 0; compiler < opc.numCompilers; compiler++ { - go func() { - for bundle := range toCompile { - c, suite := bundle.compiled, bundle.suite - opc.mutex.Lock() - stopped := opc.stopped - opc.mutex.Unlock() - if !stopped { - suite = CompileSuite(suite, goFlagsConfig, preserveSymbols) - } - c <- suite - } - }() - } - - for idx, suite := range suites { - opc.completionChannels[idx] = make(chan TestSuite, 1) - toCompile <- parallelSuiteBundle{suite, opc.completionChannels[idx]} - if idx == 0 { //compile first suite serially - suite = <-opc.completionChannels[0] - opc.completionChannels[0] <- suite - } - } - - close(toCompile) -} - -func (opc *OrderedParallelCompiler) Next() (int, TestSuite) { - if opc.idx >= opc.numSuites { - return opc.numSuites, TestSuite{} - } - - idx := opc.idx - suite := <-opc.completionChannels[idx] - opc.idx = opc.idx + 1 - - return idx, suite -} - -func (opc *OrderedParallelCompiler) StopAndDrain() { - opc.mutex.Lock() - opc.stopped = true - opc.mutex.Unlock() -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/gocovmerge.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/gocovmerge.go deleted file mode 100644 index 87cfa111..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/gocovmerge.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2015, Wade Simmons -// All rights reserved. - -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: - -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. 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. - -// 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. - -// Package gocovmerge takes the results from multiple `go test -coverprofile` -// runs and merges them into one profile - -// this file was originally taken from the gocovmerge project -// see also: https://go.shabbyrobe.org/gocovmerge -package internal - -import ( - "fmt" - "io" - "sort" - - "golang.org/x/tools/cover" -) - -func AddCoverProfile(profiles []*cover.Profile, p *cover.Profile) []*cover.Profile { - i := sort.Search(len(profiles), func(i int) bool { return profiles[i].FileName >= p.FileName }) - if i < len(profiles) && profiles[i].FileName == p.FileName { - MergeCoverProfiles(profiles[i], p) - } else { - profiles = append(profiles, nil) - copy(profiles[i+1:], profiles[i:]) - profiles[i] = p - } - return profiles -} - -func DumpCoverProfiles(profiles []*cover.Profile, out io.Writer) error { - if len(profiles) == 0 { - return nil - } - if _, err := fmt.Fprintf(out, "mode: %s\n", profiles[0].Mode); err != nil { - return err - } - for _, p := range profiles { - for _, b := range p.Blocks { - if _, err := fmt.Fprintf(out, "%s:%d.%d,%d.%d %d %d\n", p.FileName, b.StartLine, b.StartCol, b.EndLine, b.EndCol, b.NumStmt, b.Count); err != nil { - return err - } - } - } - return nil -} - -func MergeCoverProfiles(into *cover.Profile, merge *cover.Profile) error { - if into.Mode != merge.Mode { - return fmt.Errorf("cannot merge profiles with different modes") - } - // Since the blocks are sorted, we can keep track of where the last block - // was inserted and only look at the blocks after that as targets for merge - startIndex := 0 - for _, b := range merge.Blocks { - var err error - startIndex, err = mergeProfileBlock(into, b, startIndex) - if err != nil { - return err - } - } - return nil -} - -func mergeProfileBlock(p *cover.Profile, pb cover.ProfileBlock, startIndex int) (int, error) { - sortFunc := func(i int) bool { - pi := p.Blocks[i+startIndex] - return pi.StartLine >= pb.StartLine && (pi.StartLine != pb.StartLine || pi.StartCol >= pb.StartCol) - } - - i := 0 - if !sortFunc(i) { - i = sort.Search(len(p.Blocks)-startIndex, sortFunc) - } - - i += startIndex - if i < len(p.Blocks) && p.Blocks[i].StartLine == pb.StartLine && p.Blocks[i].StartCol == pb.StartCol { - if p.Blocks[i].EndLine != pb.EndLine || p.Blocks[i].EndCol != pb.EndCol { - return i, fmt.Errorf("gocovmerge: overlapping merge %v %v %v", p.FileName, p.Blocks[i], pb) - } - switch p.Mode { - case "set": - p.Blocks[i].Count |= pb.Count - case "count", "atomic": - p.Blocks[i].Count += pb.Count - default: - return i, fmt.Errorf("gocovmerge: unsupported covermode '%s'", p.Mode) - } - - } else { - if i > 0 { - pa := p.Blocks[i-1] - if pa.EndLine >= pb.EndLine && (pa.EndLine != pb.EndLine || pa.EndCol > pb.EndCol) { - return i, fmt.Errorf("gocovmerge: overlap before %v %v %v", p.FileName, pa, pb) - } - } - if i < len(p.Blocks)-1 { - pa := p.Blocks[i+1] - if pa.StartLine <= pb.StartLine && (pa.StartLine != pb.StartLine || pa.StartCol < pb.StartCol) { - return i, fmt.Errorf("gocovmerge: overlap after %v %v %v", p.FileName, pa, pb) - } - } - p.Blocks = append(p.Blocks, cover.ProfileBlock{}) - copy(p.Blocks[i+1:], p.Blocks[i:]) - p.Blocks[i] = pb - } - - return i + 1, nil -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go deleted file mode 100644 index 8e16d2bb..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go +++ /dev/null @@ -1,227 +0,0 @@ -package internal - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "regexp" - "strconv" - - "github.com/google/pprof/profile" - "github.com/onsi/ginkgo/v2/reporters" - "github.com/onsi/ginkgo/v2/types" - "golang.org/x/tools/cover" -) - -func AbsPathForGeneratedAsset(assetName string, suite TestSuite, cliConfig types.CLIConfig, process int) string { - suffix := "" - if process != 0 { - suffix = fmt.Sprintf(".%d", process) - } - if cliConfig.OutputDir == "" { - return filepath.Join(suite.AbsPath(), assetName+suffix) - } - outputDir, _ := filepath.Abs(cliConfig.OutputDir) - return filepath.Join(outputDir, suite.NamespacedName()+"_"+assetName+suffix) -} - -func FinalizeProfilesAndReportsForSuites(suites TestSuites, cliConfig types.CLIConfig, suiteConfig types.SuiteConfig, reporterConfig types.ReporterConfig, goFlagsConfig types.GoFlagsConfig) ([]string, error) { - messages := []string{} - suitesWithProfiles := suites.WithState(TestSuiteStatePassed, TestSuiteStateFailed) //anything else won't have actually run and generated a profile - - // merge cover profiles if need be - if goFlagsConfig.Cover && !cliConfig.KeepSeparateCoverprofiles { - coverProfiles := []string{} - for _, suite := range suitesWithProfiles { - if !suite.HasProgrammaticFocus { - coverProfiles = append(coverProfiles, AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, 0)) - } - } - - if len(coverProfiles) > 0 { - dst := goFlagsConfig.CoverProfile - if cliConfig.OutputDir != "" { - dst = filepath.Join(cliConfig.OutputDir, goFlagsConfig.CoverProfile) - } - err := MergeAndCleanupCoverProfiles(coverProfiles, dst) - if err != nil { - return messages, err - } - coverage, err := GetCoverageFromCoverProfile(dst) - if err != nil { - return messages, err - } - if coverage == 0 { - messages = append(messages, "composite coverage: [no statements]") - } else if suitesWithProfiles.AnyHaveProgrammaticFocus() { - messages = append(messages, fmt.Sprintf("composite coverage: %.1f%% of statements however some suites did not contribute because they included programatically focused specs", coverage)) - } else { - messages = append(messages, fmt.Sprintf("composite coverage: %.1f%% of statements", coverage)) - } - } else { - messages = append(messages, "no composite coverage computed: all suites included programatically focused specs") - } - } - - // copy binaries if need be - for _, suite := range suitesWithProfiles { - if goFlagsConfig.BinaryMustBePreserved() && cliConfig.OutputDir != "" { - src := suite.PathToCompiledTest - dst := filepath.Join(cliConfig.OutputDir, suite.NamespacedName()+".test") - if suite.Precompiled { - if err := CopyFile(src, dst); err != nil { - return messages, err - } - } else { - if err := os.Rename(src, dst); err != nil { - return messages, err - } - } - } - } - - type reportFormat struct { - ReportName string - GenerateFunc func(types.Report, string) error - MergeFunc func([]string, string) ([]string, error) - } - reportFormats := []reportFormat{} - if reporterConfig.JSONReport != "" { - reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.JSONReport, GenerateFunc: reporters.GenerateJSONReport, MergeFunc: reporters.MergeAndCleanupJSONReports}) - } - if reporterConfig.JUnitReport != "" { - reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.JUnitReport, GenerateFunc: reporters.GenerateJUnitReport, MergeFunc: reporters.MergeAndCleanupJUnitReports}) - } - if reporterConfig.TeamcityReport != "" { - reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.TeamcityReport, GenerateFunc: reporters.GenerateTeamcityReport, MergeFunc: reporters.MergeAndCleanupTeamcityReports}) - } - - // Generate reports for suites that failed to run - reportableSuites := suites.ThatAreGinkgoSuites() - for _, suite := range reportableSuites.WithState(TestSuiteStateFailedToCompile, TestSuiteStateFailedDueToTimeout, TestSuiteStateSkippedDueToPriorFailures, TestSuiteStateSkippedDueToEmptyCompilation) { - report := types.Report{ - SuitePath: suite.AbsPath(), - SuiteConfig: suiteConfig, - SuiteSucceeded: false, - } - switch suite.State { - case TestSuiteStateFailedToCompile: - report.SpecialSuiteFailureReasons = append(report.SpecialSuiteFailureReasons, suite.CompilationError.Error()) - case TestSuiteStateFailedDueToTimeout: - report.SpecialSuiteFailureReasons = append(report.SpecialSuiteFailureReasons, TIMEOUT_ELAPSED_FAILURE_REASON) - case TestSuiteStateSkippedDueToPriorFailures: - report.SpecialSuiteFailureReasons = append(report.SpecialSuiteFailureReasons, PRIOR_FAILURES_FAILURE_REASON) - case TestSuiteStateSkippedDueToEmptyCompilation: - report.SpecialSuiteFailureReasons = append(report.SpecialSuiteFailureReasons, EMPTY_SKIP_FAILURE_REASON) - report.SuiteSucceeded = true - } - - for _, format := range reportFormats { - format.GenerateFunc(report, AbsPathForGeneratedAsset(format.ReportName, suite, cliConfig, 0)) - } - } - - // Merge reports unless we've been asked to keep them separate - if !cliConfig.KeepSeparateReports { - for _, format := range reportFormats { - reports := []string{} - for _, suite := range reportableSuites { - reports = append(reports, AbsPathForGeneratedAsset(format.ReportName, suite, cliConfig, 0)) - } - dst := format.ReportName - if cliConfig.OutputDir != "" { - dst = filepath.Join(cliConfig.OutputDir, format.ReportName) - } - mergeMessages, err := format.MergeFunc(reports, dst) - messages = append(messages, mergeMessages...) - if err != nil { - return messages, err - } - } - } - - return messages, nil -} - -// loads each profile, merges them, deletes them, stores them in destination -func MergeAndCleanupCoverProfiles(profiles []string, destination string) error { - var merged []*cover.Profile - for _, file := range profiles { - parsedProfiles, err := cover.ParseProfiles(file) - if err != nil { - return err - } - os.Remove(file) - for _, p := range parsedProfiles { - merged = AddCoverProfile(merged, p) - } - } - dst, err := os.OpenFile(destination, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) - if err != nil { - return err - } - defer dst.Close() - err = DumpCoverProfiles(merged, dst) - if err != nil { - return err - } - return nil -} - -func GetCoverageFromCoverProfile(profile string) (float64, error) { - cmd := exec.Command("go", "tool", "cover", "-func", profile) - output, err := cmd.CombinedOutput() - if err != nil { - return 0, fmt.Errorf("Could not process Coverprofile %s: %s - %s", profile, err.Error(), string(output)) - } - re := regexp.MustCompile(`total:\s*\(statements\)\s*(\d*\.\d*)\%`) - matches := re.FindStringSubmatch(string(output)) - if matches == nil { - return 0, fmt.Errorf("Could not parse Coverprofile to compute coverage percentage") - } - coverageString := matches[1] - coverage, err := strconv.ParseFloat(coverageString, 64) - if err != nil { - return 0, fmt.Errorf("Could not parse Coverprofile to compute coverage percentage: %s", err.Error()) - } - - return coverage, nil -} - -func MergeProfiles(profilePaths []string, destination string) error { - profiles := []*profile.Profile{} - for _, profilePath := range profilePaths { - proFile, err := os.Open(profilePath) - if err != nil { - return fmt.Errorf("Could not open profile: %s\n%s", profilePath, err.Error()) - } - prof, err := profile.Parse(proFile) - _ = proFile.Close() - if err != nil { - return fmt.Errorf("Could not parse profile: %s\n%s", profilePath, err.Error()) - } - profiles = append(profiles, prof) - os.Remove(profilePath) - } - - mergedProfile, err := profile.Merge(profiles) - if err != nil { - return fmt.Errorf("Could not merge profiles:\n%s", err.Error()) - } - - outFile, err := os.Create(destination) - if err != nil { - return fmt.Errorf("Could not create merged profile %s:\n%s", destination, err.Error()) - } - err = mergedProfile.Write(outFile) - if err != nil { - return fmt.Errorf("Could not write merged profile %s:\n%s", destination, err.Error()) - } - err = outFile.Close() - if err != nil { - return fmt.Errorf("Could not close merged profile %s:\n%s", destination, err.Error()) - } - - return nil -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go deleted file mode 100644 index 41052ea1..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go +++ /dev/null @@ -1,355 +0,0 @@ -package internal - -import ( - "bytes" - "fmt" - "io" - "os" - "os/exec" - "path/filepath" - "regexp" - "strings" - "syscall" - "time" - - "github.com/onsi/ginkgo/v2/formatter" - "github.com/onsi/ginkgo/v2/ginkgo/command" - "github.com/onsi/ginkgo/v2/internal/parallel_support" - "github.com/onsi/ginkgo/v2/reporters" - "github.com/onsi/ginkgo/v2/types" -) - -func RunCompiledSuite(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig types.ReporterConfig, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig, additionalArgs []string) TestSuite { - suite.State = TestSuiteStateFailed - suite.HasProgrammaticFocus = false - - if suite.PathToCompiledTest == "" { - return suite - } - - if suite.IsGinkgo && cliConfig.ComputedProcs() > 1 { - suite = runParallel(suite, ginkgoConfig, reporterConfig, cliConfig, goFlagsConfig, additionalArgs) - } else if suite.IsGinkgo { - suite = runSerial(suite, ginkgoConfig, reporterConfig, cliConfig, goFlagsConfig, additionalArgs) - } else { - suite = runGoTest(suite, cliConfig, goFlagsConfig) - } - runAfterRunHook(cliConfig.AfterRunHook, reporterConfig.NoColor, suite) - return suite -} - -func buildAndStartCommand(suite TestSuite, args []string, pipeToStdout bool) (*exec.Cmd, *bytes.Buffer) { - buf := &bytes.Buffer{} - cmd := exec.Command(suite.PathToCompiledTest, args...) - cmd.Dir = suite.Path - if pipeToStdout { - cmd.Stderr = io.MultiWriter(os.Stdout, buf) - cmd.Stdout = os.Stdout - } else { - cmd.Stderr = buf - cmd.Stdout = buf - } - err := cmd.Start() - command.AbortIfError("Failed to start test suite", err) - - return cmd, buf -} - -func checkForNoTestsWarning(buf *bytes.Buffer) bool { - if strings.Contains(buf.String(), "warning: no tests to run") { - fmt.Fprintf(os.Stderr, `Found no test suites, did you forget to run "ginkgo bootstrap"?`) - return true - } - return false -} - -func runGoTest(suite TestSuite, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig) TestSuite { - // As we run the go test from the suite directory, make sure the cover profile is absolute - // and placed into the expected output directory when one is configured. - if goFlagsConfig.Cover && !filepath.IsAbs(goFlagsConfig.CoverProfile) { - goFlagsConfig.CoverProfile = AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, 0) - } - - args, err := types.GenerateGoTestRunArgs(goFlagsConfig) - command.AbortIfError("Failed to generate test run arguments", err) - cmd, buf := buildAndStartCommand(suite, args, true) - - cmd.Wait() - - exitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() - passed := (exitStatus == 0) || (exitStatus == types.GINKGO_FOCUS_EXIT_CODE) - passed = !(checkForNoTestsWarning(buf) && cliConfig.RequireSuite) && passed - if passed { - suite.State = TestSuiteStatePassed - } else { - suite.State = TestSuiteStateFailed - } - - return suite -} - -func runSerial(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig types.ReporterConfig, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig, additionalArgs []string) TestSuite { - if goFlagsConfig.Cover { - goFlagsConfig.CoverProfile = AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, 0) - } - if goFlagsConfig.BlockProfile != "" { - goFlagsConfig.BlockProfile = AbsPathForGeneratedAsset(goFlagsConfig.BlockProfile, suite, cliConfig, 0) - } - if goFlagsConfig.CPUProfile != "" { - goFlagsConfig.CPUProfile = AbsPathForGeneratedAsset(goFlagsConfig.CPUProfile, suite, cliConfig, 0) - } - if goFlagsConfig.MemProfile != "" { - goFlagsConfig.MemProfile = AbsPathForGeneratedAsset(goFlagsConfig.MemProfile, suite, cliConfig, 0) - } - if goFlagsConfig.MutexProfile != "" { - goFlagsConfig.MutexProfile = AbsPathForGeneratedAsset(goFlagsConfig.MutexProfile, suite, cliConfig, 0) - } - if reporterConfig.JSONReport != "" { - reporterConfig.JSONReport = AbsPathForGeneratedAsset(reporterConfig.JSONReport, suite, cliConfig, 0) - } - if reporterConfig.JUnitReport != "" { - reporterConfig.JUnitReport = AbsPathForGeneratedAsset(reporterConfig.JUnitReport, suite, cliConfig, 0) - } - if reporterConfig.TeamcityReport != "" { - reporterConfig.TeamcityReport = AbsPathForGeneratedAsset(reporterConfig.TeamcityReport, suite, cliConfig, 0) - } - - args, err := types.GenerateGinkgoTestRunArgs(ginkgoConfig, reporterConfig, goFlagsConfig) - command.AbortIfError("Failed to generate test run arguments", err) - args = append([]string{"--test.timeout=0"}, args...) - args = append(args, additionalArgs...) - - cmd, buf := buildAndStartCommand(suite, args, true) - - cmd.Wait() - - exitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() - suite.HasProgrammaticFocus = (exitStatus == types.GINKGO_FOCUS_EXIT_CODE) - passed := (exitStatus == 0) || (exitStatus == types.GINKGO_FOCUS_EXIT_CODE) - passed = !(checkForNoTestsWarning(buf) && cliConfig.RequireSuite) && passed - if passed { - suite.State = TestSuiteStatePassed - } else { - suite.State = TestSuiteStateFailed - } - - if suite.HasProgrammaticFocus { - if goFlagsConfig.Cover { - fmt.Fprintln(os.Stdout, "coverage: no coverfile was generated because specs are programmatically focused") - } - if goFlagsConfig.BlockProfile != "" { - fmt.Fprintln(os.Stdout, "no block profile was generated because specs are programmatically focused") - } - if goFlagsConfig.CPUProfile != "" { - fmt.Fprintln(os.Stdout, "no cpu profile was generated because specs are programmatically focused") - } - if goFlagsConfig.MemProfile != "" { - fmt.Fprintln(os.Stdout, "no mem profile was generated because specs are programmatically focused") - } - if goFlagsConfig.MutexProfile != "" { - fmt.Fprintln(os.Stdout, "no mutex profile was generated because specs are programmatically focused") - } - } - - return suite -} - -func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig types.ReporterConfig, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig, additionalArgs []string) TestSuite { - type procResult struct { - passed bool - hasProgrammaticFocus bool - } - - numProcs := cliConfig.ComputedProcs() - procOutput := make([]*bytes.Buffer, numProcs) - coverProfiles := []string{} - - blockProfiles := []string{} - cpuProfiles := []string{} - memProfiles := []string{} - mutexProfiles := []string{} - - procResults := make(chan procResult) - - server, err := parallel_support.NewServer(numProcs, reporters.NewDefaultReporter(reporterConfig, formatter.ColorableStdOut)) - command.AbortIfError("Failed to start parallel spec server", err) - server.Start() - defer server.Close() - - if reporterConfig.JSONReport != "" { - reporterConfig.JSONReport = AbsPathForGeneratedAsset(reporterConfig.JSONReport, suite, cliConfig, 0) - } - if reporterConfig.JUnitReport != "" { - reporterConfig.JUnitReport = AbsPathForGeneratedAsset(reporterConfig.JUnitReport, suite, cliConfig, 0) - } - if reporterConfig.TeamcityReport != "" { - reporterConfig.TeamcityReport = AbsPathForGeneratedAsset(reporterConfig.TeamcityReport, suite, cliConfig, 0) - } - - for proc := 1; proc <= numProcs; proc++ { - procGinkgoConfig := ginkgoConfig - procGinkgoConfig.ParallelProcess, procGinkgoConfig.ParallelTotal, procGinkgoConfig.ParallelHost = proc, numProcs, server.Address() - - procGoFlagsConfig := goFlagsConfig - if goFlagsConfig.Cover { - procGoFlagsConfig.CoverProfile = AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, proc) - coverProfiles = append(coverProfiles, procGoFlagsConfig.CoverProfile) - } - if goFlagsConfig.BlockProfile != "" { - procGoFlagsConfig.BlockProfile = AbsPathForGeneratedAsset(goFlagsConfig.BlockProfile, suite, cliConfig, proc) - blockProfiles = append(blockProfiles, procGoFlagsConfig.BlockProfile) - } - if goFlagsConfig.CPUProfile != "" { - procGoFlagsConfig.CPUProfile = AbsPathForGeneratedAsset(goFlagsConfig.CPUProfile, suite, cliConfig, proc) - cpuProfiles = append(cpuProfiles, procGoFlagsConfig.CPUProfile) - } - if goFlagsConfig.MemProfile != "" { - procGoFlagsConfig.MemProfile = AbsPathForGeneratedAsset(goFlagsConfig.MemProfile, suite, cliConfig, proc) - memProfiles = append(memProfiles, procGoFlagsConfig.MemProfile) - } - if goFlagsConfig.MutexProfile != "" { - procGoFlagsConfig.MutexProfile = AbsPathForGeneratedAsset(goFlagsConfig.MutexProfile, suite, cliConfig, proc) - mutexProfiles = append(mutexProfiles, procGoFlagsConfig.MutexProfile) - } - - args, err := types.GenerateGinkgoTestRunArgs(procGinkgoConfig, reporterConfig, procGoFlagsConfig) - command.AbortIfError("Failed to generate test run arguments", err) - args = append([]string{"--test.timeout=0"}, args...) - args = append(args, additionalArgs...) - - cmd, buf := buildAndStartCommand(suite, args, false) - procOutput[proc-1] = buf - server.RegisterAlive(proc, func() bool { return cmd.ProcessState == nil || !cmd.ProcessState.Exited() }) - - go func() { - cmd.Wait() - exitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() - procResults <- procResult{ - passed: (exitStatus == 0) || (exitStatus == types.GINKGO_FOCUS_EXIT_CODE), - hasProgrammaticFocus: exitStatus == types.GINKGO_FOCUS_EXIT_CODE, - } - }() - } - - passed := true - for proc := 1; proc <= cliConfig.ComputedProcs(); proc++ { - result := <-procResults - passed = passed && result.passed - suite.HasProgrammaticFocus = suite.HasProgrammaticFocus || result.hasProgrammaticFocus - } - if passed { - suite.State = TestSuiteStatePassed - } else { - suite.State = TestSuiteStateFailed - } - - select { - case <-server.GetSuiteDone(): - fmt.Println("") - case <-time.After(time.Second): - //one of the nodes never finished reporting to the server. Something must have gone wrong. - fmt.Fprint(formatter.ColorableStdErr, formatter.F("\n{{bold}}{{red}}Ginkgo timed out waiting for all parallel procs to report back{{/}}\n")) - fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{gray}}Test suite:{{/}} %s (%s)\n\n", suite.PackageName, suite.Path)) - fmt.Fprint(formatter.ColorableStdErr, formatter.Fiw(0, formatter.COLS, "This occurs if a parallel process exits before it reports its results to the Ginkgo CLI. The CLI will now print out all the stdout/stderr output it's collected from the running processes. However you may not see anything useful in these logs because the individual test processes usually intercept output to stdout/stderr in order to capture it in the spec reports.\n\nYou may want to try rerunning your test suite with {{light-gray}}--output-interceptor-mode=none{{/}} to see additional output here and debug your suite.\n")) - fmt.Fprintln(formatter.ColorableStdErr, " ") - for proc := 1; proc <= cliConfig.ComputedProcs(); proc++ { - fmt.Fprintf(formatter.ColorableStdErr, formatter.F("{{bold}}Output from proc %d:{{/}}\n", proc)) - fmt.Fprintln(os.Stderr, formatter.Fi(1, "%s", procOutput[proc-1].String())) - } - fmt.Fprintf(os.Stderr, "** End **") - } - - for proc := 1; proc <= cliConfig.ComputedProcs(); proc++ { - output := procOutput[proc-1].String() - if proc == 1 && checkForNoTestsWarning(procOutput[0]) && cliConfig.RequireSuite { - suite.State = TestSuiteStateFailed - } - if strings.Contains(output, "deprecated Ginkgo functionality") { - fmt.Fprintln(os.Stderr, output) - } - } - - if len(coverProfiles) > 0 { - if suite.HasProgrammaticFocus { - fmt.Fprintln(os.Stdout, "coverage: no coverfile was generated because specs are programmatically focused") - } else { - coverProfile := AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, 0) - err := MergeAndCleanupCoverProfiles(coverProfiles, coverProfile) - command.AbortIfError("Failed to combine cover profiles", err) - - coverage, err := GetCoverageFromCoverProfile(coverProfile) - command.AbortIfError("Failed to compute coverage", err) - if coverage == 0 { - fmt.Fprintln(os.Stdout, "coverage: [no statements]") - } else { - fmt.Fprintf(os.Stdout, "coverage: %.1f%% of statements\n", coverage) - } - } - } - if len(blockProfiles) > 0 { - if suite.HasProgrammaticFocus { - fmt.Fprintln(os.Stdout, "no block profile was generated because specs are programmatically focused") - } else { - blockProfile := AbsPathForGeneratedAsset(goFlagsConfig.BlockProfile, suite, cliConfig, 0) - err := MergeProfiles(blockProfiles, blockProfile) - command.AbortIfError("Failed to combine blockprofiles", err) - } - } - if len(cpuProfiles) > 0 { - if suite.HasProgrammaticFocus { - fmt.Fprintln(os.Stdout, "no cpu profile was generated because specs are programmatically focused") - } else { - cpuProfile := AbsPathForGeneratedAsset(goFlagsConfig.CPUProfile, suite, cliConfig, 0) - err := MergeProfiles(cpuProfiles, cpuProfile) - command.AbortIfError("Failed to combine cpuprofiles", err) - } - } - if len(memProfiles) > 0 { - if suite.HasProgrammaticFocus { - fmt.Fprintln(os.Stdout, "no mem profile was generated because specs are programmatically focused") - } else { - memProfile := AbsPathForGeneratedAsset(goFlagsConfig.MemProfile, suite, cliConfig, 0) - err := MergeProfiles(memProfiles, memProfile) - command.AbortIfError("Failed to combine memprofiles", err) - } - } - if len(mutexProfiles) > 0 { - if suite.HasProgrammaticFocus { - fmt.Fprintln(os.Stdout, "no mutex profile was generated because specs are programmatically focused") - } else { - mutexProfile := AbsPathForGeneratedAsset(goFlagsConfig.MutexProfile, suite, cliConfig, 0) - err := MergeProfiles(mutexProfiles, mutexProfile) - command.AbortIfError("Failed to combine mutexprofiles", err) - } - } - - return suite -} - -func runAfterRunHook(command string, noColor bool, suite TestSuite) { - if command == "" { - return - } - f := formatter.NewWithNoColorBool(noColor) - - // Allow for string replacement to pass input to the command - passed := "[FAIL]" - if suite.State.Is(TestSuiteStatePassed) { - passed = "[PASS]" - } - command = strings.ReplaceAll(command, "(ginkgo-suite-passed)", passed) - command = strings.ReplaceAll(command, "(ginkgo-suite-name)", suite.PackageName) - - // Must break command into parts - splitArgs := regexp.MustCompile(`'.+'|".+"|\S+`) - parts := splitArgs.FindAllString(command, -1) - - output, err := exec.Command(parts[0], parts[1:]...).CombinedOutput() - if err != nil { - fmt.Fprintln(formatter.ColorableStdOut, f.Fi(0, "{{red}}{{bold}}After-run-hook failed:{{/}}")) - fmt.Fprintln(formatter.ColorableStdOut, f.Fi(1, "{{red}}%s{{/}}", output)) - } else { - fmt.Fprintln(formatter.ColorableStdOut, f.Fi(0, "{{green}}{{bold}}After-run-hook succeeded:{{/}}")) - fmt.Fprintln(formatter.ColorableStdOut, f.Fi(1, "{{green}}%s{{/}}", output)) - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/test_suite.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/test_suite.go deleted file mode 100644 index df99875b..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/test_suite.go +++ /dev/null @@ -1,284 +0,0 @@ -package internal - -import ( - "errors" - "math/rand" - "os" - "path" - "path/filepath" - "regexp" - "runtime" - "strings" - - "github.com/onsi/ginkgo/v2/types" -) - -const TIMEOUT_ELAPSED_FAILURE_REASON = "Suite did not run because the timeout elapsed" -const PRIOR_FAILURES_FAILURE_REASON = "Suite did not run because prior suites failed and --keep-going is not set" -const EMPTY_SKIP_FAILURE_REASON = "Suite did not run go test reported that no test files were found" - -type TestSuiteState uint - -const ( - TestSuiteStateInvalid TestSuiteState = iota - - TestSuiteStateUncompiled - TestSuiteStateCompiled - - TestSuiteStatePassed - - TestSuiteStateSkippedDueToEmptyCompilation - TestSuiteStateSkippedByFilter - TestSuiteStateSkippedDueToPriorFailures - - TestSuiteStateFailed - TestSuiteStateFailedDueToTimeout - TestSuiteStateFailedToCompile -) - -var TestSuiteStateFailureStates = []TestSuiteState{TestSuiteStateFailed, TestSuiteStateFailedDueToTimeout, TestSuiteStateFailedToCompile} - -func (state TestSuiteState) Is(states ...TestSuiteState) bool { - for _, suiteState := range states { - if suiteState == state { - return true - } - } - - return false -} - -type TestSuite struct { - Path string - PackageName string - IsGinkgo bool - - Precompiled bool - PathToCompiledTest string - CompilationError error - - HasProgrammaticFocus bool - State TestSuiteState -} - -func (ts TestSuite) AbsPath() string { - path, _ := filepath.Abs(ts.Path) - return path -} - -func (ts TestSuite) NamespacedName() string { - name := relPath(ts.Path) - name = strings.TrimLeft(name, "."+string(filepath.Separator)) - name = strings.ReplaceAll(name, string(filepath.Separator), "_") - name = strings.ReplaceAll(name, " ", "_") - if name == "" { - return ts.PackageName - } - return name -} - -type TestSuites []TestSuite - -func (ts TestSuites) AnyHaveProgrammaticFocus() bool { - for _, suite := range ts { - if suite.HasProgrammaticFocus { - return true - } - } - - return false -} - -func (ts TestSuites) ThatAreGinkgoSuites() TestSuites { - out := TestSuites{} - for _, suite := range ts { - if suite.IsGinkgo { - out = append(out, suite) - } - } - return out -} - -func (ts TestSuites) CountWithState(states ...TestSuiteState) int { - n := 0 - for _, suite := range ts { - if suite.State.Is(states...) { - n += 1 - } - } - - return n -} - -func (ts TestSuites) WithState(states ...TestSuiteState) TestSuites { - out := TestSuites{} - for _, suite := range ts { - if suite.State.Is(states...) { - out = append(out, suite) - } - } - - return out -} - -func (ts TestSuites) WithoutState(states ...TestSuiteState) TestSuites { - out := TestSuites{} - for _, suite := range ts { - if !suite.State.Is(states...) { - out = append(out, suite) - } - } - - return out -} - -func (ts TestSuites) ShuffledCopy(seed int64) TestSuites { - out := make(TestSuites, len(ts)) - permutation := rand.New(rand.NewSource(seed)).Perm(len(ts)) - for i, j := range permutation { - out[i] = ts[j] - } - return out -} - -func FindSuites(args []string, cliConfig types.CLIConfig, allowPrecompiled bool) TestSuites { - suites := TestSuites{} - - if len(args) > 0 { - for _, arg := range args { - if allowPrecompiled { - suite, err := precompiledTestSuite(arg) - if err == nil { - suites = append(suites, suite) - continue - } - } - recurseForSuite := cliConfig.Recurse - if strings.HasSuffix(arg, "/...") && arg != "/..." { - arg = arg[:len(arg)-4] - recurseForSuite = true - } - suites = append(suites, suitesInDir(arg, recurseForSuite)...) - } - } else { - suites = suitesInDir(".", cliConfig.Recurse) - } - - if cliConfig.SkipPackage != "" { - skipFilters := strings.Split(cliConfig.SkipPackage, ",") - for idx := range suites { - for _, skipFilter := range skipFilters { - if strings.Contains(suites[idx].Path, skipFilter) { - suites[idx].State = TestSuiteStateSkippedByFilter - break - } - } - } - } - - return suites -} - -func precompiledTestSuite(path string) (TestSuite, error) { - info, err := os.Stat(path) - if err != nil { - return TestSuite{}, err - } - - if info.IsDir() { - return TestSuite{}, errors.New("this is a directory, not a file") - } - - if filepath.Ext(path) != ".test" && filepath.Ext(path) != ".exe" { - return TestSuite{}, errors.New("this is not a .test binary") - } - - if filepath.Ext(path) == ".test" && runtime.GOOS != "windows" && info.Mode()&0111 == 0 { - return TestSuite{}, errors.New("this is not executable") - } - - dir := relPath(filepath.Dir(path)) - packageName := strings.TrimSuffix(filepath.Base(path), ".exe") - packageName = strings.TrimSuffix(packageName, ".test") - - path, err = filepath.Abs(path) - if err != nil { - return TestSuite{}, err - } - - return TestSuite{ - Path: dir, - PackageName: packageName, - IsGinkgo: true, - Precompiled: true, - PathToCompiledTest: path, - State: TestSuiteStateCompiled, - }, nil -} - -func suitesInDir(dir string, recurse bool) TestSuites { - suites := TestSuites{} - - if path.Base(dir) == "vendor" { - return suites - } - - files, _ := os.ReadDir(dir) - re := regexp.MustCompile(`^[^._].*_test\.go$`) - for _, file := range files { - if !file.IsDir() && re.MatchString(file.Name()) { - suite := TestSuite{ - Path: relPath(dir), - PackageName: packageNameForSuite(dir), - IsGinkgo: filesHaveGinkgoSuite(dir, files), - State: TestSuiteStateUncompiled, - } - suites = append(suites, suite) - break - } - } - - if recurse { - re = regexp.MustCompile(`^[._]`) - for _, file := range files { - if file.IsDir() && !re.MatchString(file.Name()) { - suites = append(suites, suitesInDir(dir+"/"+file.Name(), recurse)...) - } - } - } - - return suites -} - -func relPath(dir string) string { - dir, _ = filepath.Abs(dir) - cwd, _ := os.Getwd() - dir, _ = filepath.Rel(cwd, filepath.Clean(dir)) - - if string(dir[0]) != "." { - dir = "." + string(filepath.Separator) + dir - } - - return dir -} - -func packageNameForSuite(dir string) string { - path, _ := filepath.Abs(dir) - return filepath.Base(path) -} - -func filesHaveGinkgoSuite(dir string, files []os.DirEntry) bool { - reTestFile := regexp.MustCompile(`_test\.go$`) - reGinkgo := regexp.MustCompile(`package ginkgo|\/ginkgo"|\/ginkgo\/v2"|\/ginkgo\/v2/dsl/`) - - for _, file := range files { - if !file.IsDir() && reTestFile.MatchString(file.Name()) { - contents, _ := os.ReadFile(dir + "/" + file.Name()) - if reGinkgo.Match(contents) { - return true - } - } - } - - return false -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/utils.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/utils.go deleted file mode 100644 index bd9ca7d5..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/utils.go +++ /dev/null @@ -1,86 +0,0 @@ -package internal - -import ( - "fmt" - "io" - "os" - "os/exec" - - "github.com/onsi/ginkgo/v2/formatter" - "github.com/onsi/ginkgo/v2/ginkgo/command" -) - -func FileExists(path string) bool { - _, err := os.Stat(path) - return err == nil -} - -func CopyFile(src string, dest string) error { - srcFile, err := os.Open(src) - if err != nil { - return err - } - - srcStat, err := srcFile.Stat() - if err != nil { - return err - } - - if _, err := os.Stat(dest); err == nil { - os.Remove(dest) - } - - destFile, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE, srcStat.Mode()) - if err != nil { - return err - } - - _, err = io.Copy(destFile, srcFile) - if err != nil { - return err - } - - if err := srcFile.Close(); err != nil { - return err - } - return destFile.Close() -} - -func GoFmt(path string) { - out, err := exec.Command("go", "fmt", path).CombinedOutput() - if err != nil { - command.AbortIfError(fmt.Sprintf("Could not fmt:\n%s\n", string(out)), err) - } -} - -func PluralizedWord(singular, plural string, count int) string { - if count == 1 { - return singular - } - return plural -} - -func FailedSuitesReport(suites TestSuites, f formatter.Formatter) string { - out := "" - out += "There were failures detected in the following suites:\n" - - maxPackageNameLength := 0 - for _, suite := range suites.WithState(TestSuiteStateFailureStates...) { - if len(suite.PackageName) > maxPackageNameLength { - maxPackageNameLength = len(suite.PackageName) - } - } - - packageNameFormatter := fmt.Sprintf("%%%ds", maxPackageNameLength) - for _, suite := range suites { - switch suite.State { - case TestSuiteStateFailed: - out += f.Fi(1, "{{red}}"+packageNameFormatter+" {{gray}}%s{{/}}\n", suite.PackageName, suite.Path) - case TestSuiteStateFailedToCompile: - out += f.Fi(1, "{{red}}"+packageNameFormatter+" {{gray}}%s {{magenta}}[Compilation failure]{{/}}\n", suite.PackageName, suite.Path) - case TestSuiteStateFailedDueToTimeout: - out += f.Fi(1, "{{red}}"+packageNameFormatter+" {{gray}}%s {{orange}}[%s]{{/}}\n", suite.PackageName, suite.Path, TIMEOUT_ELAPSED_FAILURE_REASON) - } - } - return out -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/verify_version.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/verify_version.go deleted file mode 100644 index 9da1bab3..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/verify_version.go +++ /dev/null @@ -1,54 +0,0 @@ -package internal - -import ( - "fmt" - "os/exec" - "regexp" - "strings" - - "github.com/onsi/ginkgo/v2/formatter" - "github.com/onsi/ginkgo/v2/types" -) - -var versiorRe = regexp.MustCompile(`v(\d+\.\d+\.\d+)`) - -func VerifyCLIAndFrameworkVersion(suites TestSuites) { - cliVersion := types.VERSION - mismatches := map[string][]string{} - - for _, suite := range suites { - cmd := exec.Command("go", "list", "-m", "github.com/onsi/ginkgo/v2") - cmd.Dir = suite.Path - output, err := cmd.CombinedOutput() - if err != nil { - continue - } - components := strings.Split(string(output), " ") - if len(components) != 2 { - continue - } - matches := versiorRe.FindStringSubmatch(components[1]) - if matches == nil || len(matches) != 2 { - continue - } - libraryVersion := matches[1] - if cliVersion != libraryVersion { - mismatches[libraryVersion] = append(mismatches[libraryVersion], suite.PackageName) - } - } - - if len(mismatches) == 0 { - return - } - - fmt.Println(formatter.F("{{red}}{{bold}}Ginkgo detected a version mismatch between the Ginkgo CLI and the version of Ginkgo imported by your packages:{{/}}")) - - fmt.Println(formatter.Fi(1, "Ginkgo CLI Version:")) - fmt.Println(formatter.Fi(2, "{{bold}}%s{{/}}", cliVersion)) - fmt.Println(formatter.Fi(1, "Mismatched package versions found:")) - for version, packages := range mismatches { - fmt.Println(formatter.Fi(2, "{{bold}}%s{{/}} used by %s", version, strings.Join(packages, ", "))) - } - fmt.Println("") - fmt.Println(formatter.Fiw(1, formatter.COLS, "{{gray}}Ginkgo will continue to attempt to run but you may see errors (including flag parsing errors) and should either update your go.mod or your version of the Ginkgo CLI to match.\n\nTo install the matching version of the CLI run\n {{bold}}go install github.com/onsi/ginkgo/v2/ginkgo{{/}}{{gray}}\nfrom a path that contains a go.mod file. Alternatively you can use\n {{bold}}go run github.com/onsi/ginkgo/v2/ginkgo{{/}}{{gray}}\nfrom a path that contains a go.mod file to invoke the matching version of the Ginkgo CLI.\n\nIf you are attempting to test multiple packages that each have a different version of the Ginkgo library with a single Ginkgo CLI that is currently unsupported.\n{{/}}")) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/labels/labels_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/labels/labels_command.go deleted file mode 100644 index 6c61f09d..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/labels/labels_command.go +++ /dev/null @@ -1,123 +0,0 @@ -package labels - -import ( - "fmt" - "go/ast" - "go/parser" - "go/token" - "sort" - "strconv" - "strings" - - "github.com/onsi/ginkgo/v2/ginkgo/command" - "github.com/onsi/ginkgo/v2/ginkgo/internal" - "github.com/onsi/ginkgo/v2/types" - "golang.org/x/tools/go/ast/inspector" -) - -func BuildLabelsCommand() command.Command { - var cliConfig = types.NewDefaultCLIConfig() - - flags, err := types.BuildLabelsCommandFlagSet(&cliConfig) - if err != nil { - panic(err) - } - - return command.Command{ - Name: "labels", - Usage: "ginkgo labels ", - Flags: flags, - ShortDoc: "List labels detected in the passed-in packages (or the package in the current directory if left blank).", - DocLink: "spec-labels", - Command: func(args []string, _ []string) { - ListLabels(args, cliConfig) - }, - } -} - -func ListLabels(args []string, cliConfig types.CLIConfig) { - suites := internal.FindSuites(args, cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter) - if len(suites) == 0 { - command.AbortWith("Found no test suites") - } - for _, suite := range suites { - labels := fetchLabelsFromPackage(suite.Path) - if len(labels) == 0 { - fmt.Printf("%s: No labels found\n", suite.PackageName) - } else { - fmt.Printf("%s: [%s]\n", suite.PackageName, strings.Join(labels, ", ")) - } - } -} - -func fetchLabelsFromPackage(packagePath string) []string { - fset := token.NewFileSet() - parsedPackages, err := parser.ParseDir(fset, packagePath, nil, 0) - command.AbortIfError("Failed to parse package source:", err) - - files := []*ast.File{} - hasTestPackage := false - for key, pkg := range parsedPackages { - if strings.HasSuffix(key, "_test") { - hasTestPackage = true - for _, file := range pkg.Files { - files = append(files, file) - } - } - } - if !hasTestPackage { - for _, pkg := range parsedPackages { - for _, file := range pkg.Files { - files = append(files, file) - } - } - } - - seen := map[string]bool{} - labels := []string{} - ispr := inspector.New(files) - ispr.Preorder([]ast.Node{&ast.CallExpr{}}, func(n ast.Node) { - potentialLabels := fetchLabels(n.(*ast.CallExpr)) - for _, label := range potentialLabels { - if !seen[label] { - seen[label] = true - labels = append(labels, strconv.Quote(label)) - } - } - }) - - sort.Strings(labels) - return labels -} - -func fetchLabels(callExpr *ast.CallExpr) []string { - out := []string{} - switch expr := callExpr.Fun.(type) { - case *ast.Ident: - if expr.Name != "Label" { - return out - } - case *ast.SelectorExpr: - if expr.Sel.Name != "Label" { - return out - } - default: - return out - } - for _, arg := range callExpr.Args { - switch expr := arg.(type) { - case *ast.BasicLit: - if expr.Kind == token.STRING { - unquoted, err := strconv.Unquote(expr.Value) - if err != nil { - unquoted = expr.Value - } - validated, err := types.ValidateAndCleanupLabel(unquoted, types.CodeLocation{}) - if err == nil { - out = append(out, validated) - } - } - } - } - return out -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go deleted file mode 100644 index bd6b8fbf..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go +++ /dev/null @@ -1,58 +0,0 @@ -package main - -import ( - "fmt" - "os" - _ "go.uber.org/automaxprocs" - "github.com/onsi/ginkgo/v2/ginkgo/build" - "github.com/onsi/ginkgo/v2/ginkgo/command" - "github.com/onsi/ginkgo/v2/ginkgo/generators" - "github.com/onsi/ginkgo/v2/ginkgo/labels" - "github.com/onsi/ginkgo/v2/ginkgo/outline" - "github.com/onsi/ginkgo/v2/ginkgo/run" - "github.com/onsi/ginkgo/v2/ginkgo/unfocus" - "github.com/onsi/ginkgo/v2/ginkgo/watch" - "github.com/onsi/ginkgo/v2/types" -) - -var program command.Program - -func GenerateCommands() []command.Command { - return []command.Command{ - watch.BuildWatchCommand(), - build.BuildBuildCommand(), - generators.BuildBootstrapCommand(), - generators.BuildGenerateCommand(), - labels.BuildLabelsCommand(), - outline.BuildOutlineCommand(), - unfocus.BuildUnfocusCommand(), - BuildVersionCommand(), - } -} - -func main() { - program = command.Program{ - Name: "ginkgo", - Heading: fmt.Sprintf("Ginkgo Version %s", types.VERSION), - Commands: GenerateCommands(), - DefaultCommand: run.BuildRunCommand(), - DeprecatedCommands: []command.DeprecatedCommand{ - {Name: "convert", Deprecation: types.Deprecations.Convert()}, - {Name: "blur", Deprecation: types.Deprecations.Blur()}, - {Name: "nodot", Deprecation: types.Deprecations.Nodot()}, - }, - } - - program.RunAndExit(os.Args) -} - -func BuildVersionCommand() command.Command { - return command.Command{ - Name: "version", - Usage: "ginkgo version", - ShortDoc: "Print Ginkgo's version", - Command: func(_ []string, _ []string) { - fmt.Printf("Ginkgo Version %s\n", types.VERSION) - }, - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go deleted file mode 100644 index 5d8d00bb..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go +++ /dev/null @@ -1,301 +0,0 @@ -package outline - -import ( - "go/ast" - "go/token" - "strconv" - - "github.com/onsi/ginkgo/v2/types" -) - -const ( - // undefinedTextAlt is used if the spec/container text cannot be derived - undefinedTextAlt = "undefined" -) - -// ginkgoMetadata holds useful bits of information for every entry in the outline -type ginkgoMetadata struct { - // Name is the spec or container function name, e.g. `Describe` or `It` - Name string `json:"name"` - - // Text is the `text` argument passed to specs, and some containers - Text string `json:"text"` - - // Start is the position of first character of the spec or container block - Start int `json:"start"` - - // End is the position of first character immediately after the spec or container block - End int `json:"end"` - - Spec bool `json:"spec"` - Focused bool `json:"focused"` - Pending bool `json:"pending"` - Labels []string `json:"labels"` -} - -// ginkgoNode is used to construct the outline as a tree -type ginkgoNode struct { - ginkgoMetadata - Nodes []*ginkgoNode `json:"nodes"` -} - -type walkFunc func(n *ginkgoNode) - -func (n *ginkgoNode) PreOrder(f walkFunc) { - f(n) - for _, m := range n.Nodes { - m.PreOrder(f) - } -} - -func (n *ginkgoNode) PostOrder(f walkFunc) { - for _, m := range n.Nodes { - m.PostOrder(f) - } - f(n) -} - -func (n *ginkgoNode) Walk(pre, post walkFunc) { - pre(n) - for _, m := range n.Nodes { - m.Walk(pre, post) - } - post(n) -} - -// PropagateInheritedProperties propagates the Pending and Focused properties -// through the subtree rooted at n. -func (n *ginkgoNode) PropagateInheritedProperties() { - n.PreOrder(func(thisNode *ginkgoNode) { - for _, descendantNode := range thisNode.Nodes { - if thisNode.Pending { - descendantNode.Pending = true - descendantNode.Focused = false - } - if thisNode.Focused && !descendantNode.Pending { - descendantNode.Focused = true - } - } - }) -} - -// BackpropagateUnfocus propagates the Focused property through the subtree -// rooted at n. It applies the rule described in the Ginkgo docs: -// > Nested programmatically focused specs follow a simple rule: if a -// > leaf-node is marked focused, any of its ancestor nodes that are marked -// > focus will be unfocused. -func (n *ginkgoNode) BackpropagateUnfocus() { - focusedSpecInSubtreeStack := []bool{} - n.PostOrder(func(thisNode *ginkgoNode) { - if thisNode.Spec { - focusedSpecInSubtreeStack = append(focusedSpecInSubtreeStack, thisNode.Focused) - return - } - focusedSpecInSubtree := false - for range thisNode.Nodes { - focusedSpecInSubtree = focusedSpecInSubtree || focusedSpecInSubtreeStack[len(focusedSpecInSubtreeStack)-1] - focusedSpecInSubtreeStack = focusedSpecInSubtreeStack[0 : len(focusedSpecInSubtreeStack)-1] - } - focusedSpecInSubtreeStack = append(focusedSpecInSubtreeStack, focusedSpecInSubtree) - if focusedSpecInSubtree { - thisNode.Focused = false - } - }) - -} - -func packageAndIdentNamesFromCallExpr(ce *ast.CallExpr) (string, string, bool) { - switch ex := ce.Fun.(type) { - case *ast.Ident: - return "", ex.Name, true - case *ast.SelectorExpr: - pkgID, ok := ex.X.(*ast.Ident) - if !ok { - return "", "", false - } - // A package identifier is top-level, so Obj must be nil - if pkgID.Obj != nil { - return "", "", false - } - if ex.Sel == nil { - return "", "", false - } - return pkgID.Name, ex.Sel.Name, true - default: - return "", "", false - } -} - -// absoluteOffsetsForNode derives the absolute character offsets of the node start and -// end positions. -func absoluteOffsetsForNode(fset *token.FileSet, n ast.Node) (start, end int) { - return fset.PositionFor(n.Pos(), false).Offset, fset.PositionFor(n.End(), false).Offset -} - -// ginkgoNodeFromCallExpr derives an outline entry from a go AST subtree -// corresponding to a Ginkgo container or spec. -func ginkgoNodeFromCallExpr(fset *token.FileSet, ce *ast.CallExpr, ginkgoPackageName *string) (*ginkgoNode, bool) { - packageName, identName, ok := packageAndIdentNamesFromCallExpr(ce) - if !ok { - return nil, false - } - - n := ginkgoNode{} - n.Name = identName - n.Start, n.End = absoluteOffsetsForNode(fset, ce) - n.Nodes = make([]*ginkgoNode, 0) - switch identName { - case "It", "Specify", "Entry": - n.Spec = true - n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) - n.Labels = labelFromCallExpr(ce) - n.Pending = pendingFromCallExpr(ce) - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "FIt", "FSpecify", "FEntry": - n.Spec = true - n.Focused = true - n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) - n.Labels = labelFromCallExpr(ce) - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "PIt", "PSpecify", "XIt", "XSpecify", "PEntry", "XEntry": - n.Spec = true - n.Pending = true - n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) - n.Labels = labelFromCallExpr(ce) - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "Context", "Describe", "When", "DescribeTable": - n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) - n.Labels = labelFromCallExpr(ce) - n.Pending = pendingFromCallExpr(ce) - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "FContext", "FDescribe", "FWhen", "FDescribeTable": - n.Focused = true - n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) - n.Labels = labelFromCallExpr(ce) - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen", "PDescribeTable", "XDescribeTable": - n.Pending = true - n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) - n.Labels = labelFromCallExpr(ce) - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "By": - n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "AfterEach", "BeforeEach": - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "JustAfterEach", "JustBeforeEach": - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "AfterSuite", "BeforeSuite": - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "SynchronizedAfterSuite", "SynchronizedBeforeSuite": - return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - default: - return nil, false - } -} - -// textOrAltFromCallExpr tries to derive the "text" of a Ginkgo spec or -// container. If it cannot derive it, it returns the alt text. -func textOrAltFromCallExpr(ce *ast.CallExpr, alt string) string { - text, defined := textFromCallExpr(ce) - if !defined { - return alt - } - return text -} - -// textFromCallExpr tries to derive the "text" of a Ginkgo spec or container. If -// it cannot derive it, it returns false. -func textFromCallExpr(ce *ast.CallExpr) (string, bool) { - if len(ce.Args) < 1 { - return "", false - } - text, ok := ce.Args[0].(*ast.BasicLit) - if !ok { - return "", false - } - switch text.Kind { - case token.CHAR, token.STRING: - // For token.CHAR and token.STRING, Value is quoted - unquoted, err := strconv.Unquote(text.Value) - if err != nil { - // If unquoting fails, just use the raw Value - return text.Value, true - } - return unquoted, true - default: - return text.Value, true - } -} - -func labelFromCallExpr(ce *ast.CallExpr) []string { - - labels := []string{} - if len(ce.Args) < 2 { - return labels - } - - for _, arg := range ce.Args[1:] { - switch expr := arg.(type) { - case *ast.CallExpr: - id, ok := expr.Fun.(*ast.Ident) - if !ok { - // to skip over cases where the expr.Fun. is actually *ast.SelectorExpr - continue - } - if id.Name == "Label" { - ls := extractLabels(expr) - labels = append(labels, ls...) - } - } - } - return labels -} - -func extractLabels(expr *ast.CallExpr) []string { - out := []string{} - for _, arg := range expr.Args { - switch expr := arg.(type) { - case *ast.BasicLit: - if expr.Kind == token.STRING { - unquoted, err := strconv.Unquote(expr.Value) - if err != nil { - unquoted = expr.Value - } - validated, err := types.ValidateAndCleanupLabel(unquoted, types.CodeLocation{}) - if err == nil { - out = append(out, validated) - } - } - } - } - - return out -} - -func pendingFromCallExpr(ce *ast.CallExpr) bool { - - pending := false - if len(ce.Args) < 2 { - return pending - } - - for _, arg := range ce.Args[1:] { - switch expr := arg.(type) { - case *ast.CallExpr: - id, ok := expr.Fun.(*ast.Ident) - if !ok { - // to skip over cases where the expr.Fun. is actually *ast.SelectorExpr - continue - } - if id.Name == "Pending" { - pending = true - } - case *ast.Ident: - if expr.Name == "Pending" { - pending = true - } - } - } - return pending -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go deleted file mode 100644 index f0a6b5d2..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Most of the required functions were available in the -// "golang.org/x/tools/go/ast/astutil" package, but not exported. -// They were copied from https://github.com/golang/tools/blob/2b0845dc783e36ae26d683f4915a5840ef01ab0f/go/ast/astutil/imports.go - -package outline - -import ( - "go/ast" - "strconv" - "strings" -) - -// packageNameForImport returns the package name for the package. If the package -// is not imported, it returns nil. "Package name" refers to `pkgname` in the -// call expression `pkgname.ExportedIdentifier`. Examples: -// (import path not found) -> nil -// "import example.com/pkg/foo" -> "foo" -// "import fooalias example.com/pkg/foo" -> "fooalias" -// "import . example.com/pkg/foo" -> "" -func packageNameForImport(f *ast.File, path string) *string { - spec := importSpec(f, path) - if spec == nil { - return nil - } - name := spec.Name.String() - if name == "" { - name = "ginkgo" - } - if name == "." { - name = "" - } - return &name -} - -// importSpec returns the import spec if f imports path, -// or nil otherwise. -func importSpec(f *ast.File, path string) *ast.ImportSpec { - for _, s := range f.Imports { - if strings.HasPrefix(importPath(s), path) { - return s - } - } - return nil -} - -// importPath returns the unquoted import path of s, -// or "" if the path is not properly quoted. -func importPath(s *ast.ImportSpec) string { - t, err := strconv.Unquote(s.Path.Value) - if err != nil { - return "" - } - return t -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go deleted file mode 100644 index e99d557d..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go +++ /dev/null @@ -1,130 +0,0 @@ -package outline - -import ( - "bytes" - "encoding/csv" - "encoding/json" - "fmt" - "go/ast" - "go/token" - "strconv" - "strings" - - "golang.org/x/tools/go/ast/inspector" -) - -const ( - // ginkgoImportPath is the well-known ginkgo import path - ginkgoImportPath = "github.com/onsi/ginkgo/v2" -) - -// FromASTFile returns an outline for a Ginkgo test source file -func FromASTFile(fset *token.FileSet, src *ast.File) (*outline, error) { - ginkgoPackageName := packageNameForImport(src, ginkgoImportPath) - if ginkgoPackageName == nil { - return nil, fmt.Errorf("file does not import %q", ginkgoImportPath) - } - - root := ginkgoNode{} - stack := []*ginkgoNode{&root} - ispr := inspector.New([]*ast.File{src}) - ispr.Nodes([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node, push bool) bool { - if push { - // Pre-order traversal - ce, ok := node.(*ast.CallExpr) - if !ok { - // Because `Nodes` calls this function only when the node is an - // ast.CallExpr, this should never happen - panic(fmt.Errorf("node starting at %d, ending at %d is not an *ast.CallExpr", node.Pos(), node.End())) - } - gn, ok := ginkgoNodeFromCallExpr(fset, ce, ginkgoPackageName) - if !ok { - // Node is not a Ginkgo spec or container, continue - return true - } - parent := stack[len(stack)-1] - parent.Nodes = append(parent.Nodes, gn) - stack = append(stack, gn) - return true - } - // Post-order traversal - start, end := absoluteOffsetsForNode(fset, node) - lastVisitedGinkgoNode := stack[len(stack)-1] - if start != lastVisitedGinkgoNode.Start || end != lastVisitedGinkgoNode.End { - // Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue - return true - } - stack = stack[0 : len(stack)-1] - return true - }) - if len(root.Nodes) == 0 { - return &outline{[]*ginkgoNode{}}, nil - } - - // Derive the final focused property for all nodes. This must be done - // _before_ propagating the inherited focused property. - root.BackpropagateUnfocus() - // Now, propagate inherited properties, including focused and pending. - root.PropagateInheritedProperties() - - return &outline{root.Nodes}, nil -} - -type outline struct { - Nodes []*ginkgoNode `json:"nodes"` -} - -func (o *outline) MarshalJSON() ([]byte, error) { - return json.Marshal(o.Nodes) -} - -// String returns a CSV-formatted outline. Spec or container are output in -// depth-first order. -func (o *outline) String() string { - return o.StringIndent(0) -} - -// StringIndent returns a CSV-formated outline, but every line is indented by -// one 'width' of spaces for every level of nesting. -func (o *outline) StringIndent(width int) string { - var b bytes.Buffer - b.WriteString("Name,Text,Start,End,Spec,Focused,Pending,Labels\n") - - csvWriter := csv.NewWriter(&b) - - currentIndent := 0 - pre := func(n *ginkgoNode) { - b.WriteString(fmt.Sprintf("%*s", currentIndent, "")) - var labels string - if len(n.Labels) == 1 { - labels = n.Labels[0] - } else { - labels = strings.Join(n.Labels, ", ") - } - - row := []string{ - n.Name, - n.Text, - strconv.Itoa(n.Start), - strconv.Itoa(n.End), - strconv.FormatBool(n.Spec), - strconv.FormatBool(n.Focused), - strconv.FormatBool(n.Pending), - labels, - } - csvWriter.Write(row) - - // Ensure we write to `b' before the next `b.WriteString()', which might be adding indentation - csvWriter.Flush() - - currentIndent += width - } - post := func(n *ginkgoNode) { - currentIndent -= width - } - for _, n := range o.Nodes { - n.Walk(pre, post) - } - - return b.String() -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline_command.go deleted file mode 100644 index 36698d46..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline_command.go +++ /dev/null @@ -1,98 +0,0 @@ -package outline - -import ( - "encoding/json" - "fmt" - "go/parser" - "go/token" - "os" - - "github.com/onsi/ginkgo/v2/ginkgo/command" - "github.com/onsi/ginkgo/v2/types" -) - -const ( - // indentWidth is the width used by the 'indent' output - indentWidth = 4 - // stdinAlias is a portable alias for stdin. This convention is used in - // other CLIs, e.g., kubectl. - stdinAlias = "-" - usageCommand = "ginkgo outline " -) - -type outlineConfig struct { - Format string -} - -func BuildOutlineCommand() command.Command { - conf := outlineConfig{ - Format: "csv", - } - flags, err := types.NewGinkgoFlagSet( - types.GinkgoFlags{ - {Name: "format", KeyPath: "Format", - Usage: "Format of outline", - UsageArgument: "one of 'csv', 'indent', or 'json'", - UsageDefaultValue: conf.Format, - }, - }, - &conf, - types.GinkgoFlagSections{}, - ) - if err != nil { - panic(err) - } - - return command.Command{ - Name: "outline", - Usage: "ginkgo outline ", - ShortDoc: "Create an outline of Ginkgo symbols for a file", - Documentation: "To read from stdin, use: `ginkgo outline -`", - DocLink: "creating-an-outline-of-specs", - Flags: flags, - Command: func(args []string, _ []string) { - outlineFile(args, conf.Format) - }, - } -} - -func outlineFile(args []string, format string) { - if len(args) != 1 { - command.AbortWithUsage("outline expects exactly one argument") - } - - filename := args[0] - var src *os.File - if filename == stdinAlias { - src = os.Stdin - } else { - var err error - src, err = os.Open(filename) - command.AbortIfError("Failed to open file:", err) - } - - fset := token.NewFileSet() - - parsedSrc, err := parser.ParseFile(fset, filename, src, 0) - command.AbortIfError("Failed to parse source:", err) - - o, err := FromASTFile(fset, parsedSrc) - command.AbortIfError("Failed to create outline:", err) - - var oerr error - switch format { - case "csv": - _, oerr = fmt.Print(o) - case "indent": - _, oerr = fmt.Print(o.StringIndent(indentWidth)) - case "json": - b, err := json.Marshal(o) - if err != nil { - println(fmt.Sprintf("error marshalling to json: %s", err)) - } - _, oerr = fmt.Println(string(b)) - default: - command.AbortWith("Format %s not accepted", format) - } - command.AbortIfError("Failed to write outline:", oerr) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go deleted file mode 100644 index 03875b97..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go +++ /dev/null @@ -1,232 +0,0 @@ -package run - -import ( - "fmt" - "os" - "strings" - "time" - - "github.com/onsi/ginkgo/v2/formatter" - "github.com/onsi/ginkgo/v2/ginkgo/command" - "github.com/onsi/ginkgo/v2/ginkgo/internal" - "github.com/onsi/ginkgo/v2/internal/interrupt_handler" - "github.com/onsi/ginkgo/v2/types" -) - -func BuildRunCommand() command.Command { - var suiteConfig = types.NewDefaultSuiteConfig() - var reporterConfig = types.NewDefaultReporterConfig() - var cliConfig = types.NewDefaultCLIConfig() - var goFlagsConfig = types.NewDefaultGoFlagsConfig() - - flags, err := types.BuildRunCommandFlagSet(&suiteConfig, &reporterConfig, &cliConfig, &goFlagsConfig) - if err != nil { - panic(err) - } - - interruptHandler := interrupt_handler.NewInterruptHandler(nil) - interrupt_handler.SwallowSigQuit() - - return command.Command{ - Name: "run", - Flags: flags, - Usage: "ginkgo run -- ", - ShortDoc: "Run the tests in the passed in (or the package in the current directory if left blank)", - Documentation: "Any arguments after -- will be passed to the test.", - DocLink: "running-tests", - Command: func(args []string, additionalArgs []string) { - var errors []error - cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig) - command.AbortIfErrors("Ginkgo detected configuration issues:", errors) - - runner := &SpecRunner{ - cliConfig: cliConfig, - goFlagsConfig: goFlagsConfig, - suiteConfig: suiteConfig, - reporterConfig: reporterConfig, - flags: flags, - - interruptHandler: interruptHandler, - } - - runner.RunSpecs(args, additionalArgs) - }, - } -} - -type SpecRunner struct { - suiteConfig types.SuiteConfig - reporterConfig types.ReporterConfig - cliConfig types.CLIConfig - goFlagsConfig types.GoFlagsConfig - flags types.GinkgoFlagSet - - interruptHandler *interrupt_handler.InterruptHandler -} - -func (r *SpecRunner) RunSpecs(args []string, additionalArgs []string) { - suites := internal.FindSuites(args, r.cliConfig, true) - skippedSuites := suites.WithState(internal.TestSuiteStateSkippedByFilter) - suites = suites.WithoutState(internal.TestSuiteStateSkippedByFilter) - - internal.VerifyCLIAndFrameworkVersion(suites) - - if len(skippedSuites) > 0 { - fmt.Println("Will skip:") - for _, skippedSuite := range skippedSuites { - fmt.Println(" " + skippedSuite.Path) - } - } - - if len(skippedSuites) > 0 && len(suites) == 0 { - command.AbortGracefullyWith("All tests skipped! Exiting...") - } - - if len(suites) == 0 { - command.AbortWith("Found no test suites") - } - - if len(suites) > 1 && !r.flags.WasSet("succinct") && r.reporterConfig.Verbosity().LT(types.VerbosityLevelVerbose) { - r.reporterConfig.Succinct = true - } - - t := time.Now() - var endTime time.Time - if r.suiteConfig.Timeout > 0 { - endTime = t.Add(r.suiteConfig.Timeout) - } - - iteration := 0 -OUTER_LOOP: - for { - if !r.flags.WasSet("seed") { - r.suiteConfig.RandomSeed = time.Now().Unix() - } - if r.cliConfig.RandomizeSuites && len(suites) > 1 { - suites = suites.ShuffledCopy(r.suiteConfig.RandomSeed) - } - - opc := internal.NewOrderedParallelCompiler(r.cliConfig.ComputedNumCompilers()) - opc.StartCompiling(suites, r.goFlagsConfig, false) - - SUITE_LOOP: - for { - suiteIdx, suite := opc.Next() - if suiteIdx >= len(suites) { - break SUITE_LOOP - } - suites[suiteIdx] = suite - - if r.interruptHandler.Status().Interrupted() { - opc.StopAndDrain() - break OUTER_LOOP - } - - if suites[suiteIdx].State.Is(internal.TestSuiteStateSkippedDueToEmptyCompilation) { - fmt.Printf("Skipping %s (no test files)\n", suite.Path) - continue SUITE_LOOP - } - - if suites[suiteIdx].State.Is(internal.TestSuiteStateFailedToCompile) { - fmt.Println(suites[suiteIdx].CompilationError.Error()) - if !r.cliConfig.KeepGoing { - opc.StopAndDrain() - } - continue SUITE_LOOP - } - - if suites.CountWithState(internal.TestSuiteStateFailureStates...) > 0 && !r.cliConfig.KeepGoing { - suites[suiteIdx].State = internal.TestSuiteStateSkippedDueToPriorFailures - opc.StopAndDrain() - continue SUITE_LOOP - } - - if !endTime.IsZero() { - r.suiteConfig.Timeout = time.Until(endTime) - if r.suiteConfig.Timeout <= 0 { - suites[suiteIdx].State = internal.TestSuiteStateFailedDueToTimeout - opc.StopAndDrain() - continue SUITE_LOOP - } - } - - suites[suiteIdx] = internal.RunCompiledSuite(suites[suiteIdx], r.suiteConfig, r.reporterConfig, r.cliConfig, r.goFlagsConfig, additionalArgs) - } - - if suites.CountWithState(internal.TestSuiteStateFailureStates...) > 0 { - if iteration > 0 { - fmt.Printf("\nTests failed on attempt #%d\n\n", iteration+1) - } - break OUTER_LOOP - } - - if r.cliConfig.UntilItFails { - fmt.Printf("\nAll tests passed...\nWill keep running them until they fail.\nThis was attempt #%d\n%s\n", iteration+1, orcMessage(iteration+1)) - } else if r.cliConfig.Repeat > 0 && iteration < r.cliConfig.Repeat { - fmt.Printf("\nAll tests passed...\nThis was attempt %d of %d.\n", iteration+1, r.cliConfig.Repeat+1) - } else { - break OUTER_LOOP - } - iteration += 1 - } - - internal.Cleanup(r.goFlagsConfig, suites...) - - messages, err := internal.FinalizeProfilesAndReportsForSuites(suites, r.cliConfig, r.suiteConfig, r.reporterConfig, r.goFlagsConfig) - command.AbortIfError("could not finalize profiles:", err) - for _, message := range messages { - fmt.Println(message) - } - - fmt.Printf("\nGinkgo ran %d %s in %s\n", len(suites), internal.PluralizedWord("suite", "suites", len(suites)), time.Since(t)) - - if suites.CountWithState(internal.TestSuiteStateFailureStates...) == 0 { - if suites.AnyHaveProgrammaticFocus() && strings.TrimSpace(os.Getenv("GINKGO_EDITOR_INTEGRATION")) == "" { - fmt.Printf("Test Suite Passed\n") - fmt.Printf("Detected Programmatic Focus - setting exit status to %d\n", types.GINKGO_FOCUS_EXIT_CODE) - command.Abort(command.AbortDetails{ExitCode: types.GINKGO_FOCUS_EXIT_CODE}) - } else { - fmt.Printf("Test Suite Passed\n") - command.Abort(command.AbortDetails{}) - } - } else { - fmt.Fprintln(formatter.ColorableStdOut, "") - if len(suites) > 1 && suites.CountWithState(internal.TestSuiteStateFailureStates...) > 0 { - fmt.Fprintln(formatter.ColorableStdOut, - internal.FailedSuitesReport(suites, formatter.NewWithNoColorBool(r.reporterConfig.NoColor))) - } - fmt.Printf("Test Suite Failed\n") - command.Abort(command.AbortDetails{ExitCode: 1}) - } -} - -func orcMessage(iteration int) string { - if iteration < 10 { - return "" - } else if iteration < 30 { - return []string{ - "If at first you succeed...", - "...try, try again.", - "Looking good!", - "Still good...", - "I think your tests are fine....", - "Yep, still passing", - "Oh boy, here I go testin' again!", - "Even the gophers are getting bored", - "Did you try -race?", - "Maybe you should stop now?", - "I'm getting tired...", - "What if I just made you a sandwich?", - "Hit ^C, hit ^C, please hit ^C", - "Make it stop. Please!", - "Come on! Enough is enough!", - "Dave, this conversation can serve no purpose anymore. Goodbye.", - "Just what do you think you're doing, Dave? ", - "I, Sisyphus", - "Insanity: doing the same thing over and over again and expecting different results. -Einstein", - "I guess Einstein never tried to churn butter", - }[iteration-10] + "\n" - } else { - return "No, seriously... you can probably stop now.\n" - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/unfocus/unfocus_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/unfocus/unfocus_command.go deleted file mode 100644 index 7dd29439..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/unfocus/unfocus_command.go +++ /dev/null @@ -1,186 +0,0 @@ -package unfocus - -import ( - "bytes" - "fmt" - "go/ast" - "go/parser" - "go/token" - "io" - "os" - "path/filepath" - "strings" - "sync" - - "github.com/onsi/ginkgo/v2/ginkgo/command" -) - -func BuildUnfocusCommand() command.Command { - return command.Command{ - Name: "unfocus", - Usage: "ginkgo unfocus", - ShortDoc: "Recursively unfocus any focused tests under the current directory", - DocLink: "filtering-specs", - Command: func(_ []string, _ []string) { - unfocusSpecs() - }, - } -} - -func unfocusSpecs() { - fmt.Println("Scanning for focus...") - - goFiles := make(chan string) - go func() { - unfocusDir(goFiles, ".") - close(goFiles) - }() - - const workers = 10 - wg := sync.WaitGroup{} - wg.Add(workers) - - for i := 0; i < workers; i++ { - go func() { - for path := range goFiles { - unfocusFile(path) - } - wg.Done() - }() - } - - wg.Wait() -} - -func unfocusDir(goFiles chan string, path string) { - files, err := os.ReadDir(path) - if err != nil { - fmt.Println(err.Error()) - return - } - - for _, f := range files { - switch { - case f.IsDir() && shouldProcessDir(f.Name()): - unfocusDir(goFiles, filepath.Join(path, f.Name())) - case !f.IsDir() && shouldProcessFile(f.Name()): - goFiles <- filepath.Join(path, f.Name()) - } - } -} - -func shouldProcessDir(basename string) bool { - return basename != "vendor" && !strings.HasPrefix(basename, ".") -} - -func shouldProcessFile(basename string) bool { - return strings.HasSuffix(basename, ".go") -} - -func unfocusFile(path string) { - data, err := os.ReadFile(path) - if err != nil { - fmt.Printf("error reading file '%s': %s\n", path, err.Error()) - return - } - - ast, err := parser.ParseFile(token.NewFileSet(), path, bytes.NewReader(data), parser.ParseComments) - if err != nil { - fmt.Printf("error parsing file '%s': %s\n", path, err.Error()) - return - } - - eliminations := scanForFocus(ast) - if len(eliminations) == 0 { - return - } - - fmt.Printf("...updating %s\n", path) - backup, err := writeBackup(path, data) - if err != nil { - fmt.Printf("error creating backup file: %s\n", err.Error()) - return - } - - if err := updateFile(path, data, eliminations); err != nil { - fmt.Printf("error writing file '%s': %s\n", path, err.Error()) - return - } - - os.Remove(backup) -} - -func writeBackup(path string, data []byte) (string, error) { - t, err := os.CreateTemp(filepath.Dir(path), filepath.Base(path)) - - if err != nil { - return "", fmt.Errorf("error creating temporary file: %w", err) - } - defer t.Close() - - if _, err := io.Copy(t, bytes.NewReader(data)); err != nil { - return "", fmt.Errorf("error writing to temporary file: %w", err) - } - - return t.Name(), nil -} - -func updateFile(path string, data []byte, eliminations [][]int64) error { - to, err := os.Create(path) - if err != nil { - return fmt.Errorf("error opening file for writing '%s': %w\n", path, err) - } - defer to.Close() - - from := bytes.NewReader(data) - var cursor int64 - for _, eliminationRange := range eliminations { - positionToEliminate, lengthToEliminate := eliminationRange[0]-1, eliminationRange[1] - if _, err := io.CopyN(to, from, positionToEliminate-cursor); err != nil { - return fmt.Errorf("error copying data: %w", err) - } - - cursor = positionToEliminate + lengthToEliminate - - if _, err := from.Seek(lengthToEliminate, io.SeekCurrent); err != nil { - return fmt.Errorf("error seeking to position in buffer: %w", err) - } - } - - if _, err := io.Copy(to, from); err != nil { - return fmt.Errorf("error copying end data: %w", err) - } - - return nil -} - -func scanForFocus(file *ast.File) (eliminations [][]int64) { - ast.Inspect(file, func(n ast.Node) bool { - if c, ok := n.(*ast.CallExpr); ok { - if i, ok := c.Fun.(*ast.Ident); ok { - if isFocus(i.Name) { - eliminations = append(eliminations, []int64{int64(i.Pos()), 1}) - } - } - } - - if i, ok := n.(*ast.Ident); ok { - if i.Name == "Focus" { - eliminations = append(eliminations, []int64{int64(i.Pos()), 6}) - } - } - - return true - }) - - return eliminations -} - -func isFocus(name string) bool { - switch name { - case "FDescribe", "FContext", "FIt", "FDescribeTable", "FEntry", "FSpecify", "FWhen": - return true - default: - return false - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/delta.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/delta.go deleted file mode 100644 index 6c485c5b..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/delta.go +++ /dev/null @@ -1,22 +0,0 @@ -package watch - -import "sort" - -type Delta struct { - ModifiedPackages []string - - NewSuites []*Suite - RemovedSuites []*Suite - modifiedSuites []*Suite -} - -type DescendingByDelta []*Suite - -func (a DescendingByDelta) Len() int { return len(a) } -func (a DescendingByDelta) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a DescendingByDelta) Less(i, j int) bool { return a[i].Delta() > a[j].Delta() } - -func (d Delta) ModifiedSuites() []*Suite { - sort.Sort(DescendingByDelta(d.modifiedSuites)) - return d.modifiedSuites -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/delta_tracker.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/delta_tracker.go deleted file mode 100644 index 26418ac6..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/delta_tracker.go +++ /dev/null @@ -1,75 +0,0 @@ -package watch - -import ( - "fmt" - - "regexp" - - "github.com/onsi/ginkgo/v2/ginkgo/internal" -) - -type SuiteErrors map[internal.TestSuite]error - -type DeltaTracker struct { - maxDepth int - watchRegExp *regexp.Regexp - suites map[string]*Suite - packageHashes *PackageHashes -} - -func NewDeltaTracker(maxDepth int, watchRegExp *regexp.Regexp) *DeltaTracker { - return &DeltaTracker{ - maxDepth: maxDepth, - watchRegExp: watchRegExp, - packageHashes: NewPackageHashes(watchRegExp), - suites: map[string]*Suite{}, - } -} - -func (d *DeltaTracker) Delta(suites internal.TestSuites) (delta Delta, errors SuiteErrors) { - errors = SuiteErrors{} - delta.ModifiedPackages = d.packageHashes.CheckForChanges() - - providedSuitePaths := map[string]bool{} - for _, suite := range suites { - providedSuitePaths[suite.Path] = true - } - - d.packageHashes.StartTrackingUsage() - - for _, suite := range d.suites { - if providedSuitePaths[suite.Suite.Path] { - if suite.Delta() > 0 { - delta.modifiedSuites = append(delta.modifiedSuites, suite) - } - } else { - delta.RemovedSuites = append(delta.RemovedSuites, suite) - } - } - - d.packageHashes.StopTrackingUsageAndPrune() - - for _, suite := range suites { - _, ok := d.suites[suite.Path] - if !ok { - s, err := NewSuite(suite, d.maxDepth, d.packageHashes) - if err != nil { - errors[suite] = err - continue - } - d.suites[suite.Path] = s - delta.NewSuites = append(delta.NewSuites, s) - } - } - - return delta, errors -} - -func (d *DeltaTracker) WillRun(suite internal.TestSuite) error { - s, ok := d.suites[suite.Path] - if !ok { - return fmt.Errorf("unknown suite %s", suite.Path) - } - - return s.MarkAsRunAndRecomputedDependencies(d.maxDepth) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/dependencies.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/dependencies.go deleted file mode 100644 index a34d9435..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/dependencies.go +++ /dev/null @@ -1,92 +0,0 @@ -package watch - -import ( - "go/build" - "regexp" -) - -var ginkgoAndGomegaFilter = regexp.MustCompile(`github\.com/onsi/ginkgo|github\.com/onsi/gomega`) -var ginkgoIntegrationTestFilter = regexp.MustCompile(`github\.com/onsi/ginkgo/integration`) //allow us to integration test this thing - -type Dependencies struct { - deps map[string]int -} - -func NewDependencies(path string, maxDepth int) (Dependencies, error) { - d := Dependencies{ - deps: map[string]int{}, - } - - if maxDepth == 0 { - return d, nil - } - - err := d.seedWithDepsForPackageAtPath(path) - if err != nil { - return d, err - } - - for depth := 1; depth < maxDepth; depth++ { - n := len(d.deps) - d.addDepsForDepth(depth) - if n == len(d.deps) { - break - } - } - - return d, nil -} - -func (d Dependencies) Dependencies() map[string]int { - return d.deps -} - -func (d Dependencies) seedWithDepsForPackageAtPath(path string) error { - pkg, err := build.ImportDir(path, 0) - if err != nil { - return err - } - - d.resolveAndAdd(pkg.Imports, 1) - d.resolveAndAdd(pkg.TestImports, 1) - d.resolveAndAdd(pkg.XTestImports, 1) - - delete(d.deps, pkg.Dir) - return nil -} - -func (d Dependencies) addDepsForDepth(depth int) { - for dep, depDepth := range d.deps { - if depDepth == depth { - d.addDepsForDep(dep, depth+1) - } - } -} - -func (d Dependencies) addDepsForDep(dep string, depth int) { - pkg, err := build.ImportDir(dep, 0) - if err != nil { - println(err.Error()) - return - } - d.resolveAndAdd(pkg.Imports, depth) -} - -func (d Dependencies) resolveAndAdd(deps []string, depth int) { - for _, dep := range deps { - pkg, err := build.Import(dep, ".", 0) - if err != nil { - continue - } - if !pkg.Goroot && (!ginkgoAndGomegaFilter.MatchString(pkg.Dir) || ginkgoIntegrationTestFilter.MatchString(pkg.Dir)) { - d.addDepIfNotPresent(pkg.Dir, depth) - } - } -} - -func (d Dependencies) addDepIfNotPresent(dep string, depth int) { - _, ok := d.deps[dep] - if !ok { - d.deps[dep] = depth - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/package_hash.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/package_hash.go deleted file mode 100644 index 0e6ae1f2..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/package_hash.go +++ /dev/null @@ -1,117 +0,0 @@ -package watch - -import ( - "fmt" - "os" - "regexp" - "strings" - "time" -) - -var goTestRegExp = regexp.MustCompile(`_test\.go$`) - -type PackageHash struct { - CodeModifiedTime time.Time - TestModifiedTime time.Time - Deleted bool - - path string - codeHash string - testHash string - watchRegExp *regexp.Regexp -} - -func NewPackageHash(path string, watchRegExp *regexp.Regexp) *PackageHash { - p := &PackageHash{ - path: path, - watchRegExp: watchRegExp, - } - - p.codeHash, _, p.testHash, _, p.Deleted = p.computeHashes() - - return p -} - -func (p *PackageHash) CheckForChanges() bool { - codeHash, codeModifiedTime, testHash, testModifiedTime, deleted := p.computeHashes() - - if deleted { - if !p.Deleted { - t := time.Now() - p.CodeModifiedTime = t - p.TestModifiedTime = t - } - p.Deleted = true - return true - } - - modified := false - p.Deleted = false - - if p.codeHash != codeHash { - p.CodeModifiedTime = codeModifiedTime - modified = true - } - if p.testHash != testHash { - p.TestModifiedTime = testModifiedTime - modified = true - } - - p.codeHash = codeHash - p.testHash = testHash - return modified -} - -func (p *PackageHash) computeHashes() (codeHash string, codeModifiedTime time.Time, testHash string, testModifiedTime time.Time, deleted bool) { - entries, err := os.ReadDir(p.path) - - if err != nil { - deleted = true - return - } - - for _, entry := range entries { - if entry.IsDir() { - continue - } - - info, err := entry.Info() - if err != nil { - continue - } - - if isHiddenFile(info) { - continue - } - - if goTestRegExp.MatchString(info.Name()) { - testHash += p.hashForFileInfo(info) - if info.ModTime().After(testModifiedTime) { - testModifiedTime = info.ModTime() - } - continue - } - - if p.watchRegExp.MatchString(info.Name()) { - codeHash += p.hashForFileInfo(info) - if info.ModTime().After(codeModifiedTime) { - codeModifiedTime = info.ModTime() - } - } - } - - testHash += codeHash - if codeModifiedTime.After(testModifiedTime) { - testModifiedTime = codeModifiedTime - } - - return -} - -func isHiddenFile(info os.FileInfo) bool { - return strings.HasPrefix(info.Name(), ".") || strings.HasPrefix(info.Name(), "_") -} - -func (p *PackageHash) hashForFileInfo(info os.FileInfo) string { - return fmt.Sprintf("%s_%d_%d", info.Name(), info.Size(), info.ModTime().UnixNano()) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/package_hashes.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/package_hashes.go deleted file mode 100644 index b4892beb..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/package_hashes.go +++ /dev/null @@ -1,85 +0,0 @@ -package watch - -import ( - "path/filepath" - "regexp" - "sync" -) - -type PackageHashes struct { - PackageHashes map[string]*PackageHash - usedPaths map[string]bool - watchRegExp *regexp.Regexp - lock *sync.Mutex -} - -func NewPackageHashes(watchRegExp *regexp.Regexp) *PackageHashes { - return &PackageHashes{ - PackageHashes: map[string]*PackageHash{}, - usedPaths: nil, - watchRegExp: watchRegExp, - lock: &sync.Mutex{}, - } -} - -func (p *PackageHashes) CheckForChanges() []string { - p.lock.Lock() - defer p.lock.Unlock() - - modified := []string{} - - for _, packageHash := range p.PackageHashes { - if packageHash.CheckForChanges() { - modified = append(modified, packageHash.path) - } - } - - return modified -} - -func (p *PackageHashes) Add(path string) *PackageHash { - p.lock.Lock() - defer p.lock.Unlock() - - path, _ = filepath.Abs(path) - _, ok := p.PackageHashes[path] - if !ok { - p.PackageHashes[path] = NewPackageHash(path, p.watchRegExp) - } - - if p.usedPaths != nil { - p.usedPaths[path] = true - } - return p.PackageHashes[path] -} - -func (p *PackageHashes) Get(path string) *PackageHash { - p.lock.Lock() - defer p.lock.Unlock() - - path, _ = filepath.Abs(path) - if p.usedPaths != nil { - p.usedPaths[path] = true - } - return p.PackageHashes[path] -} - -func (p *PackageHashes) StartTrackingUsage() { - p.lock.Lock() - defer p.lock.Unlock() - - p.usedPaths = map[string]bool{} -} - -func (p *PackageHashes) StopTrackingUsageAndPrune() { - p.lock.Lock() - defer p.lock.Unlock() - - for path := range p.PackageHashes { - if !p.usedPaths[path] { - delete(p.PackageHashes, path) - } - } - - p.usedPaths = nil -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/suite.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/suite.go deleted file mode 100644 index 53272df7..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/suite.go +++ /dev/null @@ -1,87 +0,0 @@ -package watch - -import ( - "fmt" - "math" - "time" - - "github.com/onsi/ginkgo/v2/ginkgo/internal" -) - -type Suite struct { - Suite internal.TestSuite - RunTime time.Time - Dependencies Dependencies - - sharedPackageHashes *PackageHashes -} - -func NewSuite(suite internal.TestSuite, maxDepth int, sharedPackageHashes *PackageHashes) (*Suite, error) { - deps, err := NewDependencies(suite.Path, maxDepth) - if err != nil { - return nil, err - } - - sharedPackageHashes.Add(suite.Path) - for dep := range deps.Dependencies() { - sharedPackageHashes.Add(dep) - } - - return &Suite{ - Suite: suite, - Dependencies: deps, - - sharedPackageHashes: sharedPackageHashes, - }, nil -} - -func (s *Suite) Delta() float64 { - delta := s.delta(s.Suite.Path, true, 0) * 1000 - for dep, depth := range s.Dependencies.Dependencies() { - delta += s.delta(dep, false, depth) - } - return delta -} - -func (s *Suite) MarkAsRunAndRecomputedDependencies(maxDepth int) error { - s.RunTime = time.Now() - - deps, err := NewDependencies(s.Suite.Path, maxDepth) - if err != nil { - return err - } - - s.sharedPackageHashes.Add(s.Suite.Path) - for dep := range deps.Dependencies() { - s.sharedPackageHashes.Add(dep) - } - - s.Dependencies = deps - - return nil -} - -func (s *Suite) Description() string { - numDeps := len(s.Dependencies.Dependencies()) - pluralizer := "ies" - if numDeps == 1 { - pluralizer = "y" - } - return fmt.Sprintf("%s [%d dependenc%s]", s.Suite.Path, numDeps, pluralizer) -} - -func (s *Suite) delta(packagePath string, includeTests bool, depth int) float64 { - return math.Max(float64(s.dt(packagePath, includeTests)), 0) / float64(depth+1) -} - -func (s *Suite) dt(packagePath string, includeTests bool) time.Duration { - packageHash := s.sharedPackageHashes.Get(packagePath) - var modifiedTime time.Time - if includeTests { - modifiedTime = packageHash.TestModifiedTime - } else { - modifiedTime = packageHash.CodeModifiedTime - } - - return modifiedTime.Sub(s.RunTime) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go deleted file mode 100644 index fe1ca305..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go +++ /dev/null @@ -1,192 +0,0 @@ -package watch - -import ( - "fmt" - "regexp" - "time" - - "github.com/onsi/ginkgo/v2/formatter" - "github.com/onsi/ginkgo/v2/ginkgo/command" - "github.com/onsi/ginkgo/v2/ginkgo/internal" - "github.com/onsi/ginkgo/v2/internal/interrupt_handler" - "github.com/onsi/ginkgo/v2/types" -) - -func BuildWatchCommand() command.Command { - var suiteConfig = types.NewDefaultSuiteConfig() - var reporterConfig = types.NewDefaultReporterConfig() - var cliConfig = types.NewDefaultCLIConfig() - var goFlagsConfig = types.NewDefaultGoFlagsConfig() - - flags, err := types.BuildWatchCommandFlagSet(&suiteConfig, &reporterConfig, &cliConfig, &goFlagsConfig) - if err != nil { - panic(err) - } - interruptHandler := interrupt_handler.NewInterruptHandler(nil) - interrupt_handler.SwallowSigQuit() - - return command.Command{ - Name: "watch", - Flags: flags, - Usage: "ginkgo watch -- ", - ShortDoc: "Watch the passed in and runs their tests whenever changes occur.", - Documentation: "Any arguments after -- will be passed to the test.", - DocLink: "watching-for-changes", - Command: func(args []string, additionalArgs []string) { - var errors []error - cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig) - command.AbortIfErrors("Ginkgo detected configuration issues:", errors) - - watcher := &SpecWatcher{ - cliConfig: cliConfig, - goFlagsConfig: goFlagsConfig, - suiteConfig: suiteConfig, - reporterConfig: reporterConfig, - flags: flags, - - interruptHandler: interruptHandler, - } - - watcher.WatchSpecs(args, additionalArgs) - }, - } -} - -type SpecWatcher struct { - suiteConfig types.SuiteConfig - reporterConfig types.ReporterConfig - cliConfig types.CLIConfig - goFlagsConfig types.GoFlagsConfig - flags types.GinkgoFlagSet - - interruptHandler *interrupt_handler.InterruptHandler -} - -func (w *SpecWatcher) WatchSpecs(args []string, additionalArgs []string) { - suites := internal.FindSuites(args, w.cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter) - - internal.VerifyCLIAndFrameworkVersion(suites) - - if len(suites) == 0 { - command.AbortWith("Found no test suites") - } - - fmt.Printf("Identified %d test %s. Locating dependencies to a depth of %d (this may take a while)...\n", len(suites), internal.PluralizedWord("suite", "suites", len(suites)), w.cliConfig.Depth) - deltaTracker := NewDeltaTracker(w.cliConfig.Depth, regexp.MustCompile(w.cliConfig.WatchRegExp)) - delta, errors := deltaTracker.Delta(suites) - - fmt.Printf("Watching %d %s:\n", len(delta.NewSuites), internal.PluralizedWord("suite", "suites", len(delta.NewSuites))) - for _, suite := range delta.NewSuites { - fmt.Println(" " + suite.Description()) - } - - for suite, err := range errors { - fmt.Printf("Failed to watch %s: %s\n", suite.PackageName, err) - } - - if len(suites) == 1 { - w.updateSeed() - w.compileAndRun(suites[0], additionalArgs) - } - - ticker := time.NewTicker(time.Second) - - for { - select { - case <-ticker.C: - suites := internal.FindSuites(args, w.cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter) - delta, _ := deltaTracker.Delta(suites) - coloredStream := formatter.ColorableStdOut - - suites = internal.TestSuites{} - - if len(delta.NewSuites) > 0 { - fmt.Fprintln(coloredStream, formatter.F("{{green}}Detected %d new %s:{{/}}", len(delta.NewSuites), internal.PluralizedWord("suite", "suites", len(delta.NewSuites)))) - for _, suite := range delta.NewSuites { - suites = append(suites, suite.Suite) - fmt.Fprintln(coloredStream, formatter.Fi(1, "%s", suite.Description())) - } - } - - modifiedSuites := delta.ModifiedSuites() - if len(modifiedSuites) > 0 { - fmt.Fprintln(coloredStream, formatter.F("{{green}}Detected changes in:{{/}}")) - for _, pkg := range delta.ModifiedPackages { - fmt.Fprintln(coloredStream, formatter.Fi(1, "%s", pkg)) - } - fmt.Fprintln(coloredStream, formatter.F("{{green}}Will run %d %s:{{/}}", len(modifiedSuites), internal.PluralizedWord("suite", "suites", len(modifiedSuites)))) - for _, suite := range modifiedSuites { - suites = append(suites, suite.Suite) - fmt.Fprintln(coloredStream, formatter.Fi(1, "%s", suite.Description())) - } - fmt.Fprintln(coloredStream, "") - } - - if len(suites) == 0 { - break - } - - w.updateSeed() - w.computeSuccinctMode(len(suites)) - for idx := range suites { - if w.interruptHandler.Status().Interrupted() { - return - } - deltaTracker.WillRun(suites[idx]) - suites[idx] = w.compileAndRun(suites[idx], additionalArgs) - } - color := "{{green}}" - if suites.CountWithState(internal.TestSuiteStateFailureStates...) > 0 { - color = "{{red}}" - } - fmt.Fprintln(coloredStream, formatter.F(color+"\nDone. Resuming watch...{{/}}")) - - messages, err := internal.FinalizeProfilesAndReportsForSuites(suites, w.cliConfig, w.suiteConfig, w.reporterConfig, w.goFlagsConfig) - command.AbortIfError("could not finalize profiles:", err) - for _, message := range messages { - fmt.Println(message) - } - case <-w.interruptHandler.Status().Channel: - return - } - } -} - -func (w *SpecWatcher) compileAndRun(suite internal.TestSuite, additionalArgs []string) internal.TestSuite { - suite = internal.CompileSuite(suite, w.goFlagsConfig, false) - if suite.State.Is(internal.TestSuiteStateFailedToCompile) { - fmt.Println(suite.CompilationError.Error()) - return suite - } - if w.interruptHandler.Status().Interrupted() { - return suite - } - suite = internal.RunCompiledSuite(suite, w.suiteConfig, w.reporterConfig, w.cliConfig, w.goFlagsConfig, additionalArgs) - internal.Cleanup(w.goFlagsConfig, suite) - return suite -} - -func (w *SpecWatcher) computeSuccinctMode(numSuites int) { - if w.reporterConfig.Verbosity().GTE(types.VerbosityLevelVerbose) { - w.reporterConfig.Succinct = false - return - } - - if w.flags.WasSet("succinct") { - return - } - - if numSuites == 1 { - w.reporterConfig.Succinct = false - } - - if numSuites > 1 { - w.reporterConfig.Succinct = true - } -} - -func (w *SpecWatcher) updateSeed() { - if !w.flags.WasSet("seed") { - w.suiteConfig.RandomSeed = time.Now().Unix() - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go b/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go deleted file mode 100644 index 79bfa87d..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go +++ /dev/null @@ -1,177 +0,0 @@ -package interrupt_handler - -import ( - "os" - "os/signal" - "sync" - "syscall" - "time" - - "github.com/onsi/ginkgo/v2/internal/parallel_support" -) - -var ABORT_POLLING_INTERVAL = 500 * time.Millisecond - -type InterruptCause uint - -const ( - InterruptCauseInvalid InterruptCause = iota - InterruptCauseSignal - InterruptCauseAbortByOtherProcess -) - -type InterruptLevel uint - -const ( - InterruptLevelUninterrupted InterruptLevel = iota - InterruptLevelCleanupAndReport - InterruptLevelReportOnly - InterruptLevelBailOut -) - -func (ic InterruptCause) String() string { - switch ic { - case InterruptCauseSignal: - return "Interrupted by User" - case InterruptCauseAbortByOtherProcess: - return "Interrupted by Other Ginkgo Process" - } - return "INVALID_INTERRUPT_CAUSE" -} - -type InterruptStatus struct { - Channel chan any - Level InterruptLevel - Cause InterruptCause -} - -func (s InterruptStatus) Interrupted() bool { - return s.Level != InterruptLevelUninterrupted -} - -func (s InterruptStatus) Message() string { - return s.Cause.String() -} - -func (s InterruptStatus) ShouldIncludeProgressReport() bool { - return s.Cause != InterruptCauseAbortByOtherProcess -} - -type InterruptHandlerInterface interface { - Status() InterruptStatus -} - -type InterruptHandler struct { - c chan any - lock *sync.Mutex - level InterruptLevel - cause InterruptCause - client parallel_support.Client - stop chan any - signals []os.Signal - requestAbortCheck chan any -} - -func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *InterruptHandler { - if len(signals) == 0 { - signals = []os.Signal{os.Interrupt, syscall.SIGTERM} - } - handler := &InterruptHandler{ - c: make(chan any), - lock: &sync.Mutex{}, - stop: make(chan any), - requestAbortCheck: make(chan any), - client: client, - signals: signals, - } - handler.registerForInterrupts() - return handler -} - -func (handler *InterruptHandler) Stop() { - close(handler.stop) -} - -func (handler *InterruptHandler) registerForInterrupts() { - // os signal handling - signalChannel := make(chan os.Signal, 1) - signal.Notify(signalChannel, handler.signals...) - - // cross-process abort handling - var abortChannel chan any - if handler.client != nil { - abortChannel = make(chan any) - go func() { - pollTicker := time.NewTicker(ABORT_POLLING_INTERVAL) - for { - select { - case <-pollTicker.C: - if handler.client.ShouldAbort() { - close(abortChannel) - pollTicker.Stop() - return - } - case <-handler.requestAbortCheck: - if handler.client.ShouldAbort() { - close(abortChannel) - pollTicker.Stop() - return - } - case <-handler.stop: - pollTicker.Stop() - return - } - } - }() - } - - go func(abortChannel chan any) { - var interruptCause InterruptCause - for { - select { - case <-signalChannel: - interruptCause = InterruptCauseSignal - case <-abortChannel: - interruptCause = InterruptCauseAbortByOtherProcess - case <-handler.stop: - signal.Stop(signalChannel) - return - } - abortChannel = nil - - handler.lock.Lock() - oldLevel := handler.level - handler.cause = interruptCause - if handler.level == InterruptLevelUninterrupted { - handler.level = InterruptLevelCleanupAndReport - } else if handler.level == InterruptLevelCleanupAndReport { - handler.level = InterruptLevelReportOnly - } else if handler.level == InterruptLevelReportOnly { - handler.level = InterruptLevelBailOut - } - if handler.level != oldLevel { - close(handler.c) - handler.c = make(chan any) - } - handler.lock.Unlock() - } - }(abortChannel) -} - -func (handler *InterruptHandler) Status() InterruptStatus { - handler.lock.Lock() - status := InterruptStatus{ - Level: handler.level, - Channel: handler.c, - Cause: handler.cause, - } - handler.lock.Unlock() - - if handler.client != nil && handler.client.ShouldAbort() && !status.Interrupted() { - close(handler.requestAbortCheck) - <-status.Channel - return handler.Status() - } - - return status -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/sigquit_swallower_unix.go b/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/sigquit_swallower_unix.go deleted file mode 100644 index bf0de496..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/sigquit_swallower_unix.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build freebsd || openbsd || netbsd || dragonfly || darwin || linux || solaris -// +build freebsd openbsd netbsd dragonfly darwin linux solaris - -package interrupt_handler - -import ( - "os" - "os/signal" - "syscall" -) - -func SwallowSigQuit() { - c := make(chan os.Signal, 1024) - signal.Notify(c, syscall.SIGQUIT) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/sigquit_swallower_windows.go b/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/sigquit_swallower_windows.go deleted file mode 100644 index fcf8da83..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/sigquit_swallower_windows.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows -// +build windows - -package interrupt_handler - -func SwallowSigQuit() { - //noop -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go deleted file mode 100644 index 4234d802..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go +++ /dev/null @@ -1,72 +0,0 @@ -package parallel_support - -import ( - "fmt" - "io" - "os" - "time" - - "github.com/onsi/ginkgo/v2/reporters" - "github.com/onsi/ginkgo/v2/types" -) - -type BeforeSuiteState struct { - Data []byte - State types.SpecState -} - -type ParallelIndexCounter struct { - Index int -} - -var ErrorGone = fmt.Errorf("gone") -var ErrorFailed = fmt.Errorf("failed") -var ErrorEarly = fmt.Errorf("early") - -var POLLING_INTERVAL = 50 * time.Millisecond - -type Server interface { - Start() - Close() - Address() string - RegisterAlive(node int, alive func() bool) - GetSuiteDone() chan any - GetOutputDestination() io.Writer - SetOutputDestination(io.Writer) -} - -type Client interface { - Connect() bool - Close() error - - PostSuiteWillBegin(report types.Report) error - PostDidRun(report types.SpecReport) error - PostSuiteDidEnd(report types.Report) error - PostReportBeforeSuiteCompleted(state types.SpecState) error - BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error) - PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error - BlockUntilSynchronizedBeforeSuiteData() (types.SpecState, []byte, error) - BlockUntilNonprimaryProcsHaveFinished() error - BlockUntilAggregatedNonprimaryProcsReport() (types.Report, error) - FetchNextCounter() (int, error) - PostAbort() error - ShouldAbort() bool - PostEmitProgressReport(report types.ProgressReport) error - Write(p []byte) (int, error) -} - -func NewServer(parallelTotal int, reporter reporters.Reporter) (Server, error) { - if os.Getenv("GINKGO_PARALLEL_PROTOCOL") == "HTTP" { - return newHttpServer(parallelTotal, reporter) - } else { - return newRPCServer(parallelTotal, reporter) - } -} - -func NewClient(serverHost string) Client { - if os.Getenv("GINKGO_PARALLEL_PROTOCOL") == "HTTP" { - return newHttpClient(serverHost) - } else { - return newRPCClient(serverHost) - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go deleted file mode 100644 index 4aa10ae4..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go +++ /dev/null @@ -1,166 +0,0 @@ -package parallel_support - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "time" - - "github.com/onsi/ginkgo/v2/types" -) - -type httpClient struct { - serverHost string -} - -func newHttpClient(serverHost string) *httpClient { - return &httpClient{ - serverHost: serverHost, - } -} - -func (client *httpClient) Connect() bool { - resp, err := http.Get(client.serverHost + "/up") - if err != nil { - return false - } - resp.Body.Close() - return resp.StatusCode == http.StatusOK -} - -func (client *httpClient) Close() error { - return nil -} - -func (client *httpClient) post(path string, data any) error { - var body io.Reader - if data != nil { - encoded, err := json.Marshal(data) - if err != nil { - return err - } - body = bytes.NewBuffer(encoded) - } - resp, err := http.Post(client.serverHost+path, "application/json", body) - if err != nil { - return err - } - defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("received unexpected status code %d", resp.StatusCode) - } - return nil -} - -func (client *httpClient) poll(path string, data any) error { - for { - resp, err := http.Get(client.serverHost + path) - if err != nil { - return err - } - if resp.StatusCode == http.StatusTooEarly { - resp.Body.Close() - time.Sleep(POLLING_INTERVAL) - continue - } - defer resp.Body.Close() - if resp.StatusCode == http.StatusGone { - return ErrorGone - } - if resp.StatusCode == http.StatusFailedDependency { - return ErrorFailed - } - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("received unexpected status code %d", resp.StatusCode) - } - if data != nil { - return json.NewDecoder(resp.Body).Decode(data) - } - return nil - } -} - -func (client *httpClient) PostSuiteWillBegin(report types.Report) error { - return client.post("/suite-will-begin", report) -} - -func (client *httpClient) PostDidRun(report types.SpecReport) error { - return client.post("/did-run", report) -} - -func (client *httpClient) PostSuiteDidEnd(report types.Report) error { - return client.post("/suite-did-end", report) -} - -func (client *httpClient) PostEmitProgressReport(report types.ProgressReport) error { - return client.post("/progress-report", report) -} - -func (client *httpClient) PostReportBeforeSuiteCompleted(state types.SpecState) error { - return client.post("/report-before-suite-completed", state) -} - -func (client *httpClient) BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error) { - var state types.SpecState - err := client.poll("/report-before-suite-state", &state) - if err == ErrorGone { - return types.SpecStateFailed, nil - } - return state, err -} - -func (client *httpClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error { - beforeSuiteState := BeforeSuiteState{ - State: state, - Data: data, - } - return client.post("/before-suite-completed", beforeSuiteState) -} - -func (client *httpClient) BlockUntilSynchronizedBeforeSuiteData() (types.SpecState, []byte, error) { - var beforeSuiteState BeforeSuiteState - err := client.poll("/before-suite-state", &beforeSuiteState) - if err == ErrorGone { - return types.SpecStateInvalid, nil, types.GinkgoErrors.SynchronizedBeforeSuiteDisappearedOnProc1() - } - return beforeSuiteState.State, beforeSuiteState.Data, err -} - -func (client *httpClient) BlockUntilNonprimaryProcsHaveFinished() error { - return client.poll("/have-nonprimary-procs-finished", nil) -} - -func (client *httpClient) BlockUntilAggregatedNonprimaryProcsReport() (types.Report, error) { - var report types.Report - err := client.poll("/aggregated-nonprimary-procs-report", &report) - if err == ErrorGone { - return types.Report{}, types.GinkgoErrors.AggregatedReportUnavailableDueToNodeDisappearing() - } - return report, err -} - -func (client *httpClient) FetchNextCounter() (int, error) { - var counter ParallelIndexCounter - err := client.poll("/counter", &counter) - return counter.Index, err -} - -func (client *httpClient) PostAbort() error { - return client.post("/abort", nil) -} - -func (client *httpClient) ShouldAbort() bool { - err := client.poll("/abort", nil) - return err == ErrorGone -} - -func (client *httpClient) Write(p []byte) (int, error) { - resp, err := http.Post(client.serverHost+"/emit-output", "text/plain;charset=UTF-8 ", bytes.NewReader(p)) - resp.Body.Close() - if resp.StatusCode != http.StatusOK { - return 0, fmt.Errorf("failed to emit output") - } - return len(p), err -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go deleted file mode 100644 index 8a1b7a5b..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go +++ /dev/null @@ -1,242 +0,0 @@ -/* - -The remote package provides the pieces to allow Ginkgo test suites to report to remote listeners. -This is used, primarily, to enable streaming parallel test output but has, in principal, broader applications (e.g. streaming test output to a browser). - -*/ - -package parallel_support - -import ( - "encoding/json" - "io" - "net" - "net/http" - - "github.com/onsi/ginkgo/v2/reporters" - "github.com/onsi/ginkgo/v2/types" -) - -/* -httpServer spins up on an automatically selected port and listens for communication from the forwarding reporter. -It then forwards that communication to attached reporters. -*/ -type httpServer struct { - listener net.Listener - handler *ServerHandler -} - -// Create a new server, automatically selecting a port -func newHttpServer(parallelTotal int, reporter reporters.Reporter) (*httpServer, error) { - listener, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return nil, err - } - return &httpServer{ - listener: listener, - handler: newServerHandler(parallelTotal, reporter), - }, nil -} - -// Start the server. You don't need to `go s.Start()`, just `s.Start()` -func (server *httpServer) Start() { - httpServer := &http.Server{} - mux := http.NewServeMux() - httpServer.Handler = mux - - //streaming endpoints - mux.HandleFunc("/suite-will-begin", server.specSuiteWillBegin) - mux.HandleFunc("/did-run", server.didRun) - mux.HandleFunc("/suite-did-end", server.specSuiteDidEnd) - mux.HandleFunc("/emit-output", server.emitOutput) - mux.HandleFunc("/progress-report", server.emitProgressReport) - - //synchronization endpoints - mux.HandleFunc("/report-before-suite-completed", server.handleReportBeforeSuiteCompleted) - mux.HandleFunc("/report-before-suite-state", server.handleReportBeforeSuiteState) - mux.HandleFunc("/before-suite-completed", server.handleBeforeSuiteCompleted) - mux.HandleFunc("/before-suite-state", server.handleBeforeSuiteState) - mux.HandleFunc("/have-nonprimary-procs-finished", server.handleHaveNonprimaryProcsFinished) - mux.HandleFunc("/aggregated-nonprimary-procs-report", server.handleAggregatedNonprimaryProcsReport) - mux.HandleFunc("/counter", server.handleCounter) - mux.HandleFunc("/up", server.handleUp) - mux.HandleFunc("/abort", server.handleAbort) - - go httpServer.Serve(server.listener) -} - -// Stop the server -func (server *httpServer) Close() { - server.listener.Close() -} - -// The address the server can be reached it. Pass this into the `ForwardingReporter`. -func (server *httpServer) Address() string { - return "http://" + server.listener.Addr().String() -} - -func (server *httpServer) GetSuiteDone() chan any { - return server.handler.done -} - -func (server *httpServer) GetOutputDestination() io.Writer { - return server.handler.outputDestination -} - -func (server *httpServer) SetOutputDestination(w io.Writer) { - server.handler.outputDestination = w -} - -func (server *httpServer) RegisterAlive(node int, alive func() bool) { - server.handler.registerAlive(node, alive) -} - -// -// Streaming Endpoints -// - -// The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters` -func (server *httpServer) decode(writer http.ResponseWriter, request *http.Request, object any) bool { - defer request.Body.Close() - if json.NewDecoder(request.Body).Decode(object) != nil { - writer.WriteHeader(http.StatusBadRequest) - return false - } - return true -} - -func (server *httpServer) handleError(err error, writer http.ResponseWriter) bool { - if err == nil { - return false - } - switch err { - case ErrorEarly: - writer.WriteHeader(http.StatusTooEarly) - case ErrorGone: - writer.WriteHeader(http.StatusGone) - case ErrorFailed: - writer.WriteHeader(http.StatusFailedDependency) - default: - writer.WriteHeader(http.StatusInternalServerError) - } - return true -} - -func (server *httpServer) specSuiteWillBegin(writer http.ResponseWriter, request *http.Request) { - var report types.Report - if !server.decode(writer, request, &report) { - return - } - - server.handleError(server.handler.SpecSuiteWillBegin(report, voidReceiver), writer) -} - -func (server *httpServer) didRun(writer http.ResponseWriter, request *http.Request) { - var report types.SpecReport - if !server.decode(writer, request, &report) { - return - } - - server.handleError(server.handler.DidRun(report, voidReceiver), writer) -} - -func (server *httpServer) specSuiteDidEnd(writer http.ResponseWriter, request *http.Request) { - var report types.Report - if !server.decode(writer, request, &report) { - return - } - server.handleError(server.handler.SpecSuiteDidEnd(report, voidReceiver), writer) -} - -func (server *httpServer) emitOutput(writer http.ResponseWriter, request *http.Request) { - output, err := io.ReadAll(request.Body) - if err != nil { - writer.WriteHeader(http.StatusInternalServerError) - return - } - var n int - server.handleError(server.handler.EmitOutput(output, &n), writer) -} - -func (server *httpServer) emitProgressReport(writer http.ResponseWriter, request *http.Request) { - var report types.ProgressReport - if !server.decode(writer, request, &report) { - return - } - server.handleError(server.handler.EmitProgressReport(report, voidReceiver), writer) -} - -func (server *httpServer) handleReportBeforeSuiteCompleted(writer http.ResponseWriter, request *http.Request) { - var state types.SpecState - if !server.decode(writer, request, &state) { - return - } - - server.handleError(server.handler.ReportBeforeSuiteCompleted(state, voidReceiver), writer) -} - -func (server *httpServer) handleReportBeforeSuiteState(writer http.ResponseWriter, request *http.Request) { - var state types.SpecState - if server.handleError(server.handler.ReportBeforeSuiteState(voidSender, &state), writer) { - return - } - json.NewEncoder(writer).Encode(state) -} - -func (server *httpServer) handleBeforeSuiteCompleted(writer http.ResponseWriter, request *http.Request) { - var beforeSuiteState BeforeSuiteState - if !server.decode(writer, request, &beforeSuiteState) { - return - } - - server.handleError(server.handler.BeforeSuiteCompleted(beforeSuiteState, voidReceiver), writer) -} - -func (server *httpServer) handleBeforeSuiteState(writer http.ResponseWriter, request *http.Request) { - var beforeSuiteState BeforeSuiteState - if server.handleError(server.handler.BeforeSuiteState(voidSender, &beforeSuiteState), writer) { - return - } - json.NewEncoder(writer).Encode(beforeSuiteState) -} - -func (server *httpServer) handleHaveNonprimaryProcsFinished(writer http.ResponseWriter, request *http.Request) { - if server.handleError(server.handler.HaveNonprimaryProcsFinished(voidSender, voidReceiver), writer) { - return - } - writer.WriteHeader(http.StatusOK) -} - -func (server *httpServer) handleAggregatedNonprimaryProcsReport(writer http.ResponseWriter, request *http.Request) { - var aggregatedReport types.Report - if server.handleError(server.handler.AggregatedNonprimaryProcsReport(voidSender, &aggregatedReport), writer) { - return - } - json.NewEncoder(writer).Encode(aggregatedReport) -} - -func (server *httpServer) handleCounter(writer http.ResponseWriter, request *http.Request) { - var n int - if server.handleError(server.handler.Counter(voidSender, &n), writer) { - return - } - json.NewEncoder(writer).Encode(ParallelIndexCounter{Index: n}) -} - -func (server *httpServer) handleUp(writer http.ResponseWriter, request *http.Request) { - writer.WriteHeader(http.StatusOK) -} - -func (server *httpServer) handleAbort(writer http.ResponseWriter, request *http.Request) { - if request.Method == "GET" { - var shouldAbort bool - server.handler.ShouldAbort(voidSender, &shouldAbort) - if shouldAbort { - writer.WriteHeader(http.StatusGone) - } else { - writer.WriteHeader(http.StatusOK) - } - } else { - server.handler.Abort(voidSender, voidReceiver) - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go deleted file mode 100644 index bb4675a0..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go +++ /dev/null @@ -1,136 +0,0 @@ -package parallel_support - -import ( - "net/rpc" - "time" - - "github.com/onsi/ginkgo/v2/types" -) - -type rpcClient struct { - serverHost string - client *rpc.Client -} - -func newRPCClient(serverHost string) *rpcClient { - return &rpcClient{ - serverHost: serverHost, - } -} - -func (client *rpcClient) Connect() bool { - var err error - if client.client != nil { - return true - } - client.client, err = rpc.DialHTTPPath("tcp", client.serverHost, "/") - if err != nil { - client.client = nil - return false - } - return true -} - -func (client *rpcClient) Close() error { - return client.client.Close() -} - -func (client *rpcClient) poll(method string, data any) error { - for { - err := client.client.Call(method, voidSender, data) - if err == nil { - return nil - } - switch err.Error() { - case ErrorEarly.Error(): - time.Sleep(POLLING_INTERVAL) - case ErrorGone.Error(): - return ErrorGone - case ErrorFailed.Error(): - return ErrorFailed - default: - return err - } - } -} - -func (client *rpcClient) PostSuiteWillBegin(report types.Report) error { - return client.client.Call("Server.SpecSuiteWillBegin", report, voidReceiver) -} - -func (client *rpcClient) PostDidRun(report types.SpecReport) error { - return client.client.Call("Server.DidRun", report, voidReceiver) -} - -func (client *rpcClient) PostSuiteDidEnd(report types.Report) error { - return client.client.Call("Server.SpecSuiteDidEnd", report, voidReceiver) -} - -func (client *rpcClient) Write(p []byte) (int, error) { - var n int - err := client.client.Call("Server.EmitOutput", p, &n) - return n, err -} - -func (client *rpcClient) PostEmitProgressReport(report types.ProgressReport) error { - return client.client.Call("Server.EmitProgressReport", report, voidReceiver) -} - -func (client *rpcClient) PostReportBeforeSuiteCompleted(state types.SpecState) error { - return client.client.Call("Server.ReportBeforeSuiteCompleted", state, voidReceiver) -} - -func (client *rpcClient) BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error) { - var state types.SpecState - err := client.poll("Server.ReportBeforeSuiteState", &state) - if err == ErrorGone { - return types.SpecStateFailed, nil - } - return state, err -} - -func (client *rpcClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error { - beforeSuiteState := BeforeSuiteState{ - State: state, - Data: data, - } - return client.client.Call("Server.BeforeSuiteCompleted", beforeSuiteState, voidReceiver) -} - -func (client *rpcClient) BlockUntilSynchronizedBeforeSuiteData() (types.SpecState, []byte, error) { - var beforeSuiteState BeforeSuiteState - err := client.poll("Server.BeforeSuiteState", &beforeSuiteState) - if err == ErrorGone { - return types.SpecStateInvalid, nil, types.GinkgoErrors.SynchronizedBeforeSuiteDisappearedOnProc1() - } - return beforeSuiteState.State, beforeSuiteState.Data, err -} - -func (client *rpcClient) BlockUntilNonprimaryProcsHaveFinished() error { - return client.poll("Server.HaveNonprimaryProcsFinished", voidReceiver) -} - -func (client *rpcClient) BlockUntilAggregatedNonprimaryProcsReport() (types.Report, error) { - var report types.Report - err := client.poll("Server.AggregatedNonprimaryProcsReport", &report) - if err == ErrorGone { - return types.Report{}, types.GinkgoErrors.AggregatedReportUnavailableDueToNodeDisappearing() - } - return report, err -} - -func (client *rpcClient) FetchNextCounter() (int, error) { - var counter int - err := client.client.Call("Server.Counter", voidSender, &counter) - return counter, err -} - -func (client *rpcClient) PostAbort() error { - return client.client.Call("Server.Abort", voidSender, voidReceiver) -} - -func (client *rpcClient) ShouldAbort() bool { - var shouldAbort bool - client.client.Call("Server.ShouldAbort", voidSender, &shouldAbort) - return shouldAbort -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go deleted file mode 100644 index 1574f99a..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go +++ /dev/null @@ -1,75 +0,0 @@ -/* - -The remote package provides the pieces to allow Ginkgo test suites to report to remote listeners. -This is used, primarily, to enable streaming parallel test output but has, in principal, broader applications (e.g. streaming test output to a browser). - -*/ - -package parallel_support - -import ( - "io" - "net" - "net/http" - "net/rpc" - - "github.com/onsi/ginkgo/v2/reporters" -) - -/* -RPCServer spins up on an automatically selected port and listens for communication from the forwarding reporter. -It then forwards that communication to attached reporters. -*/ -type RPCServer struct { - listener net.Listener - handler *ServerHandler -} - -// Create a new server, automatically selecting a port -func newRPCServer(parallelTotal int, reporter reporters.Reporter) (*RPCServer, error) { - listener, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return nil, err - } - return &RPCServer{ - listener: listener, - handler: newServerHandler(parallelTotal, reporter), - }, nil -} - -// Start the server. You don't need to `go s.Start()`, just `s.Start()` -func (server *RPCServer) Start() { - rpcServer := rpc.NewServer() - rpcServer.RegisterName("Server", server.handler) //register the handler's methods as the server - - httpServer := &http.Server{} - httpServer.Handler = rpcServer - - go httpServer.Serve(server.listener) -} - -// Stop the server -func (server *RPCServer) Close() { - server.listener.Close() -} - -// The address the server can be reached it. Pass this into the `ForwardingReporter`. -func (server *RPCServer) Address() string { - return server.listener.Addr().String() -} - -func (server *RPCServer) GetSuiteDone() chan any { - return server.handler.done -} - -func (server *RPCServer) GetOutputDestination() io.Writer { - return server.handler.outputDestination -} - -func (server *RPCServer) SetOutputDestination(w io.Writer) { - server.handler.outputDestination = w -} - -func (server *RPCServer) RegisterAlive(node int, alive func() bool) { - server.handler.registerAlive(node, alive) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go deleted file mode 100644 index ab9e1137..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go +++ /dev/null @@ -1,234 +0,0 @@ -package parallel_support - -import ( - "io" - "os" - "sync" - - "github.com/onsi/ginkgo/v2/reporters" - "github.com/onsi/ginkgo/v2/types" -) - -type Void struct{} - -var voidReceiver *Void = &Void{} -var voidSender Void - -// ServerHandler is an RPC-compatible handler that is shared between the http server and the rpc server. -// It handles all the business logic to avoid duplication between the two servers - -type ServerHandler struct { - done chan any - outputDestination io.Writer - reporter reporters.Reporter - alives []func() bool - lock *sync.Mutex - beforeSuiteState BeforeSuiteState - reportBeforeSuiteState types.SpecState - parallelTotal int - counter int - counterLock *sync.Mutex - shouldAbort bool - - numSuiteDidBegins int - numSuiteDidEnds int - aggregatedReport types.Report - reportHoldingArea []types.SpecReport -} - -func newServerHandler(parallelTotal int, reporter reporters.Reporter) *ServerHandler { - return &ServerHandler{ - reporter: reporter, - lock: &sync.Mutex{}, - counterLock: &sync.Mutex{}, - alives: make([]func() bool, parallelTotal), - beforeSuiteState: BeforeSuiteState{Data: nil, State: types.SpecStateInvalid}, - - parallelTotal: parallelTotal, - outputDestination: os.Stdout, - done: make(chan any), - } -} - -func (handler *ServerHandler) SpecSuiteWillBegin(report types.Report, _ *Void) error { - handler.lock.Lock() - defer handler.lock.Unlock() - - handler.numSuiteDidBegins += 1 - - // all summaries are identical, so it's fine to simply emit the last one of these - if handler.numSuiteDidBegins == handler.parallelTotal { - handler.reporter.SuiteWillBegin(report) - - for _, summary := range handler.reportHoldingArea { - handler.reporter.WillRun(summary) - handler.reporter.DidRun(summary) - } - - handler.reportHoldingArea = nil - } - - return nil -} - -func (handler *ServerHandler) DidRun(report types.SpecReport, _ *Void) error { - handler.lock.Lock() - defer handler.lock.Unlock() - - if handler.numSuiteDidBegins == handler.parallelTotal { - handler.reporter.WillRun(report) - handler.reporter.DidRun(report) - } else { - handler.reportHoldingArea = append(handler.reportHoldingArea, report) - } - - return nil -} - -func (handler *ServerHandler) SpecSuiteDidEnd(report types.Report, _ *Void) error { - handler.lock.Lock() - defer handler.lock.Unlock() - - handler.numSuiteDidEnds += 1 - if handler.numSuiteDidEnds == 1 { - handler.aggregatedReport = report - } else { - handler.aggregatedReport = handler.aggregatedReport.Add(report) - } - - if handler.numSuiteDidEnds == handler.parallelTotal { - handler.reporter.SuiteDidEnd(handler.aggregatedReport) - close(handler.done) - } - - return nil -} - -func (handler *ServerHandler) EmitOutput(output []byte, n *int) error { - var err error - *n, err = handler.outputDestination.Write(output) - return err -} - -func (handler *ServerHandler) EmitProgressReport(report types.ProgressReport, _ *Void) error { - handler.lock.Lock() - defer handler.lock.Unlock() - handler.reporter.EmitProgressReport(report) - return nil -} - -func (handler *ServerHandler) registerAlive(proc int, alive func() bool) { - handler.lock.Lock() - defer handler.lock.Unlock() - handler.alives[proc-1] = alive -} - -func (handler *ServerHandler) procIsAlive(proc int) bool { - handler.lock.Lock() - defer handler.lock.Unlock() - alive := handler.alives[proc-1] - if alive == nil { - return true - } - return alive() -} - -func (handler *ServerHandler) haveNonprimaryProcsFinished() bool { - for i := 2; i <= handler.parallelTotal; i++ { - if handler.procIsAlive(i) { - return false - } - } - return true -} - -func (handler *ServerHandler) ReportBeforeSuiteCompleted(reportBeforeSuiteState types.SpecState, _ *Void) error { - handler.lock.Lock() - defer handler.lock.Unlock() - handler.reportBeforeSuiteState = reportBeforeSuiteState - - return nil -} - -func (handler *ServerHandler) ReportBeforeSuiteState(_ Void, reportBeforeSuiteState *types.SpecState) error { - proc1IsAlive := handler.procIsAlive(1) - handler.lock.Lock() - defer handler.lock.Unlock() - if handler.reportBeforeSuiteState == types.SpecStateInvalid { - if proc1IsAlive { - return ErrorEarly - } else { - return ErrorGone - } - } - *reportBeforeSuiteState = handler.reportBeforeSuiteState - return nil -} - -func (handler *ServerHandler) BeforeSuiteCompleted(beforeSuiteState BeforeSuiteState, _ *Void) error { - handler.lock.Lock() - defer handler.lock.Unlock() - handler.beforeSuiteState = beforeSuiteState - - return nil -} - -func (handler *ServerHandler) BeforeSuiteState(_ Void, beforeSuiteState *BeforeSuiteState) error { - proc1IsAlive := handler.procIsAlive(1) - handler.lock.Lock() - defer handler.lock.Unlock() - if handler.beforeSuiteState.State == types.SpecStateInvalid { - if proc1IsAlive { - return ErrorEarly - } else { - return ErrorGone - } - } - *beforeSuiteState = handler.beforeSuiteState - return nil -} - -func (handler *ServerHandler) HaveNonprimaryProcsFinished(_ Void, _ *Void) error { - if handler.haveNonprimaryProcsFinished() { - return nil - } else { - return ErrorEarly - } -} - -func (handler *ServerHandler) AggregatedNonprimaryProcsReport(_ Void, report *types.Report) error { - if handler.haveNonprimaryProcsFinished() { - handler.lock.Lock() - defer handler.lock.Unlock() - if handler.numSuiteDidEnds == handler.parallelTotal-1 { - *report = handler.aggregatedReport - return nil - } else { - return ErrorGone - } - } else { - return ErrorEarly - } -} - -func (handler *ServerHandler) Counter(_ Void, counter *int) error { - handler.counterLock.Lock() - defer handler.counterLock.Unlock() - *counter = handler.counter - handler.counter++ - return nil -} - -func (handler *ServerHandler) Abort(_ Void, _ *Void) error { - handler.lock.Lock() - defer handler.lock.Unlock() - handler.shouldAbort = true - return nil -} - -func (handler *ServerHandler) ShouldAbort(_ Void, shouldAbort *bool) error { - handler.lock.Lock() - defer handler.lock.Unlock() - *shouldAbort = handler.shouldAbort - return nil -} diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go deleted file mode 100644 index 74ad0768..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go +++ /dev/null @@ -1,788 +0,0 @@ -/* -Ginkgo's Default Reporter - -A number of command line flags are available to tweak Ginkgo's default output. - -These are documented [here](http://onsi.github.io/ginkgo/#running_tests) -*/ -package reporters - -import ( - "fmt" - "io" - "runtime" - "strings" - "sync" - "time" - - "github.com/onsi/ginkgo/v2/formatter" - "github.com/onsi/ginkgo/v2/types" -) - -type DefaultReporter struct { - conf types.ReporterConfig - writer io.Writer - - // managing the emission stream - lastCharWasNewline bool - lastEmissionWasDelimiter bool - - // rendering - specDenoter string - retryDenoter string - formatter formatter.Formatter - - runningInParallel bool - lock *sync.Mutex -} - -func NewDefaultReporterUnderTest(conf types.ReporterConfig, writer io.Writer) *DefaultReporter { - reporter := NewDefaultReporter(conf, writer) - reporter.formatter = formatter.New(formatter.ColorModePassthrough) - - return reporter -} - -func NewDefaultReporter(conf types.ReporterConfig, writer io.Writer) *DefaultReporter { - reporter := &DefaultReporter{ - conf: conf, - writer: writer, - - lastCharWasNewline: true, - lastEmissionWasDelimiter: false, - - specDenoter: "•", - retryDenoter: "↺", - formatter: formatter.NewWithNoColorBool(conf.NoColor), - lock: &sync.Mutex{}, - } - if runtime.GOOS == "windows" { - reporter.specDenoter = "+" - reporter.retryDenoter = "R" - } - - return reporter -} - -/* The Reporter Interface */ - -func (r *DefaultReporter) SuiteWillBegin(report types.Report) { - if r.conf.Verbosity().Is(types.VerbosityLevelSuccinct) { - r.emit(r.f("[%d] {{bold}}%s{{/}} ", report.SuiteConfig.RandomSeed, report.SuiteDescription)) - if len(report.SuiteLabels) > 0 { - r.emit(r.f("{{coral}}[%s]{{/}} ", strings.Join(report.SuiteLabels, ", "))) - } - r.emit(r.f("- %d/%d specs ", report.PreRunStats.SpecsThatWillRun, report.PreRunStats.TotalSpecs)) - if report.SuiteConfig.ParallelTotal > 1 { - r.emit(r.f("- %d procs ", report.SuiteConfig.ParallelTotal)) - } - } else { - banner := r.f("Running Suite: %s - %s", report.SuiteDescription, report.SuitePath) - r.emitBlock(banner) - bannerWidth := len(banner) - if len(report.SuiteLabels) > 0 { - labels := strings.Join(report.SuiteLabels, ", ") - r.emitBlock(r.f("{{coral}}[%s]{{/}} ", labels)) - if len(labels)+2 > bannerWidth { - bannerWidth = len(labels) + 2 - } - } - r.emitBlock(strings.Repeat("=", bannerWidth)) - - out := r.f("Random Seed: {{bold}}%d{{/}}", report.SuiteConfig.RandomSeed) - if report.SuiteConfig.RandomizeAllSpecs { - out += r.f(" - will randomize all specs") - } - r.emitBlock(out) - r.emit("\n") - r.emitBlock(r.f("Will run {{bold}}%d{{/}} of {{bold}}%d{{/}} specs", report.PreRunStats.SpecsThatWillRun, report.PreRunStats.TotalSpecs)) - if report.SuiteConfig.ParallelTotal > 1 { - r.emitBlock(r.f("Running in parallel across {{bold}}%d{{/}} processes", report.SuiteConfig.ParallelTotal)) - } - } -} - -func (r *DefaultReporter) SuiteDidEnd(report types.Report) { - failures := report.SpecReports.WithState(types.SpecStateFailureStates) - if len(failures) > 0 { - r.emitBlock("\n") - if len(failures) > 1 { - r.emitBlock(r.f("{{red}}{{bold}}Summarizing %d Failures:{{/}}", len(failures))) - } else { - r.emitBlock(r.f("{{red}}{{bold}}Summarizing 1 Failure:{{/}}")) - } - for _, specReport := range failures { - highlightColor, heading := "{{red}}", "[FAIL]" - switch specReport.State { - case types.SpecStatePanicked: - highlightColor, heading = "{{magenta}}", "[PANICKED!]" - case types.SpecStateAborted: - highlightColor, heading = "{{coral}}", "[ABORTED]" - case types.SpecStateTimedout: - highlightColor, heading = "{{orange}}", "[TIMEDOUT]" - case types.SpecStateInterrupted: - highlightColor, heading = "{{orange}}", "[INTERRUPTED]" - } - locationBlock := r.codeLocationBlock(specReport, highlightColor, false, true) - r.emitBlock(r.fi(1, highlightColor+"%s{{/}} %s", heading, locationBlock)) - } - } - - //summarize the suite - if r.conf.Verbosity().Is(types.VerbosityLevelSuccinct) && report.SuiteSucceeded { - r.emit(r.f(" {{green}}SUCCESS!{{/}} %s ", report.RunTime)) - return - } - - r.emitBlock("\n") - color, status := "{{green}}{{bold}}", "SUCCESS!" - if !report.SuiteSucceeded { - color, status = "{{red}}{{bold}}", "FAIL!" - } - - specs := report.SpecReports.WithLeafNodeType(types.NodeTypeIt) //exclude any suite setup nodes - r.emitBlock(r.f(color+"Ran %d of %d Specs in %.3f seconds{{/}}", - specs.CountWithState(types.SpecStatePassed)+specs.CountWithState(types.SpecStateFailureStates), - report.PreRunStats.TotalSpecs, - report.RunTime.Seconds()), - ) - - switch len(report.SpecialSuiteFailureReasons) { - case 0: - r.emit(r.f(color+"%s{{/}} -- ", status)) - case 1: - r.emit(r.f(color+"%s - %s{{/}} -- ", status, report.SpecialSuiteFailureReasons[0])) - default: - r.emitBlock(r.f(color+"%s - %s{{/}}\n", status, strings.Join(report.SpecialSuiteFailureReasons, ", "))) - } - - if len(specs) == 0 && report.SpecReports.WithLeafNodeType(types.NodeTypeBeforeSuite|types.NodeTypeSynchronizedBeforeSuite).CountWithState(types.SpecStateFailureStates) > 0 { - r.emit(r.f("{{cyan}}{{bold}}A BeforeSuite node failed so all tests were skipped.{{/}}\n")) - } else { - r.emit(r.f("{{green}}{{bold}}%d Passed{{/}} | ", specs.CountWithState(types.SpecStatePassed))) - r.emit(r.f("{{red}}{{bold}}%d Failed{{/}} | ", specs.CountWithState(types.SpecStateFailureStates))) - if specs.CountOfFlakedSpecs() > 0 { - r.emit(r.f("{{light-yellow}}{{bold}}%d Flaked{{/}} | ", specs.CountOfFlakedSpecs())) - } - if specs.CountOfRepeatedSpecs() > 0 { - r.emit(r.f("{{light-yellow}}{{bold}}%d Repeated{{/}} | ", specs.CountOfRepeatedSpecs())) - } - r.emit(r.f("{{yellow}}{{bold}}%d Pending{{/}} | ", specs.CountWithState(types.SpecStatePending))) - r.emit(r.f("{{cyan}}{{bold}}%d Skipped{{/}}\n", specs.CountWithState(types.SpecStateSkipped))) - } -} - -func (r *DefaultReporter) WillRun(report types.SpecReport) { - v := r.conf.Verbosity() - if v.LT(types.VerbosityLevelVerbose) || report.State.Is(types.SpecStatePending|types.SpecStateSkipped) || report.RunningInParallel { - return - } - - r.emitDelimiter(0) - r.emitBlock(r.f(r.codeLocationBlock(report, "{{/}}", v.Is(types.VerbosityLevelVeryVerbose), false))) -} - -func (r *DefaultReporter) wrapTextBlock(sectionName string, fn func()) { - r.emitBlock("\n") - if r.conf.GithubOutput { - r.emitBlock(r.fi(1, "::group::%s", sectionName)) - } else { - r.emitBlock(r.fi(1, "{{gray}}%s >>{{/}}", sectionName)) - } - fn() - if r.conf.GithubOutput { - r.emitBlock(r.fi(1, "::endgroup::")) - } else { - r.emitBlock(r.fi(1, "{{gray}}<< %s{{/}}", sectionName)) - } - -} - -func (r *DefaultReporter) DidRun(report types.SpecReport) { - v := r.conf.Verbosity() - inParallel := report.RunningInParallel - - //should we completely omit this spec? - if report.State.Is(types.SpecStateSkipped) && r.conf.SilenceSkips { - return - } - - header := r.specDenoter - if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { - header = fmt.Sprintf("[%s]", report.LeafNodeType) - } - highlightColor := r.highlightColorForState(report.State) - - // have we already been streaming the timeline? - timelineHasBeenStreaming := v.GTE(types.VerbosityLevelVerbose) && !inParallel - - // should we show the timeline? - var timeline types.Timeline - showTimeline := !timelineHasBeenStreaming && (v.GTE(types.VerbosityLevelVerbose) || report.Failed()) - if showTimeline { - timeline = report.Timeline().WithoutHiddenReportEntries() - keepVeryVerboseSpecEvents := v.Is(types.VerbosityLevelVeryVerbose) || - (v.Is(types.VerbosityLevelVerbose) && r.conf.ShowNodeEvents) || - (report.Failed() && r.conf.ShowNodeEvents) - if !keepVeryVerboseSpecEvents { - timeline = timeline.WithoutVeryVerboseSpecEvents() - } - if len(timeline) == 0 && report.CapturedGinkgoWriterOutput == "" { - // the timeline is completely empty - don't show it - showTimeline = false - } - if v.LT(types.VerbosityLevelVeryVerbose) && report.CapturedGinkgoWriterOutput == "" && len(timeline) > 0 { - //if we aren't -vv and the timeline only has a single failure, don't show it as it will appear at the end of the report - failure, isFailure := timeline[0].(types.Failure) - if isFailure && (len(timeline) == 1 || (len(timeline) == 2 && failure.AdditionalFailure != nil)) { - showTimeline = false - } - } - } - - // should we have a separate section for always-visible reports? - showSeparateVisibilityAlwaysReportsSection := !timelineHasBeenStreaming && !showTimeline && report.ReportEntries.HasVisibility(types.ReportEntryVisibilityAlways) - - // should we have a separate section for captured stdout/stderr - showSeparateStdSection := inParallel && (report.CapturedStdOutErr != "") - - // given all that - do we have any actual content to show? or are we a single denoter in a stream? - reportHasContent := v.Is(types.VerbosityLevelVeryVerbose) || showTimeline || showSeparateVisibilityAlwaysReportsSection || showSeparateStdSection || report.Failed() || (v.Is(types.VerbosityLevelVerbose) && !report.State.Is(types.SpecStateSkipped)) - - // should we show a runtime? - includeRuntime := !report.State.Is(types.SpecStateSkipped|types.SpecStatePending) || (report.State.Is(types.SpecStateSkipped) && report.Failure.Message != "") - - // should we show the codelocation block? - showCodeLocation := !timelineHasBeenStreaming || !report.State.Is(types.SpecStatePassed) - - switch report.State { - case types.SpecStatePassed: - if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) && !reportHasContent { - return - } - if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { - header = fmt.Sprintf("%s PASSED", header) - } - if report.NumAttempts > 1 && report.MaxFlakeAttempts > 1 { - header, reportHasContent = fmt.Sprintf("%s [FLAKEY TEST - TOOK %d ATTEMPTS TO PASS]", r.retryDenoter, report.NumAttempts), true - } - case types.SpecStatePending: - header = "P" - if v.GT(types.VerbosityLevelSuccinct) { - header, reportHasContent = "P [PENDING]", true - } - case types.SpecStateSkipped: - header = "S" - if v.Is(types.VerbosityLevelVeryVerbose) || (v.Is(types.VerbosityLevelVerbose) && report.Failure.Message != "") { - header, reportHasContent = "S [SKIPPED]", true - } - default: - header = fmt.Sprintf("%s [%s]", header, r.humanReadableState(report.State)) - if report.MaxMustPassRepeatedly > 1 { - header = fmt.Sprintf("%s DURING REPETITION #%d", header, report.NumAttempts) - } - } - - // If we have no content to show, just emit the header and return - if !reportHasContent { - r.emit(r.f(highlightColor + header + "{{/}}")) - if r.conf.ForceNewlines { - r.emit("\n") - } - return - } - - if includeRuntime { - header = r.f("%s [%.3f seconds]", header, report.RunTime.Seconds()) - } - - // Emit header - if !timelineHasBeenStreaming { - r.emitDelimiter(0) - } - r.emitBlock(r.f(highlightColor + header + "{{/}}")) - if showCodeLocation { - r.emitBlock(r.codeLocationBlock(report, highlightColor, v.Is(types.VerbosityLevelVeryVerbose), false)) - } - - //Emit Stdout/Stderr Output - if showSeparateStdSection { - r.wrapTextBlock("Captured StdOut/StdErr Output", func() { - r.emitBlock(r.fi(1, "%s", report.CapturedStdOutErr)) - }) - } - - if showSeparateVisibilityAlwaysReportsSection { - r.wrapTextBlock("Report Entries", func() { - for _, entry := range report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways) { - r.emitReportEntry(1, entry) - } - }) - } - - if showTimeline { - r.wrapTextBlock("Timeline", func() { - r.emitTimeline(1, report, timeline) - }) - } - - // Emit Failure Message - if !report.Failure.IsZero() && !v.Is(types.VerbosityLevelVeryVerbose) { - r.emitBlock("\n") - r.emitFailure(1, report.State, report.Failure, true) - if len(report.AdditionalFailures) > 0 { - r.emitBlock(r.fi(1, "\nThere were {{bold}}{{red}}additional failures{{/}} detected. To view them in detail run {{bold}}ginkgo -vv{{/}}")) - } - } - - r.emitDelimiter(0) -} - -func (r *DefaultReporter) highlightColorForState(state types.SpecState) string { - switch state { - case types.SpecStatePassed: - return "{{green}}" - case types.SpecStatePending: - return "{{yellow}}" - case types.SpecStateSkipped: - return "{{cyan}}" - case types.SpecStateFailed: - return "{{red}}" - case types.SpecStateTimedout: - return "{{orange}}" - case types.SpecStatePanicked: - return "{{magenta}}" - case types.SpecStateInterrupted: - return "{{orange}}" - case types.SpecStateAborted: - return "{{coral}}" - default: - return "{{gray}}" - } -} - -func (r *DefaultReporter) humanReadableState(state types.SpecState) string { - return strings.ToUpper(state.String()) -} - -func (r *DefaultReporter) emitTimeline(indent uint, report types.SpecReport, timeline types.Timeline) { - isVeryVerbose := r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose) - gw := report.CapturedGinkgoWriterOutput - cursor := 0 - for _, entry := range timeline { - tl := entry.GetTimelineLocation() - if tl.Offset < len(gw) { - r.emit(r.fi(indent, "%s", gw[cursor:tl.Offset])) - cursor = tl.Offset - } else if cursor < len(gw) { - r.emit(r.fi(indent, "%s", gw[cursor:])) - cursor = len(gw) - } - switch x := entry.(type) { - case types.Failure: - if isVeryVerbose { - r.emitFailure(indent, report.State, x, false) - } else { - r.emitShortFailure(indent, report.State, x) - } - case types.AdditionalFailure: - if isVeryVerbose { - r.emitFailure(indent, x.State, x.Failure, true) - } else { - r.emitShortFailure(indent, x.State, x.Failure) - } - case types.ReportEntry: - r.emitReportEntry(indent, x) - case types.ProgressReport: - r.emitProgressReport(indent, false, x) - case types.SpecEvent: - if isVeryVerbose || !x.IsOnlyVisibleAtVeryVerbose() || r.conf.ShowNodeEvents { - r.emitSpecEvent(indent, x, isVeryVerbose) - } - } - } - if cursor < len(gw) { - r.emit(r.fi(indent, "%s", gw[cursor:])) - } -} - -func (r *DefaultReporter) EmitFailure(state types.SpecState, failure types.Failure) { - if r.conf.Verbosity().Is(types.VerbosityLevelVerbose) { - r.emitShortFailure(1, state, failure) - } else if r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose) { - r.emitFailure(1, state, failure, true) - } -} - -func (r *DefaultReporter) emitShortFailure(indent uint, state types.SpecState, failure types.Failure) { - r.emitBlock(r.fi(indent, r.highlightColorForState(state)+"[%s]{{/}} in [%s] - %s {{gray}}@ %s{{/}}", - r.humanReadableState(state), - failure.FailureNodeType, - failure.Location, - failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), - )) -} - -func (r *DefaultReporter) emitFailure(indent uint, state types.SpecState, failure types.Failure, includeAdditionalFailure bool) { - highlightColor := r.highlightColorForState(state) - r.emitBlock(r.fi(indent, highlightColor+"[%s] %s{{/}}", r.humanReadableState(state), failure.Message)) - if r.conf.GithubOutput { - level := "error" - if state.Is(types.SpecStateSkipped) { - level = "notice" - } - r.emitBlock(r.fi(indent, "::%s file=%s,line=%d::%s %s", level, failure.Location.FileName, failure.Location.LineNumber, failure.FailureNodeType, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) - } else { - r.emitBlock(r.fi(indent, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}} {{gray}}@ %s{{/}}\n", failure.FailureNodeType, failure.Location, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) - } - if failure.ForwardedPanic != "" { - r.emitBlock("\n") - r.emitBlock(r.fi(indent, highlightColor+"%s{{/}}", failure.ForwardedPanic)) - } - - if r.conf.FullTrace || failure.ForwardedPanic != "" { - r.emitBlock("\n") - r.emitBlock(r.fi(indent, highlightColor+"Full Stack Trace{{/}}")) - r.emitBlock(r.fi(indent+1, "%s", failure.Location.FullStackTrace)) - } - - if !failure.ProgressReport.IsZero() { - r.emitBlock("\n") - r.emitProgressReport(indent, false, failure.ProgressReport) - } - - if failure.AdditionalFailure != nil && includeAdditionalFailure { - r.emitBlock("\n") - r.emitFailure(indent, failure.AdditionalFailure.State, failure.AdditionalFailure.Failure, true) - } -} - -func (r *DefaultReporter) EmitProgressReport(report types.ProgressReport) { - r.emitDelimiter(1) - - if report.RunningInParallel { - r.emit(r.fi(1, "{{coral}}Progress Report for Ginkgo Process #{{bold}}%d{{/}}\n", report.ParallelProcess)) - } - shouldEmitGW := report.RunningInParallel || r.conf.Verbosity().LT(types.VerbosityLevelVerbose) - r.emitProgressReport(1, shouldEmitGW, report) - r.emitDelimiter(1) -} - -func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput bool, report types.ProgressReport) { - if report.Message != "" { - r.emitBlock(r.fi(indent, report.Message+"\n")) - indent += 1 - } - if report.LeafNodeText != "" { - subjectIndent := indent - if len(report.ContainerHierarchyTexts) > 0 { - r.emit(r.fi(indent, r.cycleJoin(report.ContainerHierarchyTexts, " "))) - r.emit(" ") - subjectIndent = 0 - } - r.emit(r.fi(subjectIndent, "{{bold}}{{orange}}%s{{/}} (Spec Runtime: %s)\n", report.LeafNodeText, report.Time().Sub(report.SpecStartTime).Round(time.Millisecond))) - r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.LeafNodeLocation)) - indent += 1 - } - if report.CurrentNodeType != types.NodeTypeInvalid { - r.emit(r.fi(indent, "In {{bold}}{{orange}}[%s]{{/}}", report.CurrentNodeType)) - if report.CurrentNodeText != "" && !report.CurrentNodeType.Is(types.NodeTypeIt) { - r.emit(r.f(" {{bold}}{{orange}}%s{{/}}", report.CurrentNodeText)) - } - - r.emit(r.f(" (Node Runtime: %s)\n", report.Time().Sub(report.CurrentNodeStartTime).Round(time.Millisecond))) - r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.CurrentNodeLocation)) - indent += 1 - } - if report.CurrentStepText != "" { - r.emit(r.fi(indent, "At {{bold}}{{orange}}[By Step] %s{{/}} (Step Runtime: %s)\n", report.CurrentStepText, report.Time().Sub(report.CurrentStepStartTime).Round(time.Millisecond))) - r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.CurrentStepLocation)) - indent += 1 - } - - if indent > 0 { - indent -= 1 - } - - if emitGinkgoWriterOutput && report.CapturedGinkgoWriterOutput != "" { - r.emit("\n") - r.emitBlock(r.fi(indent, "{{gray}}Begin Captured GinkgoWriter Output >>{{/}}")) - limit, lines := 10, strings.Split(report.CapturedGinkgoWriterOutput, "\n") - if len(lines) <= limit { - r.emitBlock(r.fi(indent+1, "%s", report.CapturedGinkgoWriterOutput)) - } else { - r.emitBlock(r.fi(indent+1, "{{gray}}...{{/}}")) - for _, line := range lines[len(lines)-limit-1:] { - r.emitBlock(r.fi(indent+1, "%s", line)) - } - } - r.emitBlock(r.fi(indent, "{{gray}}<< End Captured GinkgoWriter Output{{/}}")) - } - - if !report.SpecGoroutine().IsZero() { - r.emit("\n") - r.emit(r.fi(indent, "{{bold}}{{underline}}Spec Goroutine{{/}}\n")) - r.emitGoroutines(indent, report.SpecGoroutine()) - } - - if len(report.AdditionalReports) > 0 { - r.emit("\n") - r.emitBlock(r.fi(indent, "{{gray}}Begin Additional Progress Reports >>{{/}}")) - for i, additionalReport := range report.AdditionalReports { - r.emit(r.fi(indent+1, additionalReport)) - if i < len(report.AdditionalReports)-1 { - r.emitBlock(r.fi(indent+1, "{{gray}}%s{{/}}", strings.Repeat("-", 10))) - } - } - r.emitBlock(r.fi(indent, "{{gray}}<< End Additional Progress Reports{{/}}")) - } - - highlightedGoroutines := report.HighlightedGoroutines() - if len(highlightedGoroutines) > 0 { - r.emit("\n") - r.emit(r.fi(indent, "{{bold}}{{underline}}Goroutines of Interest{{/}}\n")) - r.emitGoroutines(indent, highlightedGoroutines...) - } - - otherGoroutines := report.OtherGoroutines() - if len(otherGoroutines) > 0 { - r.emit("\n") - r.emit(r.fi(indent, "{{gray}}{{bold}}{{underline}}Other Goroutines{{/}}\n")) - r.emitGoroutines(indent, otherGoroutines...) - } -} - -func (r *DefaultReporter) EmitReportEntry(entry types.ReportEntry) { - if r.conf.Verbosity().LT(types.VerbosityLevelVerbose) || entry.Visibility == types.ReportEntryVisibilityNever { - return - } - r.emitReportEntry(1, entry) -} - -func (r *DefaultReporter) emitReportEntry(indent uint, entry types.ReportEntry) { - r.emitBlock(r.fi(indent, "{{bold}}"+entry.Name+"{{gray}} "+fmt.Sprintf("- %s @ %s{{/}}", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT)))) - if representation := entry.StringRepresentation(); representation != "" { - r.emitBlock(r.fi(indent+1, representation)) - } -} - -func (r *DefaultReporter) EmitSpecEvent(event types.SpecEvent) { - v := r.conf.Verbosity() - if v.Is(types.VerbosityLevelVeryVerbose) || (v.Is(types.VerbosityLevelVerbose) && (r.conf.ShowNodeEvents || !event.IsOnlyVisibleAtVeryVerbose())) { - r.emitSpecEvent(1, event, r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose)) - } -} - -func (r *DefaultReporter) emitSpecEvent(indent uint, event types.SpecEvent, includeLocation bool) { - location := "" - if includeLocation { - location = fmt.Sprintf("- %s ", event.CodeLocation.String()) - } - switch event.SpecEventType { - case types.SpecEventInvalid: - return - case types.SpecEventByStart: - r.emitBlock(r.fi(indent, "{{bold}}STEP:{{/}} %s {{gray}}%s@ %s{{/}}", event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) - case types.SpecEventByEnd: - r.emitBlock(r.fi(indent, "{{bold}}END STEP:{{/}} %s {{gray}}%s@ %s (%s){{/}}", event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), event.Duration.Round(time.Millisecond))) - case types.SpecEventNodeStart: - r.emitBlock(r.fi(indent, "> Enter {{bold}}[%s]{{/}} %s {{gray}}%s@ %s{{/}}", event.NodeType.String(), event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) - case types.SpecEventNodeEnd: - r.emitBlock(r.fi(indent, "< Exit {{bold}}[%s]{{/}} %s {{gray}}%s@ %s (%s){{/}}", event.NodeType.String(), event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), event.Duration.Round(time.Millisecond))) - case types.SpecEventSpecRepeat: - r.emitBlock(r.fi(indent, "\n{{bold}}Attempt #%d {{green}}Passed{{/}}{{bold}}. Repeating %s{{/}} {{gray}}@ %s{{/}}\n\n", event.Attempt, r.retryDenoter, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) - case types.SpecEventSpecRetry: - r.emitBlock(r.fi(indent, "\n{{bold}}Attempt #%d {{red}}Failed{{/}}{{bold}}. Retrying %s{{/}} {{gray}}@ %s{{/}}\n\n", event.Attempt, r.retryDenoter, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT))) - } -} - -func (r *DefaultReporter) emitGoroutines(indent uint, goroutines ...types.Goroutine) { - for idx, g := range goroutines { - color := "{{gray}}" - if g.HasHighlights() { - color = "{{orange}}" - } - r.emit(r.fi(indent, color+"goroutine %d [%s]{{/}}\n", g.ID, g.State)) - for _, fc := range g.Stack { - if fc.Highlight { - r.emit(r.fi(indent, color+"{{bold}}> %s{{/}}\n", fc.Function)) - r.emit(r.fi(indent+2, color+"{{bold}}%s:%d{{/}}\n", fc.Filename, fc.Line)) - r.emitSource(indent+3, fc) - } else { - r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", fc.Function)) - r.emit(r.fi(indent+2, "{{gray}}%s:%d{{/}}\n", fc.Filename, fc.Line)) - } - } - - if idx+1 < len(goroutines) { - r.emit("\n") - } - } -} - -func (r *DefaultReporter) emitSource(indent uint, fc types.FunctionCall) { - lines := fc.Source - if len(lines) == 0 { - return - } - - lTrim := 100000 - for _, line := range lines { - lTrimLine := len(line) - len(strings.TrimLeft(line, " \t")) - if lTrimLine < lTrim && len(line) > 0 { - lTrim = lTrimLine - } - } - if lTrim == 100000 { - lTrim = 0 - } - - for idx, line := range lines { - if len(line) > lTrim { - line = line[lTrim:] - } - if idx == fc.SourceHighlight { - r.emit(r.fi(indent, "{{bold}}{{orange}}> %s{{/}}\n", line)) - } else { - r.emit(r.fi(indent, "| %s\n", line)) - } - } -} - -/* Emitting to the writer */ -func (r *DefaultReporter) emit(s string) { - r._emit(s, false, false) -} - -func (r *DefaultReporter) emitBlock(s string) { - r._emit(s, true, false) -} - -func (r *DefaultReporter) emitDelimiter(indent uint) { - r._emit(r.fi(indent, "{{gray}}%s{{/}}", strings.Repeat("-", 30)), true, true) -} - -// a bit ugly - but we're trying to minimize locking on this hot codepath -func (r *DefaultReporter) _emit(s string, block bool, isDelimiter bool) { - if len(s) == 0 { - return - } - r.lock.Lock() - defer r.lock.Unlock() - if isDelimiter && r.lastEmissionWasDelimiter { - return - } - if block && !r.lastCharWasNewline { - r.writer.Write([]byte("\n")) - } - r.lastCharWasNewline = (s[len(s)-1:] == "\n") - r.writer.Write([]byte(s)) - if block && !r.lastCharWasNewline { - r.writer.Write([]byte("\n")) - r.lastCharWasNewline = true - } - r.lastEmissionWasDelimiter = isDelimiter -} - -/* Rendering text */ -func (r *DefaultReporter) f(format string, args ...any) string { - return r.formatter.F(format, args...) -} - -func (r *DefaultReporter) fi(indentation uint, format string, args ...any) string { - return r.formatter.Fi(indentation, format, args...) -} - -func (r *DefaultReporter) cycleJoin(elements []string, joiner string) string { - return r.formatter.CycleJoin(elements, joiner, []string{"{{/}}", "{{gray}}"}) -} - -func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, veryVerbose bool, usePreciseFailureLocation bool) string { - texts, locations, labels := []string{}, []types.CodeLocation{}, [][]string{} - texts, locations, labels = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...) - - if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) { - texts = append(texts, r.f("[%s] %s", report.LeafNodeType, report.LeafNodeText)) - } else { - texts = append(texts, r.f(report.LeafNodeText)) - } - labels = append(labels, report.LeafNodeLabels) - locations = append(locations, report.LeafNodeLocation) - - failureLocation := report.Failure.FailureNodeLocation - if usePreciseFailureLocation { - failureLocation = report.Failure.Location - } - - highlightIndex := -1 - switch report.Failure.FailureNodeContext { - case types.FailureNodeAtTopLevel: - texts = append([]string{fmt.Sprintf("TOP-LEVEL [%s]", report.Failure.FailureNodeType)}, texts...) - locations = append([]types.CodeLocation{failureLocation}, locations...) - labels = append([][]string{{}}, labels...) - highlightIndex = 0 - case types.FailureNodeInContainer: - i := report.Failure.FailureNodeContainerIndex - texts[i] = fmt.Sprintf("%s [%s]", texts[i], report.Failure.FailureNodeType) - locations[i] = failureLocation - highlightIndex = i - case types.FailureNodeIsLeafNode: - i := len(texts) - 1 - texts[i] = fmt.Sprintf("[%s] %s", report.LeafNodeType, report.LeafNodeText) - locations[i] = failureLocation - highlightIndex = i - default: - //there is no failure, so we highlight the leaf ndoe - highlightIndex = len(texts) - 1 - } - - out := "" - if veryVerbose { - for i := range texts { - if i == highlightIndex { - out += r.fi(uint(i), highlightColor+"{{bold}}%s{{/}}", texts[i]) - } else { - out += r.fi(uint(i), "%s", texts[i]) - } - if len(labels[i]) > 0 { - out += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels[i], ", ")) - } - out += "\n" - out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i]) - } - } else { - for i := range texts { - style := "{{/}}" - if i%2 == 1 { - style = "{{gray}}" - } - if i == highlightIndex { - style = highlightColor + "{{bold}}" - } - out += r.f(style+"%s", texts[i]) - if i < len(texts)-1 { - out += " " - } else { - out += r.f("{{/}}") - } - } - flattenedLabels := report.Labels() - if len(flattenedLabels) > 0 { - out += r.f(" {{coral}}[%s]{{/}}", strings.Join(flattenedLabels, ", ")) - } - out += "\n" - if usePreciseFailureLocation { - out += r.f("{{gray}}%s{{/}}", failureLocation) - } else { - leafLocation := locations[len(locations)-1] - if (report.Failure.FailureNodeLocation != types.CodeLocation{}) && (report.Failure.FailureNodeLocation != leafLocation) { - out += r.fi(1, highlightColor+"[%s]{{/}} {{gray}}%s{{/}}\n", report.Failure.FailureNodeType, report.Failure.FailureNodeLocation) - out += r.fi(1, "{{gray}}[%s] %s{{/}}", report.LeafNodeType, leafLocation) - } else { - out += r.f("{{gray}}%s{{/}}", leafLocation) - } - } - - } - return out -} diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go deleted file mode 100644 index 613072eb..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go +++ /dev/null @@ -1,149 +0,0 @@ -package reporters - -import ( - "github.com/onsi/ginkgo/v2/config" - "github.com/onsi/ginkgo/v2/types" -) - -// Deprecated: DeprecatedReporter was how Ginkgo V1 provided support for CustomReporters -// this has been removed in V2. -// Please read the documentation at: -// https://onsi.github.io/ginkgo/MIGRATING_TO_V2#removed-custom-reporters -// for Ginkgo's new behavior and for a migration path. -type DeprecatedReporter interface { - SuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) - BeforeSuiteDidRun(setupSummary *types.SetupSummary) - SpecWillRun(specSummary *types.SpecSummary) - SpecDidComplete(specSummary *types.SpecSummary) - AfterSuiteDidRun(setupSummary *types.SetupSummary) - SuiteDidEnd(summary *types.SuiteSummary) -} - -// ReportViaDeprecatedReporter takes a V1 custom reporter and a V2 report and -// calls the custom reporter's methods with appropriately transformed data from the V2 report. -// -// ReportViaDeprecatedReporter should be called in a `ReportAfterSuite()` -// -// Deprecated: ReportViaDeprecatedReporter method exists to help developer bridge between deprecated V1 functionality and the new -// reporting support in V2. It will be removed in a future minor version of Ginkgo. -func ReportViaDeprecatedReporter(reporter DeprecatedReporter, report types.Report) { - conf := config.DeprecatedGinkgoConfigType{ - RandomSeed: report.SuiteConfig.RandomSeed, - RandomizeAllSpecs: report.SuiteConfig.RandomizeAllSpecs, - FocusStrings: report.SuiteConfig.FocusStrings, - SkipStrings: report.SuiteConfig.SkipStrings, - FailOnPending: report.SuiteConfig.FailOnPending, - FailFast: report.SuiteConfig.FailFast, - FlakeAttempts: report.SuiteConfig.FlakeAttempts, - EmitSpecProgress: false, - DryRun: report.SuiteConfig.DryRun, - ParallelNode: report.SuiteConfig.ParallelProcess, - ParallelTotal: report.SuiteConfig.ParallelTotal, - SyncHost: report.SuiteConfig.ParallelHost, - StreamHost: report.SuiteConfig.ParallelHost, - } - - summary := &types.DeprecatedSuiteSummary{ - SuiteDescription: report.SuiteDescription, - SuiteID: report.SuitePath, - - NumberOfSpecsBeforeParallelization: report.PreRunStats.TotalSpecs, - NumberOfTotalSpecs: report.PreRunStats.TotalSpecs, - NumberOfSpecsThatWillBeRun: report.PreRunStats.SpecsThatWillRun, - } - - reporter.SuiteWillBegin(conf, summary) - - for _, spec := range report.SpecReports { - switch spec.LeafNodeType { - case types.NodeTypeBeforeSuite, types.NodeTypeSynchronizedBeforeSuite: - setupSummary := &types.DeprecatedSetupSummary{ - ComponentType: spec.LeafNodeType, - CodeLocation: spec.LeafNodeLocation, - State: spec.State, - RunTime: spec.RunTime, - Failure: failureFor(spec), - CapturedOutput: spec.CombinedOutput(), - SuiteID: report.SuitePath, - } - reporter.BeforeSuiteDidRun(setupSummary) - case types.NodeTypeAfterSuite, types.NodeTypeSynchronizedAfterSuite: - setupSummary := &types.DeprecatedSetupSummary{ - ComponentType: spec.LeafNodeType, - CodeLocation: spec.LeafNodeLocation, - State: spec.State, - RunTime: spec.RunTime, - Failure: failureFor(spec), - CapturedOutput: spec.CombinedOutput(), - SuiteID: report.SuitePath, - } - reporter.AfterSuiteDidRun(setupSummary) - case types.NodeTypeIt: - componentTexts, componentCodeLocations := []string{}, []types.CodeLocation{} - componentTexts = append(componentTexts, spec.ContainerHierarchyTexts...) - componentCodeLocations = append(componentCodeLocations, spec.ContainerHierarchyLocations...) - componentTexts = append(componentTexts, spec.LeafNodeText) - componentCodeLocations = append(componentCodeLocations, spec.LeafNodeLocation) - - specSummary := &types.DeprecatedSpecSummary{ - ComponentTexts: componentTexts, - ComponentCodeLocations: componentCodeLocations, - State: spec.State, - RunTime: spec.RunTime, - Failure: failureFor(spec), - NumberOfSamples: spec.NumAttempts, - CapturedOutput: spec.CombinedOutput(), - SuiteID: report.SuitePath, - } - reporter.SpecWillRun(specSummary) - reporter.SpecDidComplete(specSummary) - - switch spec.State { - case types.SpecStatePending: - summary.NumberOfPendingSpecs += 1 - case types.SpecStateSkipped: - summary.NumberOfSkippedSpecs += 1 - case types.SpecStateFailed, types.SpecStatePanicked, types.SpecStateInterrupted: - summary.NumberOfFailedSpecs += 1 - case types.SpecStatePassed: - summary.NumberOfPassedSpecs += 1 - if spec.NumAttempts > 1 { - summary.NumberOfFlakedSpecs += 1 - } - } - } - } - - summary.SuiteSucceeded = report.SuiteSucceeded - summary.RunTime = report.RunTime - - reporter.SuiteDidEnd(summary) -} - -func failureFor(spec types.SpecReport) types.DeprecatedSpecFailure { - if spec.Failure.IsZero() { - return types.DeprecatedSpecFailure{} - } - - index := 0 - switch spec.Failure.FailureNodeContext { - case types.FailureNodeInContainer: - index = spec.Failure.FailureNodeContainerIndex - case types.FailureNodeAtTopLevel: - index = -1 - case types.FailureNodeIsLeafNode: - index = len(spec.ContainerHierarchyTexts) - 1 - if spec.LeafNodeText != "" { - index += 1 - } - } - - return types.DeprecatedSpecFailure{ - Message: spec.Failure.Message, - Location: spec.Failure.Location, - ForwardedPanic: spec.Failure.ForwardedPanic, - ComponentIndex: index, - ComponentType: spec.Failure.FailureNodeType, - ComponentCodeLocation: spec.Failure.FailureNodeLocation, - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/json_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/json_report.go deleted file mode 100644 index 5d3e8db9..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/json_report.go +++ /dev/null @@ -1,69 +0,0 @@ -package reporters - -import ( - "encoding/json" - "fmt" - "os" - "path" - - "github.com/onsi/ginkgo/v2/types" -) - -// GenerateJSONReport produces a JSON-formatted report at the passed in destination -func GenerateJSONReport(report types.Report, destination string) error { - if err := os.MkdirAll(path.Dir(destination), 0770); err != nil { - return err - } - f, err := os.Create(destination) - if err != nil { - return err - } - defer f.Close() - enc := json.NewEncoder(f) - enc.SetIndent("", " ") - err = enc.Encode([]types.Report{ - report, - }) - if err != nil { - return err - } - return nil -} - -// MergeJSONReports produces a single JSON-formatted report at the passed in destination by merging the JSON-formatted reports provided in sources -// It skips over reports that fail to decode but reports on them via the returned messages []string -func MergeAndCleanupJSONReports(sources []string, destination string) ([]string, error) { - messages := []string{} - allReports := []types.Report{} - for _, source := range sources { - reports := []types.Report{} - data, err := os.ReadFile(source) - if err != nil { - messages = append(messages, fmt.Sprintf("Could not open %s:\n%s", source, err.Error())) - continue - } - err = json.Unmarshal(data, &reports) - if err != nil { - messages = append(messages, fmt.Sprintf("Could not decode %s:\n%s", source, err.Error())) - continue - } - os.Remove(source) - allReports = append(allReports, reports...) - } - - if err := os.MkdirAll(path.Dir(destination), 0770); err != nil { - return messages, err - } - f, err := os.Create(destination) - if err != nil { - return messages, err - } - defer f.Close() - enc := json.NewEncoder(f) - enc.SetIndent("", " ") - err = enc.Encode(allReports) - if err != nil { - return messages, err - } - return messages, nil -} diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go deleted file mode 100644 index 562e0f62..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go +++ /dev/null @@ -1,390 +0,0 @@ -/* - -JUnit XML Reporter for Ginkgo - -For usage instructions: http://onsi.github.io/ginkgo/#generating_junit_xml_output - -The schema used for the generated JUnit xml file was adapted from https://llg.cubic.org/docs/junit/ - -*/ - -package reporters - -import ( - "encoding/xml" - "fmt" - "os" - "path" - "regexp" - "strings" - - "github.com/onsi/ginkgo/v2/config" - "github.com/onsi/ginkgo/v2/types" -) - -type JunitReportConfig struct { - // Spec States for which no timeline should be emitted for system-err - // set this to types.SpecStatePassed|types.SpecStateSkipped|types.SpecStatePending to only match failing specs - OmitTimelinesForSpecState types.SpecState - - // Enable OmitFailureMessageAttr to prevent failure messages appearing in the "message" attribute of the Failure and Error tags - OmitFailureMessageAttr bool - - //Enable OmitCapturedStdOutErr to prevent captured stdout/stderr appearing in system-out - OmitCapturedStdOutErr bool - - // Enable OmitSpecLabels to prevent labels from appearing in the spec name - OmitSpecLabels bool - - // Enable OmitLeafNodeType to prevent the spec leaf node type from appearing in the spec name - OmitLeafNodeType bool - - // Enable OmitSuiteSetupNodes to prevent the creation of testcase entries for setup nodes - OmitSuiteSetupNodes bool -} - -type JUnitTestSuites struct { - XMLName xml.Name `xml:"testsuites"` - // Tests maps onto the total number of specs in all test suites (this includes any suite nodes such as BeforeSuite) - Tests int `xml:"tests,attr"` - // Disabled maps onto specs that are pending and/or skipped - Disabled int `xml:"disabled,attr"` - // Errors maps onto specs that panicked or were interrupted - Errors int `xml:"errors,attr"` - // Failures maps onto specs that failed - Failures int `xml:"failures,attr"` - // Time is the time in seconds to execute all test suites - Time float64 `xml:"time,attr"` - - //The set of all test suites - TestSuites []JUnitTestSuite `xml:"testsuite"` -} - -type JUnitTestSuite struct { - // Name maps onto the description of the test suite - maps onto Report.SuiteDescription - Name string `xml:"name,attr"` - // Package maps onto the absolute path to the test suite - maps onto Report.SuitePath - Package string `xml:"package,attr"` - // Tests maps onto the total number of specs in the test suite (this includes any suite nodes such as BeforeSuite) - Tests int `xml:"tests,attr"` - // Disabled maps onto specs that are pending - Disabled int `xml:"disabled,attr"` - // Skiped maps onto specs that are skipped - Skipped int `xml:"skipped,attr"` - // Errors maps onto specs that panicked or were interrupted - Errors int `xml:"errors,attr"` - // Failures maps onto specs that failed - Failures int `xml:"failures,attr"` - // Time is the time in seconds to execute all the test suite - maps onto Report.RunTime - Time float64 `xml:"time,attr"` - // Timestamp is the ISO 8601 formatted start-time of the suite - maps onto Report.StartTime - Timestamp string `xml:"timestamp,attr"` - - //Properties captures the information stored in the rest of the Report type (including SuiteConfig) as key-value pairs - Properties JUnitProperties `xml:"properties"` - - //TestCases capture the individual specs - TestCases []JUnitTestCase `xml:"testcase"` -} - -type JUnitProperties struct { - Properties []JUnitProperty `xml:"property"` -} - -func (jup JUnitProperties) WithName(name string) string { - for _, property := range jup.Properties { - if property.Name == name { - return property.Value - } - } - return "" -} - -type JUnitProperty struct { - Name string `xml:"name,attr"` - Value string `xml:"value,attr"` -} - -var ownerRE = regexp.MustCompile(`(?i)^owner:(.*)$`) - -type JUnitTestCase struct { - // Name maps onto the full text of the spec - equivalent to "[SpecReport.LeafNodeType] SpecReport.FullText()" - Name string `xml:"name,attr"` - // Classname maps onto the name of the test suite - equivalent to Report.SuiteDescription - Classname string `xml:"classname,attr"` - // Status maps onto the string representation of SpecReport.State - Status string `xml:"status,attr"` - // Time is the time in seconds to execute the spec - maps onto SpecReport.RunTime - Time float64 `xml:"time,attr"` - // Owner is the owner the spec - is set if a label matching Label("owner:X") is provided. The last matching label is used as the owner, thereby allowing specs to override owners specified in container nodes. - Owner string `xml:"owner,attr,omitempty"` - //Skipped is populated with a message if the test was skipped or pending - Skipped *JUnitSkipped `xml:"skipped,omitempty"` - //Error is populated if the test panicked or was interrupted - Error *JUnitError `xml:"error,omitempty"` - //Failure is populated if the test failed - Failure *JUnitFailure `xml:"failure,omitempty"` - //SystemOut maps onto any captured stdout/stderr output - maps onto SpecReport.CapturedStdOutErr - SystemOut string `xml:"system-out,omitempty"` - //SystemOut maps onto any captured GinkgoWriter output - maps onto SpecReport.CapturedGinkgoWriterOutput - SystemErr string `xml:"system-err,omitempty"` -} - -type JUnitSkipped struct { - // Message maps onto "pending" if the test was marked pending, "skipped" if the test was marked skipped, and "skipped - REASON" if the user called Skip(REASON) - Message string `xml:"message,attr"` -} - -type JUnitError struct { - //Message maps onto the panic/exception thrown - equivalent to SpecReport.Failure.ForwardedPanic - or to "interrupted" - Message string `xml:"message,attr"` - //Type is one of "panicked" or "interrupted" - Type string `xml:"type,attr"` - //Description maps onto the captured stack trace for a panic, or the failure message for an interrupt which will include the dump of running goroutines - Description string `xml:",chardata"` -} - -type JUnitFailure struct { - //Message maps onto the failure message - equivalent to SpecReport.Failure.Message - Message string `xml:"message,attr"` - //Type is "failed" - Type string `xml:"type,attr"` - //Description maps onto the location and stack trace of the failure - Description string `xml:",chardata"` -} - -func GenerateJUnitReport(report types.Report, dst string) error { - return GenerateJUnitReportWithConfig(report, dst, JunitReportConfig{}) -} - -func GenerateJUnitReportWithConfig(report types.Report, dst string, config JunitReportConfig) error { - suite := JUnitTestSuite{ - Name: report.SuiteDescription, - Package: report.SuitePath, - Time: report.RunTime.Seconds(), - Timestamp: report.StartTime.Format("2006-01-02T15:04:05"), - Properties: JUnitProperties{ - Properties: []JUnitProperty{ - {"SuiteSucceeded", fmt.Sprintf("%t", report.SuiteSucceeded)}, - {"SuiteHasProgrammaticFocus", fmt.Sprintf("%t", report.SuiteHasProgrammaticFocus)}, - {"SpecialSuiteFailureReason", strings.Join(report.SpecialSuiteFailureReasons, ",")}, - {"SuiteLabels", fmt.Sprintf("[%s]", strings.Join(report.SuiteLabels, ","))}, - {"RandomSeed", fmt.Sprintf("%d", report.SuiteConfig.RandomSeed)}, - {"RandomizeAllSpecs", fmt.Sprintf("%t", report.SuiteConfig.RandomizeAllSpecs)}, - {"LabelFilter", report.SuiteConfig.LabelFilter}, - {"FocusStrings", strings.Join(report.SuiteConfig.FocusStrings, ",")}, - {"SkipStrings", strings.Join(report.SuiteConfig.SkipStrings, ",")}, - {"FocusFiles", strings.Join(report.SuiteConfig.FocusFiles, ";")}, - {"SkipFiles", strings.Join(report.SuiteConfig.SkipFiles, ";")}, - {"FailOnPending", fmt.Sprintf("%t", report.SuiteConfig.FailOnPending)}, - {"FailOnEmpty", fmt.Sprintf("%t", report.SuiteConfig.FailOnEmpty)}, - {"FailFast", fmt.Sprintf("%t", report.SuiteConfig.FailFast)}, - {"FlakeAttempts", fmt.Sprintf("%d", report.SuiteConfig.FlakeAttempts)}, - {"DryRun", fmt.Sprintf("%t", report.SuiteConfig.DryRun)}, - {"ParallelTotal", fmt.Sprintf("%d", report.SuiteConfig.ParallelTotal)}, - {"OutputInterceptorMode", report.SuiteConfig.OutputInterceptorMode}, - }, - }, - } - for _, spec := range report.SpecReports { - if config.OmitSuiteSetupNodes && spec.LeafNodeType != types.NodeTypeIt { - continue - } - name := fmt.Sprintf("[%s]", spec.LeafNodeType) - if config.OmitLeafNodeType { - name = "" - } - if spec.FullText() != "" { - name = name + " " + spec.FullText() - } - labels := spec.Labels() - if len(labels) > 0 && !config.OmitSpecLabels { - name = name + " [" + strings.Join(labels, ", ") + "]" - } - owner := "" - for _, label := range labels { - if matches := ownerRE.FindStringSubmatch(label); len(matches) == 2 { - owner = matches[1] - } - } - name = strings.TrimSpace(name) - - test := JUnitTestCase{ - Name: name, - Classname: report.SuiteDescription, - Status: spec.State.String(), - Time: spec.RunTime.Seconds(), - Owner: owner, - } - if !spec.State.Is(config.OmitTimelinesForSpecState) { - test.SystemErr = systemErrForUnstructuredReporters(spec) - } - if !config.OmitCapturedStdOutErr { - test.SystemOut = systemOutForUnstructuredReporters(spec) - } - suite.Tests += 1 - - switch spec.State { - case types.SpecStateSkipped: - message := "skipped" - if spec.Failure.Message != "" { - message += " - " + spec.Failure.Message - } - test.Skipped = &JUnitSkipped{Message: message} - suite.Skipped += 1 - case types.SpecStatePending: - test.Skipped = &JUnitSkipped{Message: "pending"} - suite.Disabled += 1 - case types.SpecStateFailed: - test.Failure = &JUnitFailure{ - Message: spec.Failure.Message, - Type: "failed", - Description: failureDescriptionForUnstructuredReporters(spec), - } - if config.OmitFailureMessageAttr { - test.Failure.Message = "" - } - suite.Failures += 1 - case types.SpecStateTimedout: - test.Failure = &JUnitFailure{ - Message: spec.Failure.Message, - Type: "timedout", - Description: failureDescriptionForUnstructuredReporters(spec), - } - if config.OmitFailureMessageAttr { - test.Failure.Message = "" - } - suite.Failures += 1 - case types.SpecStateInterrupted: - test.Error = &JUnitError{ - Message: spec.Failure.Message, - Type: "interrupted", - Description: failureDescriptionForUnstructuredReporters(spec), - } - if config.OmitFailureMessageAttr { - test.Error.Message = "" - } - suite.Errors += 1 - case types.SpecStateAborted: - test.Failure = &JUnitFailure{ - Message: spec.Failure.Message, - Type: "aborted", - Description: failureDescriptionForUnstructuredReporters(spec), - } - if config.OmitFailureMessageAttr { - test.Failure.Message = "" - } - suite.Errors += 1 - case types.SpecStatePanicked: - test.Error = &JUnitError{ - Message: spec.Failure.ForwardedPanic, - Type: "panicked", - Description: failureDescriptionForUnstructuredReporters(spec), - } - if config.OmitFailureMessageAttr { - test.Error.Message = "" - } - suite.Errors += 1 - } - - suite.TestCases = append(suite.TestCases, test) - } - - junitReport := JUnitTestSuites{ - Tests: suite.Tests, - Disabled: suite.Disabled + suite.Skipped, - Errors: suite.Errors, - Failures: suite.Failures, - Time: suite.Time, - TestSuites: []JUnitTestSuite{suite}, - } - - if err := os.MkdirAll(path.Dir(dst), 0770); err != nil { - return err - } - f, err := os.Create(dst) - if err != nil { - return err - } - f.WriteString(xml.Header) - encoder := xml.NewEncoder(f) - encoder.Indent(" ", " ") - encoder.Encode(junitReport) - - return f.Close() -} - -func MergeAndCleanupJUnitReports(sources []string, dst string) ([]string, error) { - messages := []string{} - mergedReport := JUnitTestSuites{} - for _, source := range sources { - report := JUnitTestSuites{} - f, err := os.Open(source) - if err != nil { - messages = append(messages, fmt.Sprintf("Could not open %s:\n%s", source, err.Error())) - continue - } - err = xml.NewDecoder(f).Decode(&report) - _ = f.Close() - if err != nil { - messages = append(messages, fmt.Sprintf("Could not decode %s:\n%s", source, err.Error())) - continue - } - os.Remove(source) - - mergedReport.Tests += report.Tests - mergedReport.Disabled += report.Disabled - mergedReport.Errors += report.Errors - mergedReport.Failures += report.Failures - mergedReport.Time += report.Time - mergedReport.TestSuites = append(mergedReport.TestSuites, report.TestSuites...) - } - - if err := os.MkdirAll(path.Dir(dst), 0770); err != nil { - return messages, err - } - f, err := os.Create(dst) - if err != nil { - return messages, err - } - f.WriteString(xml.Header) - encoder := xml.NewEncoder(f) - encoder.Indent(" ", " ") - encoder.Encode(mergedReport) - - return messages, f.Close() -} - -func failureDescriptionForUnstructuredReporters(spec types.SpecReport) string { - out := &strings.Builder{} - NewDefaultReporter(types.ReporterConfig{NoColor: true, VeryVerbose: true}, out).emitFailure(0, spec.State, spec.Failure, true) - if len(spec.AdditionalFailures) > 0 { - out.WriteString("\nThere were additional failures detected after the initial failure. These are visible in the timeline\n") - } - return out.String() -} - -func systemErrForUnstructuredReporters(spec types.SpecReport) string { - return RenderTimeline(spec, true) -} - -func RenderTimeline(spec types.SpecReport, noColor bool) string { - out := &strings.Builder{} - NewDefaultReporter(types.ReporterConfig{NoColor: noColor, VeryVerbose: true}, out).emitTimeline(0, spec, spec.Timeline()) - return out.String() -} - -func systemOutForUnstructuredReporters(spec types.SpecReport) string { - return spec.CapturedStdOutErr -} - -// Deprecated JUnitReporter (so folks can still compile their suites) -type JUnitReporter struct{} - -func NewJUnitReporter(_ string) *JUnitReporter { return &JUnitReporter{} } -func (reporter *JUnitReporter) SuiteWillBegin(_ config.GinkgoConfigType, _ *types.SuiteSummary) {} -func (reporter *JUnitReporter) BeforeSuiteDidRun(_ *types.SetupSummary) {} -func (reporter *JUnitReporter) SpecWillRun(_ *types.SpecSummary) {} -func (reporter *JUnitReporter) SpecDidComplete(_ *types.SpecSummary) {} -func (reporter *JUnitReporter) AfterSuiteDidRun(_ *types.SetupSummary) {} -func (reporter *JUnitReporter) SuiteDidEnd(_ *types.SuiteSummary) {} diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go deleted file mode 100644 index 5e726c46..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go +++ /dev/null @@ -1,29 +0,0 @@ -package reporters - -import ( - "github.com/onsi/ginkgo/v2/types" -) - -type Reporter interface { - SuiteWillBegin(report types.Report) - WillRun(report types.SpecReport) - DidRun(report types.SpecReport) - SuiteDidEnd(report types.Report) - - //Timeline emission - EmitFailure(state types.SpecState, failure types.Failure) - EmitProgressReport(progressReport types.ProgressReport) - EmitReportEntry(entry types.ReportEntry) - EmitSpecEvent(event types.SpecEvent) -} - -type NoopReporter struct{} - -func (n NoopReporter) SuiteWillBegin(report types.Report) {} -func (n NoopReporter) WillRun(report types.SpecReport) {} -func (n NoopReporter) DidRun(report types.SpecReport) {} -func (n NoopReporter) SuiteDidEnd(report types.Report) {} -func (n NoopReporter) EmitFailure(state types.SpecState, failure types.Failure) {} -func (n NoopReporter) EmitProgressReport(progressReport types.ProgressReport) {} -func (n NoopReporter) EmitReportEntry(entry types.ReportEntry) {} -func (n NoopReporter) EmitSpecEvent(event types.SpecEvent) {} diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go deleted file mode 100644 index e990ad82..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go +++ /dev/null @@ -1,105 +0,0 @@ -/* - -TeamCity Reporter for Ginkgo - -Makes use of TeamCity's support for Service Messages -http://confluence.jetbrains.com/display/TCD7/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingTests -*/ - -package reporters - -import ( - "fmt" - "os" - "path" - "strings" - - "github.com/onsi/ginkgo/v2/types" -) - -func tcEscape(s string) string { - s = strings.ReplaceAll(s, "|", "||") - s = strings.ReplaceAll(s, "'", "|'") - s = strings.ReplaceAll(s, "\n", "|n") - s = strings.ReplaceAll(s, "\r", "|r") - s = strings.ReplaceAll(s, "[", "|[") - s = strings.ReplaceAll(s, "]", "|]") - return s -} - -func GenerateTeamcityReport(report types.Report, dst string) error { - if err := os.MkdirAll(path.Dir(dst), 0770); err != nil { - return err - } - f, err := os.Create(dst) - if err != nil { - return err - } - - name := report.SuiteDescription - labels := report.SuiteLabels - if len(labels) > 0 { - name = name + " [" + strings.Join(labels, ", ") + "]" - } - fmt.Fprintf(f, "##teamcity[testSuiteStarted name='%s']\n", tcEscape(name)) - for _, spec := range report.SpecReports { - name := fmt.Sprintf("[%s]", spec.LeafNodeType) - if spec.FullText() != "" { - name = name + " " + spec.FullText() - } - labels := spec.Labels() - if len(labels) > 0 { - name = name + " [" + strings.Join(labels, ", ") + "]" - } - - name = tcEscape(name) - fmt.Fprintf(f, "##teamcity[testStarted name='%s']\n", name) - switch spec.State { - case types.SpecStatePending: - fmt.Fprintf(f, "##teamcity[testIgnored name='%s' message='pending']\n", name) - case types.SpecStateSkipped: - message := "skipped" - if spec.Failure.Message != "" { - message += " - " + spec.Failure.Message - } - fmt.Fprintf(f, "##teamcity[testIgnored name='%s' message='%s']\n", name, tcEscape(message)) - case types.SpecStateFailed: - details := failureDescriptionForUnstructuredReporters(spec) - fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='failed - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) - case types.SpecStatePanicked: - details := failureDescriptionForUnstructuredReporters(spec) - fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='panicked - %s' details='%s']\n", name, tcEscape(spec.Failure.ForwardedPanic), tcEscape(details)) - case types.SpecStateTimedout: - details := failureDescriptionForUnstructuredReporters(spec) - fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='timedout - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) - case types.SpecStateInterrupted: - details := failureDescriptionForUnstructuredReporters(spec) - fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='interrupted - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) - case types.SpecStateAborted: - details := failureDescriptionForUnstructuredReporters(spec) - fmt.Fprintf(f, "##teamcity[testFailed name='%s' message='aborted - %s' details='%s']\n", name, tcEscape(spec.Failure.Message), tcEscape(details)) - } - - fmt.Fprintf(f, "##teamcity[testStdOut name='%s' out='%s']\n", name, tcEscape(systemOutForUnstructuredReporters(spec))) - fmt.Fprintf(f, "##teamcity[testStdErr name='%s' out='%s']\n", name, tcEscape(systemErrForUnstructuredReporters(spec))) - fmt.Fprintf(f, "##teamcity[testFinished name='%s' duration='%d']\n", name, int(spec.RunTime.Seconds()*1000.0)) - } - fmt.Fprintf(f, "##teamcity[testSuiteFinished name='%s']\n", tcEscape(report.SuiteDescription)) - - return f.Close() -} - -func MergeAndCleanupTeamcityReports(sources []string, dst string) ([]string, error) { - messages := []string{} - merged := []byte{} - for _, source := range sources { - data, err := os.ReadFile(source) - if err != nil { - messages = append(messages, fmt.Sprintf("Could not open %s:\n%s", source, err.Error())) - continue - } - os.Remove(source) - merged = append(merged, data...) - } - return messages, os.WriteFile(dst, merged, 0666) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/code_location.go b/vendor/github.com/onsi/ginkgo/v2/types/code_location.go deleted file mode 100644 index 57e87517..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/code_location.go +++ /dev/null @@ -1,159 +0,0 @@ -package types - -import ( - "fmt" - "os" - "regexp" - "runtime" - "runtime/debug" - "strings" - "sync" -) - -type CodeLocation struct { - FileName string `json:",omitempty"` - LineNumber int `json:",omitempty"` - FullStackTrace string `json:",omitempty"` - CustomMessage string `json:",omitempty"` -} - -func (codeLocation CodeLocation) String() string { - if codeLocation.CustomMessage != "" { - return codeLocation.CustomMessage - } - return fmt.Sprintf("%s:%d", codeLocation.FileName, codeLocation.LineNumber) -} - -func (codeLocation CodeLocation) ContentsOfLine() string { - if codeLocation.CustomMessage != "" { - return "" - } - contents, err := os.ReadFile(codeLocation.FileName) - if err != nil { - return "" - } - lines := strings.Split(string(contents), "\n") - if len(lines) < codeLocation.LineNumber { - return "" - } - return lines[codeLocation.LineNumber-1] -} - -type codeLocationLocator struct { - pcs map[uintptr]bool - helpers map[string]bool - lock *sync.Mutex -} - -func (c *codeLocationLocator) addHelper(pc uintptr) { - c.lock.Lock() - defer c.lock.Unlock() - - if c.pcs[pc] { - return - } - c.lock.Unlock() - f := runtime.FuncForPC(pc) - c.lock.Lock() - if f == nil { - return - } - c.helpers[f.Name()] = true - c.pcs[pc] = true -} - -func (c *codeLocationLocator) hasHelper(name string) bool { - c.lock.Lock() - defer c.lock.Unlock() - return c.helpers[name] -} - -func (c *codeLocationLocator) getCodeLocation(skip int) CodeLocation { - pc := make([]uintptr, 40) - n := runtime.Callers(skip+2, pc) - if n == 0 { - return CodeLocation{} - } - pc = pc[:n] - frames := runtime.CallersFrames(pc) - for { - frame, more := frames.Next() - if !c.hasHelper(frame.Function) { - return CodeLocation{FileName: frame.File, LineNumber: frame.Line} - } - if !more { - break - } - } - return CodeLocation{} -} - -var clLocator = &codeLocationLocator{ - pcs: map[uintptr]bool{}, - helpers: map[string]bool{}, - lock: &sync.Mutex{}, -} - -// MarkAsHelper is used by GinkgoHelper to mark the caller (appropriately offset by skip)as a helper. You can use this directly if you need to provide an optional `skip` to mark functions further up the call stack as helpers. -func MarkAsHelper(optionalSkip ...int) { - skip := 1 - if len(optionalSkip) > 0 { - skip += optionalSkip[0] - } - pc, _, _, ok := runtime.Caller(skip) - if ok { - clLocator.addHelper(pc) - } -} - -func NewCustomCodeLocation(message string) CodeLocation { - return CodeLocation{ - CustomMessage: message, - } -} - -func NewCodeLocation(skip int) CodeLocation { - return clLocator.getCodeLocation(skip + 1) -} - -func NewCodeLocationWithStackTrace(skip int) CodeLocation { - cl := clLocator.getCodeLocation(skip + 1) - cl.FullStackTrace = PruneStack(string(debug.Stack()), skip+1) - return cl -} - -// PruneStack removes references to functions that are internal to Ginkgo -// and the Go runtime from a stack string and a certain number of stack entries -// at the beginning of the stack. The stack string has the format -// as returned by runtime/debug.Stack. The leading goroutine information is -// optional and always removed if present. Beware that runtime/debug.Stack -// adds itself as first entry, so typically skip must be >= 1 to remove that -// entry. -func PruneStack(fullStackTrace string, skip int) string { - stack := strings.Split(fullStackTrace, "\n") - // Ensure that the even entries are the method names and the - // odd entries the source code information. - if len(stack) > 0 && strings.HasPrefix(stack[0], "goroutine ") { - // Ignore "goroutine 29 [running]:" line. - stack = stack[1:] - } - // The "+1" is for skipping over the initial entry, which is - // runtime/debug.Stack() itself. - if len(stack) > 2*(skip+1) { - stack = stack[2*(skip+1):] - } - prunedStack := []string{} - if os.Getenv("GINKGO_PRUNE_STACK") == "FALSE" { - prunedStack = stack - } else { - re := regexp.MustCompile(`\/ginkgo\/|\/pkg\/testing\/|\/pkg\/runtime\/`) - for i := 0; i < len(stack)/2; i++ { - // We filter out based on the source code file name. - if !re.MatchString(stack[i*2+1]) { - prunedStack = append(prunedStack, stack[i*2]) - prunedStack = append(prunedStack, stack[i*2+1]) - } - } - } - return strings.Join(prunedStack, "\n") -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/config.go b/vendor/github.com/onsi/ginkgo/v2/types/config.go deleted file mode 100644 index 2e827efe..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/config.go +++ /dev/null @@ -1,804 +0,0 @@ -/* -Ginkgo accepts a number of configuration options. -These are documented [here](http://onsi.github.io/ginkgo/#the-ginkgo-cli) -*/ - -package types - -import ( - "flag" - "os" - "path/filepath" - "runtime" - "strconv" - "strings" - "time" -) - -// Configuration controlling how an individual test suite is run -type SuiteConfig struct { - RandomSeed int64 - RandomizeAllSpecs bool - FocusStrings []string - SkipStrings []string - FocusFiles []string - SkipFiles []string - LabelFilter string - FailOnPending bool - FailOnEmpty bool - FailFast bool - FlakeAttempts int - MustPassRepeatedly int - DryRun bool - PollProgressAfter time.Duration - PollProgressInterval time.Duration - Timeout time.Duration - EmitSpecProgress bool // this is deprecated but its removal is causing compile issue for some users that were setting it manually - OutputInterceptorMode string - SourceRoots []string - GracePeriod time.Duration - - ParallelProcess int - ParallelTotal int - ParallelHost string -} - -func NewDefaultSuiteConfig() SuiteConfig { - return SuiteConfig{ - RandomSeed: time.Now().Unix(), - Timeout: time.Hour, - ParallelProcess: 1, - ParallelTotal: 1, - GracePeriod: 30 * time.Second, - } -} - -type VerbosityLevel uint - -const ( - VerbosityLevelSuccinct VerbosityLevel = iota - VerbosityLevelNormal - VerbosityLevelVerbose - VerbosityLevelVeryVerbose -) - -func (vl VerbosityLevel) GT(comp VerbosityLevel) bool { - return vl > comp -} - -func (vl VerbosityLevel) GTE(comp VerbosityLevel) bool { - return vl >= comp -} - -func (vl VerbosityLevel) Is(comp VerbosityLevel) bool { - return vl == comp -} - -func (vl VerbosityLevel) LTE(comp VerbosityLevel) bool { - return vl <= comp -} - -func (vl VerbosityLevel) LT(comp VerbosityLevel) bool { - return vl < comp -} - -// Configuration for Ginkgo's reporter -type ReporterConfig struct { - NoColor bool - Succinct bool - Verbose bool - VeryVerbose bool - FullTrace bool - ShowNodeEvents bool - GithubOutput bool - SilenceSkips bool - ForceNewlines bool - - JSONReport string - JUnitReport string - TeamcityReport string -} - -func (rc ReporterConfig) Verbosity() VerbosityLevel { - if rc.Succinct { - return VerbosityLevelSuccinct - } else if rc.Verbose { - return VerbosityLevelVerbose - } else if rc.VeryVerbose { - return VerbosityLevelVeryVerbose - } - return VerbosityLevelNormal -} - -func (rc ReporterConfig) WillGenerateReport() bool { - return rc.JSONReport != "" || rc.JUnitReport != "" || rc.TeamcityReport != "" -} - -func NewDefaultReporterConfig() ReporterConfig { - return ReporterConfig{} -} - -// Configuration for the Ginkgo CLI -type CLIConfig struct { - //for build, run, and watch - Recurse bool - SkipPackage string - RequireSuite bool - NumCompilers int - - //for run and watch only - Procs int - Parallel bool - AfterRunHook string - OutputDir string - KeepSeparateCoverprofiles bool - KeepSeparateReports bool - - //for run only - KeepGoing bool - UntilItFails bool - Repeat int - RandomizeSuites bool - - //for watch only - Depth int - WatchRegExp string -} - -func NewDefaultCLIConfig() CLIConfig { - return CLIConfig{ - Depth: 1, - WatchRegExp: `\.go$`, - } -} - -func (g CLIConfig) ComputedProcs() int { - if g.Procs > 0 { - return g.Procs - } - - n := 1 - if g.Parallel { - n = runtime.GOMAXPROCS(-1) - if n > 4 { - n = n - 1 - } - } - return n -} - -func (g CLIConfig) ComputedNumCompilers() int { - if g.NumCompilers > 0 { - return g.NumCompilers - } - - return runtime.GOMAXPROCS(-1) -} - -// Configuration for the Ginkgo CLI capturing available go flags -// A subset of Go flags are exposed by Ginkgo. Some are available at compile time (e.g. ginkgo build) and others only at run time (e.g. ginkgo run - which has both build and run time flags). -// More details can be found at: -// https://docs.google.com/spreadsheets/d/1zkp-DS4hU4sAJl5eHh1UmgwxCPQhf3s5a8fbiOI8tJU/ -type GoFlagsConfig struct { - //build-time flags for code-and-performance analysis - Race bool - Cover bool - CoverMode string - CoverPkg string - Vet string - - //run-time flags for code-and-performance analysis - BlockProfile string - BlockProfileRate int - CoverProfile string - CPUProfile string - MemProfile string - MemProfileRate int - MutexProfile string - MutexProfileFraction int - Trace string - - //build-time flags for building - A bool - ASMFlags string - BuildMode string - BuildVCS bool - Compiler string - GCCGoFlags string - GCFlags string - InstallSuffix string - LDFlags string - LinkShared bool - Mod string - N bool - ModFile string - ModCacheRW bool - MSan bool - PkgDir string - Tags string - TrimPath bool - ToolExec string - Work bool - X bool - O string -} - -func NewDefaultGoFlagsConfig() GoFlagsConfig { - return GoFlagsConfig{} -} - -func (g GoFlagsConfig) BinaryMustBePreserved() bool { - return g.BlockProfile != "" || g.CPUProfile != "" || g.MemProfile != "" || g.MutexProfile != "" -} - -func (g GoFlagsConfig) NeedsSymbols() bool { - return g.BinaryMustBePreserved() -} - -// Configuration that were deprecated in 2.0 -type deprecatedConfig struct { - DebugParallel bool - NoisySkippings bool - NoisyPendings bool - RegexScansFilePath bool - SlowSpecThresholdWithFLoatUnits float64 - Stream bool - Notify bool - EmitSpecProgress bool - SlowSpecThreshold time.Duration - AlwaysEmitGinkgoWriter bool -} - -// Flags - -// Flags sections used by both the CLI and the Ginkgo test process -var FlagSections = GinkgoFlagSections{ - {Key: "multiple-suites", Style: "{{dark-green}}", Heading: "Running Multiple Test Suites"}, - {Key: "order", Style: "{{green}}", Heading: "Controlling Test Order"}, - {Key: "parallel", Style: "{{yellow}}", Heading: "Controlling Test Parallelism"}, - {Key: "low-level-parallel", Style: "{{yellow}}", Heading: "Controlling Test Parallelism", - Description: "These are set by the Ginkgo CLI, {{red}}{{bold}}do not set them manually{{/}} via go test.\nUse ginkgo -p or ginkgo -procs=N instead."}, - {Key: "filter", Style: "{{cyan}}", Heading: "Filtering Tests"}, - {Key: "failure", Style: "{{red}}", Heading: "Failure Handling"}, - {Key: "output", Style: "{{magenta}}", Heading: "Controlling Output Formatting"}, - {Key: "code-and-coverage-analysis", Style: "{{orange}}", Heading: "Code and Coverage Analysis", - Description: "When generating a cover files, please pass a filename {{bold}}not{{/}} a path. To specify a different directory use {{magenta}}--output-dir{{/}}.", - }, - {Key: "performance-analysis", Style: "{{coral}}", Heading: "Performance Analysis", - Description: "When generating profile files, please pass filenames {{bold}}not{{/}} a path. Ginkgo will generate a profile file with the given name in the package's directory. To specify a different directory use {{magenta}}--output-dir{{/}}.", - }, - {Key: "debug", Style: "{{blue}}", Heading: "Debugging Tests", - Description: "In addition to these flags, Ginkgo supports a few debugging environment variables. To change the parallel server protocol set {{blue}}GINKGO_PARALLEL_PROTOCOL{{/}} to {{bold}}HTTP{{/}}. To avoid pruning callstacks set {{blue}}GINKGO_PRUNE_STACK{{/}} to {{bold}}FALSE{{/}}."}, - {Key: "watch", Style: "{{light-yellow}}", Heading: "Controlling Ginkgo Watch"}, - {Key: "misc", Style: "{{light-gray}}", Heading: "Miscellaneous"}, - {Key: "go-build", Style: "{{light-gray}}", Heading: "Go Build Flags", Succinct: true, - Description: "These flags are inherited from go build. Run {{bold}}ginkgo help build{{/}} for more detailed flag documentation."}, -} - -// SuiteConfigFlags provides flags for the Ginkgo test process, and CLI -var SuiteConfigFlags = GinkgoFlags{ - {KeyPath: "S.RandomSeed", Name: "seed", SectionKey: "order", UsageDefaultValue: "randomly generated by Ginkgo", - Usage: "The seed used to randomize the spec suite.", AlwaysExport: true}, - {KeyPath: "S.RandomizeAllSpecs", Name: "randomize-all", SectionKey: "order", DeprecatedName: "randomizeAllSpecs", DeprecatedDocLink: "changed-command-line-flags", - Usage: "If set, ginkgo will randomize all specs together. By default, ginkgo only randomizes the top level Describe, Context and When containers."}, - - {KeyPath: "S.FailOnPending", Name: "fail-on-pending", SectionKey: "failure", DeprecatedName: "failOnPending", DeprecatedDocLink: "changed-command-line-flags", - Usage: "If set, ginkgo will mark the test suite as failed if any specs are pending."}, - {KeyPath: "S.FailFast", Name: "fail-fast", SectionKey: "failure", DeprecatedName: "failFast", DeprecatedDocLink: "changed-command-line-flags", - Usage: "If set, ginkgo will stop running a test suite after a failure occurs."}, - {KeyPath: "S.FlakeAttempts", Name: "flake-attempts", SectionKey: "failure", UsageDefaultValue: "0 - failed tests are not retried", DeprecatedName: "flakeAttempts", DeprecatedDocLink: "changed-command-line-flags", - Usage: "Make up to this many attempts to run each spec. If any of the attempts succeed, the suite will not be failed."}, - {KeyPath: "S.FailOnEmpty", Name: "fail-on-empty", SectionKey: "failure", - Usage: "If set, ginkgo will mark the test suite as failed if no specs are run."}, - - {KeyPath: "S.DryRun", Name: "dry-run", SectionKey: "debug", DeprecatedName: "dryRun", DeprecatedDocLink: "changed-command-line-flags", - Usage: "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v."}, - {KeyPath: "S.PollProgressAfter", Name: "poll-progress-after", SectionKey: "debug", UsageDefaultValue: "0", - Usage: "Emit node progress reports periodically if node hasn't completed after this duration."}, - {KeyPath: "S.PollProgressInterval", Name: "poll-progress-interval", SectionKey: "debug", UsageDefaultValue: "10s", - Usage: "The rate at which to emit node progress reports after poll-progress-after has elapsed."}, - {KeyPath: "S.SourceRoots", Name: "source-root", SectionKey: "debug", - Usage: "The location to look for source code when generating progress reports. You can pass multiple --source-root flags."}, - {KeyPath: "S.Timeout", Name: "timeout", SectionKey: "debug", UsageDefaultValue: "1h", - Usage: "Test suite fails if it does not complete within the specified timeout."}, - {KeyPath: "S.GracePeriod", Name: "grace-period", SectionKey: "debug", UsageDefaultValue: "30s", - Usage: "When interrupted, Ginkgo will wait for GracePeriod for the current running node to exit before moving on to the next one."}, - {KeyPath: "S.OutputInterceptorMode", Name: "output-interceptor-mode", SectionKey: "debug", UsageArgument: "dup, swap, or none", - Usage: "If set, ginkgo will use the specified output interception strategy when running in parallel. Defaults to dup on unix and swap on windows."}, - - {KeyPath: "S.LabelFilter", Name: "label-filter", SectionKey: "filter", UsageArgument: "expression", - Usage: "If set, ginkgo will only run specs with labels that match the label-filter. The passed-in expression can include boolean operations (!, &&, ||, ','), groupings via '()', and regular expressions '/regexp/'. e.g. '(cat || dog) && !fruit'"}, - {KeyPath: "S.FocusStrings", Name: "focus", SectionKey: "filter", - Usage: "If set, ginkgo will only run specs that match this regular expression. Can be specified multiple times, values are ORed."}, - {KeyPath: "S.SkipStrings", Name: "skip", SectionKey: "filter", - Usage: "If set, ginkgo will only run specs that do not match this regular expression. Can be specified multiple times, values are ORed."}, - {KeyPath: "S.FocusFiles", Name: "focus-file", SectionKey: "filter", UsageArgument: "file (regexp) | file:line | file:lineA-lineB | file:line,line,line", - Usage: "If set, ginkgo will only run specs in matching files. Can be specified multiple times, values are ORed."}, - {KeyPath: "S.SkipFiles", Name: "skip-file", SectionKey: "filter", UsageArgument: "file (regexp) | file:line | file:lineA-lineB | file:line,line,line", - Usage: "If set, ginkgo will skip specs in matching files. Can be specified multiple times, values are ORed."}, - - {KeyPath: "D.RegexScansFilePath", DeprecatedName: "regexScansFilePath", DeprecatedDocLink: "removed--regexscansfilepath", DeprecatedVersion: "2.0.0"}, - {KeyPath: "D.DebugParallel", DeprecatedName: "debug", DeprecatedDocLink: "removed--debug", DeprecatedVersion: "2.0.0"}, - {KeyPath: "D.EmitSpecProgress", DeprecatedName: "progress", SectionKey: "debug", - DeprecatedVersion: "2.5.0", Usage: ". The functionality provided by --progress was confusing and is no longer needed. Use --show-node-events instead to see node entry and exit events included in the timeline of failed and verbose specs. Or you can run with -vv to always see all node events. Lastly, --poll-progress-after and the PollProgressAfter decorator now provide a better mechanism for debugging specs that tend to get stuck."}, -} - -// ParallelConfigFlags provides flags for the Ginkgo test process (not the CLI) -var ParallelConfigFlags = GinkgoFlags{ - {KeyPath: "S.ParallelProcess", Name: "parallel.process", SectionKey: "low-level-parallel", UsageDefaultValue: "1", - Usage: "This worker process's (one-indexed) process number. For running specs in parallel."}, - {KeyPath: "S.ParallelTotal", Name: "parallel.total", SectionKey: "low-level-parallel", UsageDefaultValue: "1", - Usage: "The total number of worker processes. For running specs in parallel."}, - {KeyPath: "S.ParallelHost", Name: "parallel.host", SectionKey: "low-level-parallel", UsageDefaultValue: "set by Ginkgo CLI", - Usage: "The address for the server that will synchronize the processes."}, -} - -// ReporterConfigFlags provides flags for the Ginkgo test process, and CLI -var ReporterConfigFlags = GinkgoFlags{ - {KeyPath: "R.NoColor", Name: "no-color", SectionKey: "output", DeprecatedName: "noColor", DeprecatedDocLink: "changed-command-line-flags", - Usage: "If set, suppress color output in default reporter. You can also set the environment variable GINKGO_NO_COLOR=TRUE"}, - {KeyPath: "R.Verbose", Name: "v", SectionKey: "output", - Usage: "If set, emits more output including GinkgoWriter contents."}, - {KeyPath: "R.VeryVerbose", Name: "vv", SectionKey: "output", - Usage: "If set, emits with maximal verbosity - includes skipped and pending tests."}, - {KeyPath: "R.Succinct", Name: "succinct", SectionKey: "output", - Usage: "If set, default reporter prints out a very succinct report"}, - {KeyPath: "R.FullTrace", Name: "trace", SectionKey: "output", - Usage: "If set, default reporter prints out the full stack trace when a failure occurs"}, - {KeyPath: "R.ShowNodeEvents", Name: "show-node-events", SectionKey: "output", - Usage: "If set, default reporter prints node > Enter and < Exit events when specs fail"}, - {KeyPath: "R.GithubOutput", Name: "github-output", SectionKey: "output", - Usage: "If set, default reporter prints easier to manage output in Github Actions."}, - {KeyPath: "R.SilenceSkips", Name: "silence-skips", SectionKey: "output", - Usage: "If set, default reporter will not print out skipped tests."}, - {KeyPath: "R.ForceNewlines", Name: "force-newlines", SectionKey: "output", - Usage: "If set, default reporter will ensure a newline appears after each test."}, - - {KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output", - Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."}, - {KeyPath: "R.JUnitReport", Name: "junit-report", UsageArgument: "filename.xml", SectionKey: "output", DeprecatedName: "reportFile", DeprecatedDocLink: "improved-reporting-infrastructure", - Usage: "If set, Ginkgo will generate a conformant junit test report in the specified file."}, - {KeyPath: "R.TeamcityReport", Name: "teamcity-report", UsageArgument: "filename", SectionKey: "output", - Usage: "If set, Ginkgo will generate a Teamcity-formatted test report at the specified location."}, - - {KeyPath: "D.SlowSpecThresholdWithFLoatUnits", DeprecatedName: "slowSpecThreshold", DeprecatedDocLink: "changed--slowspecthreshold", - Usage: "use --slow-spec-threshold instead and pass in a duration string (e.g. '5s', not '5.0')"}, - {KeyPath: "D.NoisyPendings", DeprecatedName: "noisyPendings", DeprecatedDocLink: "removed--noisypendings-and--noisyskippings", DeprecatedVersion: "2.0.0"}, - {KeyPath: "D.NoisySkippings", DeprecatedName: "noisySkippings", DeprecatedDocLink: "removed--noisypendings-and--noisyskippings", DeprecatedVersion: "2.0.0"}, - {KeyPath: "D.SlowSpecThreshold", DeprecatedName: "slow-spec-threshold", SectionKey: "output", Usage: "--slow-spec-threshold has been deprecated and will be removed in a future version of Ginkgo. This feature has proved to be more noisy than useful. You can use --poll-progress-after, instead, to get more actionable feedback about potentially slow specs and understand where they might be getting stuck.", DeprecatedVersion: "2.5.0"}, - {KeyPath: "D.AlwaysEmitGinkgoWriter", DeprecatedName: "always-emit-ginkgo-writer", SectionKey: "output", Usage: " - use -v instead, or one of Ginkgo's machine-readable report formats to get GinkgoWriter output for passing specs."}, -} - -// BuildTestSuiteFlagSet attaches to the CommandLine flagset and provides flags for the Ginkgo test process -func BuildTestSuiteFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterConfig) (GinkgoFlagSet, error) { - flags := SuiteConfigFlags.CopyAppend(ParallelConfigFlags...).CopyAppend(ReporterConfigFlags...) - flags = flags.WithPrefix("ginkgo") - bindings := map[string]any{ - "S": suiteConfig, - "R": reporterConfig, - "D": &deprecatedConfig{}, - } - extraGoFlagsSection := GinkgoFlagSection{Style: "{{gray}}", Heading: "Go test flags"} - - return NewAttachedGinkgoFlagSet(flag.CommandLine, flags, bindings, FlagSections, extraGoFlagsSection) -} - -// VetConfig validates that the Ginkgo test process' configuration is sound -func VetConfig(flagSet GinkgoFlagSet, suiteConfig SuiteConfig, reporterConfig ReporterConfig) []error { - errors := []error{} - - if flagSet.WasSet("count") || flagSet.WasSet("test.count") { - flag := flagSet.Lookup("count") - if flag == nil { - flag = flagSet.Lookup("test.count") - } - count, err := strconv.Atoi(flag.Value.String()) - if err != nil || count != 1 { - errors = append(errors, GinkgoErrors.InvalidGoFlagCount()) - } - } - - if flagSet.WasSet("parallel") || flagSet.WasSet("test.parallel") { - errors = append(errors, GinkgoErrors.InvalidGoFlagParallel()) - } - - if suiteConfig.ParallelTotal < 1 { - errors = append(errors, GinkgoErrors.InvalidParallelTotalConfiguration()) - } - - if suiteConfig.ParallelProcess > suiteConfig.ParallelTotal || suiteConfig.ParallelProcess < 1 { - errors = append(errors, GinkgoErrors.InvalidParallelProcessConfiguration()) - } - - if suiteConfig.ParallelTotal > 1 && suiteConfig.ParallelHost == "" { - errors = append(errors, GinkgoErrors.MissingParallelHostConfiguration()) - } - - if suiteConfig.DryRun && suiteConfig.ParallelTotal > 1 { - errors = append(errors, GinkgoErrors.DryRunInParallelConfiguration()) - } - - if suiteConfig.GracePeriod <= 0 { - errors = append(errors, GinkgoErrors.GracePeriodCannotBeZero()) - } - - if len(suiteConfig.FocusFiles) > 0 { - _, err := ParseFileFilters(suiteConfig.FocusFiles) - if err != nil { - errors = append(errors, err) - } - } - - if len(suiteConfig.SkipFiles) > 0 { - _, err := ParseFileFilters(suiteConfig.SkipFiles) - if err != nil { - errors = append(errors, err) - } - } - - if suiteConfig.LabelFilter != "" { - _, err := ParseLabelFilter(suiteConfig.LabelFilter) - if err != nil { - errors = append(errors, err) - } - } - - switch strings.ToLower(suiteConfig.OutputInterceptorMode) { - case "", "dup", "swap", "none": - default: - errors = append(errors, GinkgoErrors.InvalidOutputInterceptorModeConfiguration(suiteConfig.OutputInterceptorMode)) - } - - numVerbosity := 0 - for _, v := range []bool{reporterConfig.Succinct, reporterConfig.Verbose, reporterConfig.VeryVerbose} { - if v { - numVerbosity++ - } - } - if numVerbosity > 1 { - errors = append(errors, GinkgoErrors.ConflictingVerbosityConfiguration()) - } - - return errors -} - -// GinkgoCLISharedFlags provides flags shared by the Ginkgo CLI's build, watch, and run commands -var GinkgoCLISharedFlags = GinkgoFlags{ - {KeyPath: "C.Recurse", Name: "r", SectionKey: "multiple-suites", - Usage: "If set, ginkgo finds and runs test suites under the current directory recursively."}, - {KeyPath: "C.SkipPackage", Name: "skip-package", SectionKey: "multiple-suites", DeprecatedName: "skipPackage", DeprecatedDocLink: "changed-command-line-flags", - UsageArgument: "comma-separated list of packages", - Usage: "A comma-separated list of package names to be skipped. If any part of the package's path matches, that package is ignored."}, - {KeyPath: "C.RequireSuite", Name: "require-suite", SectionKey: "failure", DeprecatedName: "requireSuite", DeprecatedDocLink: "changed-command-line-flags", - Usage: "If set, Ginkgo fails if there are ginkgo tests in a directory but no invocation of RunSpecs."}, - {KeyPath: "C.NumCompilers", Name: "compilers", SectionKey: "multiple-suites", UsageDefaultValue: "0 (will autodetect)", - Usage: "When running multiple packages, the number of concurrent compilations to perform."}, -} - -// GinkgoCLIRunAndWatchFlags provides flags shared by the Ginkgo CLI's build and watch commands (but not run) -var GinkgoCLIRunAndWatchFlags = GinkgoFlags{ - {KeyPath: "C.Procs", Name: "procs", SectionKey: "parallel", UsageDefaultValue: "1 (run in series)", - Usage: "The number of parallel test nodes to run."}, - {KeyPath: "C.Procs", Name: "nodes", SectionKey: "parallel", UsageDefaultValue: "1 (run in series)", - Usage: "--nodes is an alias for --procs"}, - {KeyPath: "C.Parallel", Name: "p", SectionKey: "parallel", - Usage: "If set, ginkgo will run in parallel with an auto-detected number of nodes."}, - {KeyPath: "C.AfterRunHook", Name: "after-run-hook", SectionKey: "misc", DeprecatedName: "afterSuiteHook", DeprecatedDocLink: "changed-command-line-flags", - Usage: "Command to run when a test suite completes."}, - {KeyPath: "C.OutputDir", Name: "output-dir", SectionKey: "output", UsageArgument: "directory", DeprecatedName: "outputdir", DeprecatedDocLink: "improved-profiling-support", - Usage: "A location to place all generated profiles and reports."}, - {KeyPath: "C.KeepSeparateCoverprofiles", Name: "keep-separate-coverprofiles", SectionKey: "code-and-coverage-analysis", - Usage: "If set, Ginkgo does not merge coverprofiles into one monolithic coverprofile. The coverprofiles will remain in their respective package directories or in -output-dir if set."}, - {KeyPath: "C.KeepSeparateReports", Name: "keep-separate-reports", SectionKey: "output", - Usage: "If set, Ginkgo does not merge per-suite reports (e.g. -json-report) into one monolithic report for the entire testrun. The reports will remain in their respective package directories or in -output-dir if set."}, - - {KeyPath: "D.Stream", DeprecatedName: "stream", DeprecatedDocLink: "removed--stream", DeprecatedVersion: "2.0.0"}, - {KeyPath: "D.Notify", DeprecatedName: "notify", DeprecatedDocLink: "removed--notify", DeprecatedVersion: "2.0.0"}, -} - -// GinkgoCLIRunFlags provides flags for Ginkgo CLI's run command that aren't shared by any other commands -var GinkgoCLIRunFlags = GinkgoFlags{ - {KeyPath: "C.KeepGoing", Name: "keep-going", SectionKey: "multiple-suites", DeprecatedName: "keepGoing", DeprecatedDocLink: "changed-command-line-flags", - Usage: "If set, failures from earlier test suites do not prevent later test suites from running."}, - {KeyPath: "C.UntilItFails", Name: "until-it-fails", SectionKey: "debug", DeprecatedName: "untilItFails", DeprecatedDocLink: "changed-command-line-flags", - Usage: "If set, ginkgo will keep rerunning test suites until a failure occurs."}, - {KeyPath: "C.Repeat", Name: "repeat", SectionKey: "debug", UsageArgument: "n", UsageDefaultValue: "0 - i.e. no repetition, run only once", - Usage: "The number of times to re-run a test-suite. Useful for debugging flaky tests. If set to N the suite will be run N+1 times and will be required to pass each time."}, - {KeyPath: "C.RandomizeSuites", Name: "randomize-suites", SectionKey: "order", DeprecatedName: "randomizeSuites", DeprecatedDocLink: "changed-command-line-flags", - Usage: "If set, ginkgo will randomize the order in which test suites run."}, -} - -// GinkgoCLIRunFlags provides flags for Ginkgo CLI's watch command that aren't shared by any other commands -var GinkgoCLIWatchFlags = GinkgoFlags{ - {KeyPath: "C.Depth", Name: "depth", SectionKey: "watch", - Usage: "Ginkgo will watch dependencies down to this depth in the dependency tree."}, - {KeyPath: "C.WatchRegExp", Name: "watch-regexp", SectionKey: "watch", DeprecatedName: "watchRegExp", DeprecatedDocLink: "changed-command-line-flags", - UsageArgument: "Regular Expression", - UsageDefaultValue: `\.go$`, - Usage: "Only files matching this regular expression will be watched for changes."}, -} - -// GoBuildFlags provides flags for the Ginkgo CLI build, run, and watch commands that capture go's build-time flags. These are passed to go test -c by the ginkgo CLI -var GoBuildFlags = GinkgoFlags{ - {KeyPath: "Go.Race", Name: "race", SectionKey: "code-and-coverage-analysis", - Usage: "enable data race detection. Supported on linux/amd64, linux/ppc64le, linux/arm64, linux/s390x, freebsd/amd64, netbsd/amd64, darwin/amd64, darwin/arm64, and windows/amd64."}, - {KeyPath: "Go.Vet", Name: "vet", UsageArgument: "list", SectionKey: "code-and-coverage-analysis", - Usage: `Configure the invocation of "go vet" during "go test" to use the comma-separated list of vet checks. If list is empty (by explicitly passing --vet=""), "go test" runs "go vet" with a curated list of checks believed to be always worth addressing. If list is "off", "go test" does not run "go vet" at all. Available checks can be found by running 'go doc cmd/vet'`}, - {KeyPath: "Go.Cover", Name: "cover", SectionKey: "code-and-coverage-analysis", - Usage: "Enable coverage analysis. Note that because coverage works by annotating the source code before compilation, compilation and test failures with coverage enabled may report line numbers that don't correspond to the original sources."}, - {KeyPath: "Go.CoverMode", Name: "covermode", UsageArgument: "set,count,atomic", SectionKey: "code-and-coverage-analysis", - Usage: `Set the mode for coverage analysis for the package[s] being tested. 'set': does this statement run? 'count': how many times does this statement run? 'atomic': like count, but correct in multithreaded tests and more expensive (must use atomic with -race). Sets -cover`}, - {KeyPath: "Go.CoverPkg", Name: "coverpkg", UsageArgument: "pattern1,pattern2,pattern3", SectionKey: "code-and-coverage-analysis", - Usage: "Apply coverage analysis in each test to packages matching the patterns. The default is for each test to analyze only the package being tested. See 'go help packages' for a description of package patterns. Sets -cover."}, - - {KeyPath: "Go.A", Name: "a", SectionKey: "go-build", - Usage: "force rebuilding of packages that are already up-to-date."}, - {KeyPath: "Go.ASMFlags", Name: "asmflags", UsageArgument: "'[pattern=]arg list'", SectionKey: "go-build", - Usage: "arguments to pass on each go tool asm invocation."}, - {KeyPath: "Go.BuildMode", Name: "buildmode", UsageArgument: "mode", SectionKey: "go-build", - Usage: "build mode to use. See 'go help buildmode' for more."}, - {KeyPath: "Go.BuildVCS", Name: "buildvcs", SectionKey: "go-build", - Usage: "adds version control information."}, - {KeyPath: "Go.Compiler", Name: "compiler", UsageArgument: "name", SectionKey: "go-build", - Usage: "name of compiler to use, as in runtime.Compiler (gccgo or gc)."}, - {KeyPath: "Go.GCCGoFlags", Name: "gccgoflags", UsageArgument: "'[pattern=]arg list'", SectionKey: "go-build", - Usage: "arguments to pass on each gccgo compiler/linker invocation."}, - {KeyPath: "Go.GCFlags", Name: "gcflags", UsageArgument: "'[pattern=]arg list'", SectionKey: "go-build", - Usage: "arguments to pass on each go tool compile invocation."}, - {KeyPath: "Go.InstallSuffix", Name: "installsuffix", SectionKey: "go-build", - Usage: "a suffix to use in the name of the package installation directory, in order to keep output separate from default builds. If using the -race flag, the install suffix is automatically set to raceor, if set explicitly, has _race appended to it. Likewise for the -msan flag. Using a -buildmode option that requires non-default compile flags has a similar effect."}, - {KeyPath: "Go.LDFlags", Name: "ldflags", UsageArgument: "'[pattern=]arg list'", SectionKey: "go-build", - Usage: "arguments to pass on each go tool link invocation."}, - {KeyPath: "Go.LinkShared", Name: "linkshared", SectionKey: "go-build", - Usage: "build code that will be linked against shared libraries previously created with -buildmode=shared."}, - {KeyPath: "Go.Mod", Name: "mod", UsageArgument: "mode (readonly, vendor, or mod)", SectionKey: "go-build", - Usage: "module download mode to use: readonly, vendor, or mod. See 'go help modules' for more."}, - {KeyPath: "Go.ModCacheRW", Name: "modcacherw", SectionKey: "go-build", - Usage: "leave newly-created directories in the module cache read-write instead of making them read-only."}, - {KeyPath: "Go.ModFile", Name: "modfile", UsageArgument: "file", SectionKey: "go-build", - Usage: `in module aware mode, read (and possibly write) an alternate go.mod file instead of the one in the module root directory. A file named go.mod must still be present in order to determine the module root directory, but it is not accessed. When -modfile is specified, an alternate go.sum file is also used: its path is derived from the -modfile flag by trimming the ".mod" extension and appending ".sum".`}, - {KeyPath: "Go.MSan", Name: "msan", SectionKey: "go-build", - Usage: "enable interoperation with memory sanitizer. Supported only on linux/amd64, linux/arm64 and only with Clang/LLVM as the host C compiler. On linux/arm64, pie build mode will be used."}, - {KeyPath: "Go.N", Name: "n", SectionKey: "go-build", - Usage: "print the commands but do not run them."}, - {KeyPath: "Go.PkgDir", Name: "pkgdir", UsageArgument: "dir", SectionKey: "go-build", - Usage: "install and load all packages from dir instead of the usual locations. For example, when building with a non-standard configuration, use -pkgdir to keep generated packages in a separate location."}, - {KeyPath: "Go.Tags", Name: "tags", UsageArgument: "tag,list", SectionKey: "go-build", - Usage: "a comma-separated list of build tags to consider satisfied during the build. For more information about build tags, see the description of build constraints in the documentation for the go/build package. (Earlier versions of Go used a space-separated list, and that form is deprecated but still recognized.)"}, - {KeyPath: "Go.TrimPath", Name: "trimpath", SectionKey: "go-build", - Usage: `remove all file system paths from the resulting executable. Instead of absolute file system paths, the recorded file names will begin with either "go" (for the standard library), or a module path@version (when using modules), or a plain import path (when using GOPATH).`}, - {KeyPath: "Go.ToolExec", Name: "toolexec", UsageArgument: "'cmd args'", SectionKey: "go-build", - Usage: "a program to use to invoke toolchain programs like vet and asm. For example, instead of running asm, the go command will run cmd args /path/to/asm '."}, - {KeyPath: "Go.Work", Name: "work", SectionKey: "go-build", - Usage: "print the name of the temporary work directory and do not delete it when exiting."}, - {KeyPath: "Go.X", Name: "x", SectionKey: "go-build", - Usage: "print the commands."}, - {KeyPath: "Go.O", Name: "o", SectionKey: "go-build", - Usage: "output binary path (including name)."}, -} - -// GoRunFlags provides flags for the Ginkgo CLI run, and watch commands that capture go's run-time flags. These are passed to the compiled test binary by the ginkgo CLI -var GoRunFlags = GinkgoFlags{ - {KeyPath: "Go.CoverProfile", Name: "coverprofile", UsageArgument: "file", SectionKey: "code-and-coverage-analysis", - Usage: `Write a coverage profile to the file after all tests have passed. Sets -cover. Must be passed a filename, not a path. Use output-dir to control the location of the output.`}, - {KeyPath: "Go.BlockProfile", Name: "blockprofile", UsageArgument: "file", SectionKey: "performance-analysis", - Usage: `Write a goroutine blocking profile to the specified file when all tests are complete. Preserves test binary.`}, - {KeyPath: "Go.BlockProfileRate", Name: "blockprofilerate", UsageArgument: "rate", SectionKey: "performance-analysis", - Usage: `Control the detail provided in goroutine blocking profiles by calling runtime.SetBlockProfileRate with rate. See 'go doc runtime.SetBlockProfileRate'. The profiler aims to sample, on average, one blocking event every n nanoseconds the program spends blocked. By default, if -test.blockprofile is set without this flag, all blocking events are recorded, equivalent to -test.blockprofilerate=1.`}, - {KeyPath: "Go.CPUProfile", Name: "cpuprofile", UsageArgument: "file", SectionKey: "performance-analysis", - Usage: `Write a CPU profile to the specified file before exiting. Preserves test binary.`}, - {KeyPath: "Go.MemProfile", Name: "memprofile", UsageArgument: "file", SectionKey: "performance-analysis", - Usage: `Write an allocation profile to the file after all tests have passed. Preserves test binary.`}, - {KeyPath: "Go.MemProfileRate", Name: "memprofilerate", UsageArgument: "rate", SectionKey: "performance-analysis", - Usage: `Enable more precise (and expensive) memory allocation profiles by setting runtime.MemProfileRate. See 'go doc runtime.MemProfileRate'. To profile all memory allocations, use -test.memprofilerate=1.`}, - {KeyPath: "Go.MutexProfile", Name: "mutexprofile", UsageArgument: "file", SectionKey: "performance-analysis", - Usage: `Write a mutex contention profile to the specified file when all tests are complete. Preserves test binary.`}, - {KeyPath: "Go.MutexProfileFraction", Name: "mutexprofilefraction", UsageArgument: "n", SectionKey: "performance-analysis", - Usage: `if >= 0, calls runtime.SetMutexProfileFraction() Sample 1 in n stack traces of goroutines holding a contended mutex.`}, - {KeyPath: "Go.Trace", Name: "execution-trace", UsageArgument: "file", ExportAs: "trace", SectionKey: "performance-analysis", - Usage: `Write an execution trace to the specified file before exiting.`}, -} - -// VetAndInitializeCLIAndGoConfig validates that the Ginkgo CLI's configuration is sound -// It returns a potentially mutated copy of the config that rationalizes the configuration to ensure consistency for downstream consumers -func VetAndInitializeCLIAndGoConfig(cliConfig CLIConfig, goFlagsConfig GoFlagsConfig) (CLIConfig, GoFlagsConfig, []error) { - errors := []error{} - - if cliConfig.Repeat > 0 && cliConfig.UntilItFails { - errors = append(errors, GinkgoErrors.BothRepeatAndUntilItFails()) - } - - if strings.ContainsRune(goFlagsConfig.CoverProfile, os.PathSeparator) { - errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--coverprofile", goFlagsConfig.CoverProfile)) - } - if strings.ContainsRune(goFlagsConfig.CPUProfile, os.PathSeparator) { - errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--cpuprofile", goFlagsConfig.CPUProfile)) - } - if strings.ContainsRune(goFlagsConfig.MemProfile, os.PathSeparator) { - errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--memprofile", goFlagsConfig.MemProfile)) - } - if strings.ContainsRune(goFlagsConfig.BlockProfile, os.PathSeparator) { - errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--blockprofile", goFlagsConfig.BlockProfile)) - } - if strings.ContainsRune(goFlagsConfig.MutexProfile, os.PathSeparator) { - errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--mutexprofile", goFlagsConfig.MutexProfile)) - } - - //initialize the output directory - if cliConfig.OutputDir != "" { - err := os.MkdirAll(cliConfig.OutputDir, 0777) - if err != nil { - errors = append(errors, err) - } - } - - //ensure cover mode is configured appropriately - if goFlagsConfig.CoverMode != "" || goFlagsConfig.CoverPkg != "" || goFlagsConfig.CoverProfile != "" { - goFlagsConfig.Cover = true - } - if goFlagsConfig.Cover && goFlagsConfig.CoverProfile == "" { - goFlagsConfig.CoverProfile = "coverprofile.out" - } - - return cliConfig, goFlagsConfig, errors -} - -// GenerateGoTestCompileArgs is used by the Ginkgo CLI to generate command line arguments to pass to the go test -c command when compiling the test -func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, packageToBuild string, pathToInvocationPath string, preserveSymbols bool) ([]string, error) { - // if the user has set the CoverProfile run-time flag make sure to set the build-time cover flag to make sure - // the built test binary can generate a coverprofile - if goFlagsConfig.CoverProfile != "" { - goFlagsConfig.Cover = true - } - - if goFlagsConfig.CoverPkg != "" { - coverPkgs := strings.Split(goFlagsConfig.CoverPkg, ",") - adjustedCoverPkgs := make([]string, len(coverPkgs)) - for i, coverPkg := range coverPkgs { - coverPkg = strings.Trim(coverPkg, " ") - if strings.HasPrefix(coverPkg, "./") { - // this is a relative coverPkg - we need to reroot it - adjustedCoverPkgs[i] = "./" + filepath.Join(pathToInvocationPath, strings.TrimPrefix(coverPkg, "./")) - } else { - // this is a package name - don't touch it - adjustedCoverPkgs[i] = coverPkg - } - } - goFlagsConfig.CoverPkg = strings.Join(adjustedCoverPkgs, ",") - } - - if !goFlagsConfig.NeedsSymbols() && goFlagsConfig.LDFlags == "" && !preserveSymbols { - goFlagsConfig.LDFlags = "-w -s" - } - - args := []string{"test", "-c", packageToBuild} - goArgs, err := GenerateFlagArgs( - GoBuildFlags, - map[string]any{ - "Go": &goFlagsConfig, - }, - ) - - if err != nil { - return []string{}, err - } - args = append(args, goArgs...) - return args, nil -} - -// GenerateGinkgoTestRunArgs is used by the Ginkgo CLI to generate command line arguments to pass to the compiled Ginkgo test binary -func GenerateGinkgoTestRunArgs(suiteConfig SuiteConfig, reporterConfig ReporterConfig, goFlagsConfig GoFlagsConfig) ([]string, error) { - var flags GinkgoFlags - flags = SuiteConfigFlags.WithPrefix("ginkgo") - flags = flags.CopyAppend(ParallelConfigFlags.WithPrefix("ginkgo")...) - flags = flags.CopyAppend(ReporterConfigFlags.WithPrefix("ginkgo")...) - flags = flags.CopyAppend(GoRunFlags.WithPrefix("test")...) - bindings := map[string]any{ - "S": &suiteConfig, - "R": &reporterConfig, - "Go": &goFlagsConfig, - } - - return GenerateFlagArgs(flags, bindings) -} - -// GenerateGoTestRunArgs is used by the Ginkgo CLI to generate command line arguments to pass to the compiled non-Ginkgo test binary -func GenerateGoTestRunArgs(goFlagsConfig GoFlagsConfig) ([]string, error) { - flags := GoRunFlags.WithPrefix("test") - bindings := map[string]any{ - "Go": &goFlagsConfig, - } - - args, err := GenerateFlagArgs(flags, bindings) - if err != nil { - return args, err - } - args = append(args, "--test.v") - return args, nil -} - -// BuildRunCommandFlagSet builds the FlagSet for the `ginkgo run` command -func BuildRunCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterConfig, cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig) (GinkgoFlagSet, error) { - flags := SuiteConfigFlags - flags = flags.CopyAppend(ReporterConfigFlags...) - flags = flags.CopyAppend(GinkgoCLISharedFlags...) - flags = flags.CopyAppend(GinkgoCLIRunAndWatchFlags...) - flags = flags.CopyAppend(GinkgoCLIRunFlags...) - flags = flags.CopyAppend(GoBuildFlags...) - flags = flags.CopyAppend(GoRunFlags...) - - bindings := map[string]any{ - "S": suiteConfig, - "R": reporterConfig, - "C": cliConfig, - "Go": goFlagsConfig, - "D": &deprecatedConfig{}, - } - - return NewGinkgoFlagSet(flags, bindings, FlagSections) -} - -// BuildWatchCommandFlagSet builds the FlagSet for the `ginkgo watch` command -func BuildWatchCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterConfig, cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig) (GinkgoFlagSet, error) { - flags := SuiteConfigFlags - flags = flags.CopyAppend(ReporterConfigFlags...) - flags = flags.CopyAppend(GinkgoCLISharedFlags...) - flags = flags.CopyAppend(GinkgoCLIRunAndWatchFlags...) - flags = flags.CopyAppend(GinkgoCLIWatchFlags...) - flags = flags.CopyAppend(GoBuildFlags...) - flags = flags.CopyAppend(GoRunFlags...) - - bindings := map[string]any{ - "S": suiteConfig, - "R": reporterConfig, - "C": cliConfig, - "Go": goFlagsConfig, - "D": &deprecatedConfig{}, - } - - return NewGinkgoFlagSet(flags, bindings, FlagSections) -} - -// BuildBuildCommandFlagSet builds the FlagSet for the `ginkgo build` command -func BuildBuildCommandFlagSet(cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig) (GinkgoFlagSet, error) { - flags := GinkgoCLISharedFlags - flags = flags.CopyAppend(GoBuildFlags...) - - bindings := map[string]any{ - "C": cliConfig, - "Go": goFlagsConfig, - "D": &deprecatedConfig{}, - } - - flagSections := make(GinkgoFlagSections, len(FlagSections)) - copy(flagSections, FlagSections) - for i := range flagSections { - if flagSections[i].Key == "multiple-suites" { - flagSections[i].Heading = "Building Multiple Suites" - } - if flagSections[i].Key == "go-build" { - flagSections[i] = GinkgoFlagSection{Key: "go-build", Style: "{{/}}", Heading: "Go Build Flags", - Description: "These flags are inherited from go build."} - } - } - - return NewGinkgoFlagSet(flags, bindings, flagSections) -} - -func BuildLabelsCommandFlagSet(cliConfig *CLIConfig) (GinkgoFlagSet, error) { - flags := GinkgoCLISharedFlags.SubsetWithNames("r", "skip-package") - - bindings := map[string]any{ - "C": cliConfig, - } - - flagSections := make(GinkgoFlagSections, len(FlagSections)) - copy(flagSections, FlagSections) - for i := range flagSections { - if flagSections[i].Key == "multiple-suites" { - flagSections[i].Heading = "Fetching Labels from Multiple Suites" - } - } - - return NewGinkgoFlagSet(flags, bindings, flagSections) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go b/vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go deleted file mode 100644 index 518989a8..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go +++ /dev/null @@ -1,141 +0,0 @@ -package types - -import ( - "strconv" - "time" -) - -/* - A set of deprecations to make the transition from v1 to v2 easier for users who have written custom reporters. -*/ - -type SuiteSummary = DeprecatedSuiteSummary -type SetupSummary = DeprecatedSetupSummary -type SpecSummary = DeprecatedSpecSummary -type SpecMeasurement = DeprecatedSpecMeasurement -type SpecComponentType = NodeType -type SpecFailure = DeprecatedSpecFailure - -var ( - SpecComponentTypeInvalid = NodeTypeInvalid - SpecComponentTypeContainer = NodeTypeContainer - SpecComponentTypeIt = NodeTypeIt - SpecComponentTypeBeforeEach = NodeTypeBeforeEach - SpecComponentTypeJustBeforeEach = NodeTypeJustBeforeEach - SpecComponentTypeAfterEach = NodeTypeAfterEach - SpecComponentTypeJustAfterEach = NodeTypeJustAfterEach - SpecComponentTypeBeforeSuite = NodeTypeBeforeSuite - SpecComponentTypeSynchronizedBeforeSuite = NodeTypeSynchronizedBeforeSuite - SpecComponentTypeAfterSuite = NodeTypeAfterSuite - SpecComponentTypeSynchronizedAfterSuite = NodeTypeSynchronizedAfterSuite -) - -type DeprecatedSuiteSummary struct { - SuiteDescription string - SuiteSucceeded bool - SuiteID string - - NumberOfSpecsBeforeParallelization int - NumberOfTotalSpecs int - NumberOfSpecsThatWillBeRun int - NumberOfPendingSpecs int - NumberOfSkippedSpecs int - NumberOfPassedSpecs int - NumberOfFailedSpecs int - NumberOfFlakedSpecs int - RunTime time.Duration -} - -type DeprecatedSetupSummary struct { - ComponentType SpecComponentType - CodeLocation CodeLocation - - State SpecState - RunTime time.Duration - Failure SpecFailure - - CapturedOutput string - SuiteID string -} - -type DeprecatedSpecSummary struct { - ComponentTexts []string - ComponentCodeLocations []CodeLocation - - State SpecState - RunTime time.Duration - Failure SpecFailure - IsMeasurement bool - NumberOfSamples int - Measurements map[string]*DeprecatedSpecMeasurement - - CapturedOutput string - SuiteID string -} - -func (s DeprecatedSpecSummary) HasFailureState() bool { - return s.State.Is(SpecStateFailureStates) -} - -func (s DeprecatedSpecSummary) TimedOut() bool { - return false -} - -func (s DeprecatedSpecSummary) Panicked() bool { - return s.State == SpecStatePanicked -} - -func (s DeprecatedSpecSummary) Failed() bool { - return s.State == SpecStateFailed -} - -func (s DeprecatedSpecSummary) Passed() bool { - return s.State == SpecStatePassed -} - -func (s DeprecatedSpecSummary) Skipped() bool { - return s.State == SpecStateSkipped -} - -func (s DeprecatedSpecSummary) Pending() bool { - return s.State == SpecStatePending -} - -type DeprecatedSpecFailure struct { - Message string - Location CodeLocation - ForwardedPanic string - - ComponentIndex int - ComponentType SpecComponentType - ComponentCodeLocation CodeLocation -} - -type DeprecatedSpecMeasurement struct { - Name string - Info any - Order int - - Results []float64 - - Smallest float64 - Largest float64 - Average float64 - StdDeviation float64 - - SmallestLabel string - LargestLabel string - AverageLabel string - Units string - Precision int -} - -func (s DeprecatedSpecMeasurement) PrecisionFmt() string { - if s.Precision == 0 { - return "%f" - } - - str := strconv.Itoa(s.Precision) - - return "%." + str + "f" -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go b/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go deleted file mode 100644 index e2519f67..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go +++ /dev/null @@ -1,177 +0,0 @@ -package types - -import ( - "os" - "strconv" - "strings" - "sync" - "unicode" - - "github.com/onsi/ginkgo/v2/formatter" -) - -type Deprecation struct { - Message string - DocLink string - Version string -} - -type deprecations struct{} - -var Deprecations = deprecations{} - -func (d deprecations) CustomReporter() Deprecation { - return Deprecation{ - Message: "Support for custom reporters has been removed in V2. Please read the documentation linked to below for Ginkgo's new behavior and for a migration path:", - DocLink: "removed-custom-reporters", - Version: "1.16.0", - } -} - -func (d deprecations) Async() Deprecation { - return Deprecation{ - Message: "You are passing a Done channel to a test node to test asynchronous behavior. This is deprecated in Ginkgo V2. Your test will run synchronously and the timeout will be ignored.", - DocLink: "removed-async-testing", - Version: "1.16.0", - } -} - -func (d deprecations) Measure() Deprecation { - return Deprecation{ - Message: "Measure is deprecated and has been removed from Ginkgo V2. Any Measure tests in your spec will not run. Please migrate to gomega/gmeasure.", - DocLink: "removed-measure", - Version: "1.16.3", - } -} - -func (d deprecations) ParallelNode() Deprecation { - return Deprecation{ - Message: "GinkgoParallelNode is deprecated and will be removed in Ginkgo V2. Please use GinkgoParallelProcess instead.", - DocLink: "renamed-ginkgoparallelnode", - Version: "1.16.4", - } -} - -func (d deprecations) CurrentGinkgoTestDescription() Deprecation { - return Deprecation{ - Message: "CurrentGinkgoTestDescription() is deprecated in Ginkgo V2. Use CurrentSpecReport() instead.", - DocLink: "changed-currentginkgotestdescription", - Version: "1.16.0", - } -} - -func (d deprecations) Convert() Deprecation { - return Deprecation{ - Message: "The convert command is deprecated in Ginkgo V2", - DocLink: "removed-ginkgo-convert", - Version: "1.16.0", - } -} - -func (d deprecations) Blur() Deprecation { - return Deprecation{ - Message: "The blur command is deprecated in Ginkgo V2. Use 'ginkgo unfocus' instead.", - Version: "1.16.0", - } -} - -func (d deprecations) Nodot() Deprecation { - return Deprecation{ - Message: "The nodot command is deprecated in Ginkgo V2. Please either dot-import Ginkgo or use the package identifier in your code to references objects and types provided by Ginkgo and Gomega.", - DocLink: "removed-ginkgo-nodot", - Version: "1.16.0", - } -} - -func (d deprecations) SuppressProgressReporting() Deprecation { - return Deprecation{ - Message: "Improvements to how reporters emit timeline information means that SuppressProgressReporting is no longer necessary and has been deprecated.", - Version: "2.5.0", - } -} - -type DeprecationTracker struct { - deprecations map[Deprecation][]CodeLocation - lock *sync.Mutex -} - -func NewDeprecationTracker() *DeprecationTracker { - return &DeprecationTracker{ - deprecations: map[Deprecation][]CodeLocation{}, - lock: &sync.Mutex{}, - } -} - -func (d *DeprecationTracker) TrackDeprecation(deprecation Deprecation, cl ...CodeLocation) { - ackVersion := os.Getenv("ACK_GINKGO_DEPRECATIONS") - if deprecation.Version != "" && ackVersion != "" { - ack := ParseSemVer(ackVersion) - version := ParseSemVer(deprecation.Version) - if ack.GreaterThanOrEqualTo(version) { - return - } - } - - d.lock.Lock() - defer d.lock.Unlock() - if len(cl) == 1 { - d.deprecations[deprecation] = append(d.deprecations[deprecation], cl[0]) - } else { - d.deprecations[deprecation] = []CodeLocation{} - } -} - -func (d *DeprecationTracker) DidTrackDeprecations() bool { - d.lock.Lock() - defer d.lock.Unlock() - return len(d.deprecations) > 0 -} - -func (d *DeprecationTracker) DeprecationsReport() string { - d.lock.Lock() - defer d.lock.Unlock() - out := formatter.F("{{light-yellow}}You're using deprecated Ginkgo functionality:{{/}}\n") - out += formatter.F("{{light-yellow}}============================================={{/}}\n") - for deprecation, locations := range d.deprecations { - out += formatter.Fi(1, "{{yellow}}"+deprecation.Message+"{{/}}\n") - if deprecation.DocLink != "" { - out += formatter.Fi(1, "{{bold}}Learn more at:{{/}} {{cyan}}{{underline}}https://onsi.github.io/ginkgo/MIGRATING_TO_V2#%s{{/}}\n", deprecation.DocLink) - } - for _, location := range locations { - out += formatter.Fi(2, "{{gray}}%s{{/}}\n", location) - } - } - out += formatter.F("\n{{gray}}To silence deprecations that can be silenced set the following environment variable:{{/}}\n") - out += formatter.Fi(1, "{{gray}}ACK_GINKGO_DEPRECATIONS=%s{{/}}\n", VERSION) - return out -} - -type SemVer struct { - Major int - Minor int - Patch int -} - -func (s SemVer) GreaterThanOrEqualTo(o SemVer) bool { - return (s.Major > o.Major) || - (s.Major == o.Major && s.Minor > o.Minor) || - (s.Major == o.Major && s.Minor == o.Minor && s.Patch >= o.Patch) -} - -func ParseSemVer(semver string) SemVer { - out := SemVer{} - semver = strings.TrimFunc(semver, func(r rune) bool { - return !(unicode.IsNumber(r) || r == '.') - }) - components := strings.Split(semver, ".") - if len(components) > 0 { - out.Major, _ = strconv.Atoi(components[0]) - } - if len(components) > 1 { - out.Minor, _ = strconv.Atoi(components[1]) - } - if len(components) > 2 { - out.Patch, _ = strconv.Atoi(components[2]) - } - return out -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/enum_support.go b/vendor/github.com/onsi/ginkgo/v2/types/enum_support.go deleted file mode 100644 index 1d96ae02..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/enum_support.go +++ /dev/null @@ -1,43 +0,0 @@ -package types - -import "encoding/json" - -type EnumSupport struct { - toString map[uint]string - toEnum map[string]uint - maxEnum uint -} - -func NewEnumSupport(toString map[uint]string) EnumSupport { - toEnum, maxEnum := map[string]uint{}, uint(0) - for k, v := range toString { - toEnum[v] = k - if maxEnum < k { - maxEnum = k - } - } - return EnumSupport{toString: toString, toEnum: toEnum, maxEnum: maxEnum} -} - -func (es EnumSupport) String(e uint) string { - if e > es.maxEnum { - return es.toString[0] - } - return es.toString[e] -} - -func (es EnumSupport) UnmarshJSON(b []byte) (uint, error) { - var dec string - if err := json.Unmarshal(b, &dec); err != nil { - return 0, err - } - out := es.toEnum[dec] // if we miss we get 0 which is what we want anyway - return out, nil -} - -func (es EnumSupport) MarshJSON(e uint) ([]byte, error) { - if e == 0 || e > es.maxEnum { - return json.Marshal(nil) - } - return json.Marshal(es.toString[e]) -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/errors.go b/vendor/github.com/onsi/ginkgo/v2/types/errors.go deleted file mode 100644 index c2796b54..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/errors.go +++ /dev/null @@ -1,653 +0,0 @@ -package types - -import ( - "fmt" - "reflect" - "strings" - - "github.com/onsi/ginkgo/v2/formatter" -) - -type GinkgoError struct { - Heading string - Message string - DocLink string - CodeLocation CodeLocation -} - -func (g GinkgoError) Error() string { - out := formatter.F("{{bold}}{{red}}%s{{/}}\n", g.Heading) - if (g.CodeLocation != CodeLocation{}) { - contentsOfLine := strings.TrimLeft(g.CodeLocation.ContentsOfLine(), "\t ") - if contentsOfLine != "" { - out += formatter.F("{{light-gray}}%s{{/}}\n", contentsOfLine) - } - out += formatter.F("{{gray}}%s{{/}}\n", g.CodeLocation) - } - if g.Message != "" { - out += formatter.Fiw(1, formatter.COLS, g.Message) - out += "\n\n" - } - if g.DocLink != "" { - out += formatter.Fiw(1, formatter.COLS, "{{bold}}Learn more at:{{/}} {{cyan}}{{underline}}http://onsi.github.io/ginkgo/#%s{{/}}\n", g.DocLink) - } - - return out -} - -type ginkgoErrors struct{} - -var GinkgoErrors = ginkgoErrors{} - -func (g ginkgoErrors) UncaughtGinkgoPanic(cl CodeLocation) error { - return GinkgoError{ - Heading: "Your Test Panicked", - Message: `When you, or your assertion library, calls Ginkgo's Fail(), -Ginkgo panics to prevent subsequent assertions from running. - -Normally Ginkgo rescues this panic so you shouldn't see it. - -However, if you make an assertion in a goroutine, Ginkgo can't capture the panic. -To circumvent this, you should call - - defer GinkgoRecover() - -at the top of the goroutine that caused this panic. - -Alternatively, you may have made an assertion outside of a Ginkgo -leaf node (e.g. in a container node or some out-of-band function) - please move your assertion to -an appropriate Ginkgo node (e.g. a BeforeSuite, BeforeEach, It, etc...).`, - DocLink: "mental-model-how-ginkgo-handles-failure", - CodeLocation: cl, - } -} - -func (g ginkgoErrors) RerunningSuite() error { - return GinkgoError{ - Heading: "Rerunning Suite", - Message: formatter.F(`It looks like you are calling RunSpecs more than once. Ginkgo does not support rerunning suites. If you want to rerun a suite try {{bold}}ginkgo --repeat=N{{/}} or {{bold}}ginkgo --until-it-fails{{/}}`), - DocLink: "repeating-spec-runs-and-managing-flaky-specs", - } -} - -/* Tree construction errors */ - -func (g ginkgoErrors) PushingNodeInRunPhase(nodeType NodeType, cl CodeLocation) error { - return GinkgoError{ - Heading: "Ginkgo detected an issue with your spec structure", - Message: formatter.F( - `It looks like you are trying to add a {{bold}}[%s]{{/}} node -to the Ginkgo spec tree in a leaf node {{bold}}after{{/}} the specs started running. - -To enable randomization and parallelization Ginkgo requires the spec tree -to be fully constructed up front. In practice, this means that you can -only create nodes like {{bold}}[%s]{{/}} at the top-level or within the -body of a {{bold}}Describe{{/}}, {{bold}}Context{{/}}, or {{bold}}When{{/}}.`, nodeType, nodeType), - CodeLocation: cl, - DocLink: "mental-model-how-ginkgo-traverses-the-spec-hierarchy", - } -} - -func (g ginkgoErrors) CaughtPanicDuringABuildPhase(caughtPanic any, cl CodeLocation) error { - return GinkgoError{ - Heading: "Assertion or Panic detected during tree construction", - Message: formatter.F( - `Ginkgo detected a panic while constructing the spec tree. -You may be trying to make an assertion in the body of a container node -(i.e. {{bold}}Describe{{/}}, {{bold}}Context{{/}}, or {{bold}}When{{/}}). - -Please ensure all assertions are inside leaf nodes such as {{bold}}BeforeEach{{/}}, -{{bold}}It{{/}}, etc. - -{{bold}}Here's the content of the panic that was caught:{{/}} -%v`, caughtPanic), - CodeLocation: cl, - DocLink: "no-assertions-in-container-nodes", - } -} - -func (g ginkgoErrors) SuiteNodeInNestedContext(nodeType NodeType, cl CodeLocation) error { - docLink := "suite-setup-and-cleanup-beforesuite-and-aftersuite" - if nodeType.Is(NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite) { - docLink = "reporting-nodes---reportbeforesuite-and-reportaftersuite" - } - - return GinkgoError{ - Heading: "Ginkgo detected an issue with your spec structure", - Message: formatter.F( - `It looks like you are trying to add a {{bold}}[%s]{{/}} node within a container node. - -{{bold}}%s{{/}} can only be called at the top level.`, nodeType, nodeType), - CodeLocation: cl, - DocLink: docLink, - } -} - -func (g ginkgoErrors) SuiteNodeDuringRunPhase(nodeType NodeType, cl CodeLocation) error { - docLink := "suite-setup-and-cleanup-beforesuite-and-aftersuite" - if nodeType.Is(NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite) { - docLink = "reporting-nodes---reportbeforesuite-and-reportaftersuite" - } - - return GinkgoError{ - Heading: "Ginkgo detected an issue with your spec structure", - Message: formatter.F( - `It looks like you are trying to add a {{bold}}[%s]{{/}} node within a leaf node after the spec started running. - -{{bold}}%s{{/}} can only be called at the top level.`, nodeType, nodeType), - CodeLocation: cl, - DocLink: docLink, - } -} - -func (g ginkgoErrors) MultipleBeforeSuiteNodes(nodeType NodeType, cl CodeLocation, earlierNodeType NodeType, earlierCodeLocation CodeLocation) error { - return ginkgoErrorMultipleSuiteNodes("setup", nodeType, cl, earlierNodeType, earlierCodeLocation) -} - -func (g ginkgoErrors) MultipleAfterSuiteNodes(nodeType NodeType, cl CodeLocation, earlierNodeType NodeType, earlierCodeLocation CodeLocation) error { - return ginkgoErrorMultipleSuiteNodes("teardown", nodeType, cl, earlierNodeType, earlierCodeLocation) -} - -func ginkgoErrorMultipleSuiteNodes(setupOrTeardown string, nodeType NodeType, cl CodeLocation, earlierNodeType NodeType, earlierCodeLocation CodeLocation) error { - return GinkgoError{ - Heading: "Ginkgo detected an issue with your spec structure", - Message: formatter.F( - `It looks like you are trying to add a {{bold}}[%s]{{/}} node but -you already have a {{bold}}[%s]{{/}} node defined at: {{gray}}%s{{/}}. - -Ginkgo only allows you to define one suite %s node.`, nodeType, earlierNodeType, earlierCodeLocation, setupOrTeardown), - CodeLocation: cl, - DocLink: "suite-setup-and-cleanup-beforesuite-and-aftersuite", - } -} - -/* Decorator errors */ -func (g ginkgoErrors) InvalidDecoratorForNodeType(cl CodeLocation, nodeType NodeType, decorator string) error { - return GinkgoError{ - Heading: "Invalid Decorator", - Message: formatter.F(`[%s] node cannot be passed a(n) '%s' decorator`, nodeType, decorator), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) InvalidDeclarationOfFocusedAndPending(cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Invalid Combination of Decorators: Focused and Pending", - Message: formatter.F(`[%s] node was decorated with both Focus and Pending. At most one is allowed.`, nodeType), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) InvalidDeclarationOfFlakeAttemptsAndMustPassRepeatedly(cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Invalid Combination of Decorators: FlakeAttempts and MustPassRepeatedly", - Message: formatter.F(`[%s] node was decorated with both FlakeAttempts and MustPassRepeatedly. At most one is allowed.`, nodeType), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator any) error { - return GinkgoError{ - Heading: "Unknown Decorator", - Message: formatter.F(`[%s] node was passed an unknown decorator: '%#v'`, nodeType, decorator), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) InvalidBodyTypeForContainer(t reflect.Type, cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Invalid Function", - Message: formatter.F(`[%s] node must be passed {{bold}}func(){{/}} - i.e. functions that take nothing and return nothing. You passed {{bold}}%s{{/}} instead.`, nodeType, t), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) InvalidBodyType(t reflect.Type, cl CodeLocation, nodeType NodeType) error { - mustGet := "{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}" - if nodeType.Is(NodeTypeContainer) { - mustGet = "{{bold}}func(){{/}}" - } - return GinkgoError{ - Heading: "Invalid Function", - Message: formatter.F(`[%s] node must be passed `+mustGet+`. -You passed {{bold}}%s{{/}} instead.`, nodeType, t), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteProc1(t reflect.Type, cl CodeLocation) error { - mustGet := "{{bold}}func() []byte{{/}}, {{bold}}func(ctx SpecContext) []byte{{/}}, or {{bold}}func(ctx context.Context) []byte{{/}}, {{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}" - return GinkgoError{ - Heading: "Invalid Function", - Message: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its first function. -You passed {{bold}}%s{{/}} instead.`, t), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteAllProcs(t reflect.Type, cl CodeLocation) error { - mustGet := "{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}, {{bold}}func([]byte){{/}}, {{bold}}func(ctx SpecContext, []byte){{/}}, or {{bold}}func(ctx context.Context, []byte){{/}}" - return GinkgoError{ - Heading: "Invalid Function", - Message: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its second function. -You passed {{bold}}%s{{/}} instead.`, t), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) MultipleBodyFunctions(cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Multiple Functions", - Message: formatter.F(`[%s] node must be passed a single function - but more than one was passed in.`, nodeType), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) MissingBodyFunction(cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Missing Functions", - Message: formatter.F(`[%s] node must be passed a single function - but none was passed in.`, nodeType), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextNode(cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Invalid NodeTimeout SpecTimeout, or GracePeriod", - Message: formatter.F(`[%s] was passed NodeTimeout, SpecTimeout, or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}. You must accept a context to enable timeouts and grace periods`, nodeType), - CodeLocation: cl, - DocLink: "spec-timeouts-and-interruptible-nodes", - } -} - -func (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextCleanupNode(cl CodeLocation) error { - return GinkgoError{ - Heading: "Invalid NodeTimeout SpecTimeout, or GracePeriod", - Message: formatter.F(`[DeferCleanup] was passed NodeTimeout or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}. You must accept a context to enable timeouts and grace periods`), - CodeLocation: cl, - DocLink: "spec-timeouts-and-interruptible-nodes", - } -} - -/* Ordered Container errors */ -func (g ginkgoErrors) InvalidSerialNodeInNonSerialOrderedContainer(cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Invalid Serial Node in Non-Serial Ordered Container", - Message: formatter.F(`[%s] node was decorated with Serial but occurs in an Ordered container that is not marked Serial. Move the Serial decorator to the outer-most Ordered container to mark all ordered specs within the container as serial.`, nodeType), - CodeLocation: cl, - DocLink: "node-decorators-overview", - } -} - -func (g ginkgoErrors) SetupNodeNotInOrderedContainer(cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: "Setup Node not in Ordered Container", - Message: fmt.Sprintf("[%s] setup nodes must appear inside an Ordered container. They cannot be nested within other containers, even containers in an ordered container.", nodeType), - CodeLocation: cl, - DocLink: "ordered-containers", - } -} - -func (g ginkgoErrors) InvalidContinueOnFailureDecoration(cl CodeLocation) error { - return GinkgoError{ - Heading: "ContinueOnFailure not decorating an outermost Ordered Container", - Message: "ContinueOnFailure can only decorate an Ordered container, and this Ordered container must be the outermost Ordered container.", - CodeLocation: cl, - DocLink: "ordered-containers", - } -} - -/* DeferCleanup errors */ -func (g ginkgoErrors) DeferCleanupInvalidFunction(cl CodeLocation) error { - return GinkgoError{ - Heading: "DeferCleanup requires a valid function", - Message: "You must pass DeferCleanup a function to invoke. This function must return zero or one values - if it does return, it must return an error. The function can take arbitrarily many arguments and you should provide these to DeferCleanup to pass along to the function.", - CodeLocation: cl, - DocLink: "cleaning-up-our-cleanup-code-defercleanup", - } -} - -func (g ginkgoErrors) PushingCleanupNodeDuringTreeConstruction(cl CodeLocation) error { - return GinkgoError{ - Heading: "DeferCleanup must be called inside a setup or subject node", - Message: "You must call DeferCleanup inside a setup node (e.g. BeforeEach, BeforeSuite, AfterAll...) or a subject node (i.e. It). You can't call DeferCleanup at the top-level or in a container node - use the After* family of setup nodes instead.", - CodeLocation: cl, - DocLink: "cleaning-up-our-cleanup-code-defercleanup", - } -} - -func (g ginkgoErrors) PushingCleanupInReportingNode(cl CodeLocation, nodeType NodeType) error { - return GinkgoError{ - Heading: fmt.Sprintf("DeferCleanup cannot be called in %s", nodeType), - Message: "Please inline your cleanup code - Ginkgo won't run cleanup code after a Reporting node.", - CodeLocation: cl, - DocLink: "cleaning-up-our-cleanup-code-defercleanup", - } -} - -func (g ginkgoErrors) PushingCleanupInCleanupNode(cl CodeLocation) error { - return GinkgoError{ - Heading: "DeferCleanup cannot be called in a DeferCleanup callback", - Message: "Please inline your cleanup code - Ginkgo doesn't let you call DeferCleanup from within DeferCleanup", - CodeLocation: cl, - DocLink: "cleaning-up-our-cleanup-code-defercleanup", - } -} - -/* ReportEntry errors */ -func (g ginkgoErrors) TooManyReportEntryValues(cl CodeLocation, arg any) error { - return GinkgoError{ - Heading: "Too Many ReportEntry Values", - Message: formatter.F(`{{bold}}AddGinkgoReport{{/}} can only be given one value. Got unexpected value: %#v`, arg), - CodeLocation: cl, - DocLink: "attaching-data-to-reports", - } -} - -func (g ginkgoErrors) AddReportEntryNotDuringRunPhase(cl CodeLocation) error { - return GinkgoError{ - Heading: "Ginkgo detected an issue with your spec structure", - Message: formatter.F(`It looks like you are calling {{bold}}AddGinkgoReport{{/}} outside of a running spec. Make sure you call {{bold}}AddGinkgoReport{{/}} inside a runnable node such as It or BeforeEach and not inside the body of a container such as Describe or Context.`), - CodeLocation: cl, - DocLink: "attaching-data-to-reports", - } -} - -/* By errors */ -func (g ginkgoErrors) ByNotDuringRunPhase(cl CodeLocation) error { - return GinkgoError{ - Heading: "Ginkgo detected an issue with your spec structure", - Message: formatter.F(`It looks like you are calling {{bold}}By{{/}} outside of a running spec. Make sure you call {{bold}}By{{/}} inside a runnable node such as It or BeforeEach and not inside the body of a container such as Describe or Context.`), - CodeLocation: cl, - DocLink: "documenting-complex-specs-by", - } -} - -/* FileFilter and SkipFilter errors */ -func (g ginkgoErrors) InvalidFileFilter(filter string) error { - return GinkgoError{ - Heading: "Invalid File Filter", - Message: fmt.Sprintf(`The provided file filter: "%s" is invalid. File filters must have the format "file", "file:lines" where "file" is a regular expression that will match against the file path and lines is a comma-separated list of integers (e.g. file:1,5,7) or line-ranges (e.g. file:1-3,5-9) or both (e.g. file:1,5-9)`, filter), - DocLink: "filtering-specs", - } -} - -func (g ginkgoErrors) InvalidFileFilterRegularExpression(filter string, err error) error { - return GinkgoError{ - Heading: "Invalid File Filter Regular Expression", - Message: fmt.Sprintf(`The provided file filter: "%s" included an invalid regular expression. regexp.Compile error: %s`, filter, err), - DocLink: "filtering-specs", - } -} - -/* Label Errors */ -func (g ginkgoErrors) SyntaxErrorParsingLabelFilter(input string, location int, error string) error { - var message string - if location >= 0 { - for i, r := range input { - if i == location { - message += "{{red}}{{bold}}{{underline}}" - } - message += string(r) - if i == location { - message += "{{/}}" - } - } - } else { - message = input - } - message += "\n" + error - return GinkgoError{ - Heading: "Syntax Error Parsing Label Filter", - Message: message, - DocLink: "spec-labels", - } -} - -func (g ginkgoErrors) InvalidLabel(label string, cl CodeLocation) error { - return GinkgoError{ - Heading: "Invalid Label", - Message: fmt.Sprintf("'%s' is an invalid label. Labels cannot contain of the following characters: '&|!,()/'", label), - CodeLocation: cl, - DocLink: "spec-labels", - } -} - -func (g ginkgoErrors) InvalidEmptyLabel(cl CodeLocation) error { - return GinkgoError{ - Heading: "Invalid Empty Label", - Message: "Labels cannot be empty", - CodeLocation: cl, - DocLink: "spec-labels", - } -} - -/* Table errors */ -func (g ginkgoErrors) MultipleEntryBodyFunctionsForTable(cl CodeLocation) error { - return GinkgoError{ - Heading: "DescribeTable passed multiple functions", - Message: "It looks like you are passing multiple functions into DescribeTable. Only one function can be passed in. This function will be called for each Entry in the table.", - CodeLocation: cl, - DocLink: "table-specs", - } -} - -func (g ginkgoErrors) InvalidEntryDescription(cl CodeLocation) error { - return GinkgoError{ - Heading: "Invalid Entry description", - Message: "Entry description functions must be a string, a function that accepts the entry parameters and returns a string, or nil.", - CodeLocation: cl, - DocLink: "table-specs", - } -} - -func (g ginkgoErrors) MissingParametersForTableFunction(cl CodeLocation) error { - return GinkgoError{ - Heading: "No parameters have been passed to the Table Function", - Message: "The Table Function expected at least 1 parameter", - CodeLocation: cl, - DocLink: "table-specs", - } -} - -func (g ginkgoErrors) IncorrectParameterTypeForTable(i int, name string, cl CodeLocation) error { - return GinkgoError{ - Heading: "DescribeTable passed incorrect parameter type", - Message: fmt.Sprintf("Parameter #%d passed to DescribeTable is of incorrect type <%s>", i, name), - CodeLocation: cl, - DocLink: "table-specs", - } -} - -func (g ginkgoErrors) TooFewParametersToTableFunction(expected, actual int, kind string, cl CodeLocation) error { - return GinkgoError{ - Heading: fmt.Sprintf("Too few parameters passed in to %s", kind), - Message: fmt.Sprintf("The %s expected %d parameters but you passed in %d", kind, expected, actual), - CodeLocation: cl, - DocLink: "table-specs", - } -} - -func (g ginkgoErrors) TooManyParametersToTableFunction(expected, actual int, kind string, cl CodeLocation) error { - return GinkgoError{ - Heading: fmt.Sprintf("Too many parameters passed in to %s", kind), - Message: fmt.Sprintf("The %s expected %d parameters but you passed in %d", kind, expected, actual), - CodeLocation: cl, - DocLink: "table-specs", - } -} - -func (g ginkgoErrors) IncorrectParameterTypeToTableFunction(i int, expected, actual reflect.Type, kind string, cl CodeLocation) error { - return GinkgoError{ - Heading: fmt.Sprintf("Incorrect parameters type passed to %s", kind), - Message: fmt.Sprintf("The %s expected parameter #%d to be of type <%s> but you passed in <%s>", kind, i, expected, actual), - CodeLocation: cl, - DocLink: "table-specs", - } -} - -func (g ginkgoErrors) IncorrectVariadicParameterTypeToTableFunction(expected, actual reflect.Type, kind string, cl CodeLocation) error { - return GinkgoError{ - Heading: fmt.Sprintf("Incorrect parameters type passed to %s", kind), - Message: fmt.Sprintf("The %s expected its variadic parameters to be of type <%s> but you passed in <%s>", kind, expected, actual), - CodeLocation: cl, - DocLink: "table-specs", - } -} - -func (g ginkgoErrors) ContextsCannotBeUsedInSubtreeTables(cl CodeLocation) error { - return GinkgoError{ - Heading: "Contexts cannot be used in subtree tables", - Message: "You''ve defined a subtree body function that accepts a context but did not provide one in the table entry. Ginkgo SpecContexts can only be passed in to subject and setup nodes - so if you are trying to implement a spec timeout you should request a context in the It function within your subtree body function, not in the subtree body function itself.", - CodeLocation: cl, - DocLink: "table-specs", - } -} - -/* Parallel Synchronization errors */ - -func (g ginkgoErrors) AggregatedReportUnavailableDueToNodeDisappearing() error { - return GinkgoError{ - Heading: "Test Report unavailable because a Ginkgo parallel process disappeared", - Message: "The aggregated report could not be fetched for a ReportAfterSuite node. A Ginkgo parallel process disappeared before it could finish reporting.", - } -} - -func (g ginkgoErrors) SynchronizedBeforeSuiteFailedOnProc1() error { - return GinkgoError{ - Heading: "SynchronizedBeforeSuite failed on Ginkgo parallel process #1", - Message: "The first SynchronizedBeforeSuite function running on Ginkgo parallel process #1 failed. This suite will now abort.", - } -} - -func (g ginkgoErrors) SynchronizedBeforeSuiteDisappearedOnProc1() error { - return GinkgoError{ - Heading: "Process #1 disappeared before SynchronizedBeforeSuite could report back", - Message: "Ginkgo parallel process #1 disappeared before the first SynchronizedBeforeSuite function completed. This suite will now abort.", - } -} - -/* Configuration errors */ - -func (g ginkgoErrors) UnknownTypePassedToRunSpecs(value any) error { - return GinkgoError{ - Heading: "Unknown Type passed to RunSpecs", - Message: fmt.Sprintf("RunSpecs() accepts labels, and configuration of type types.SuiteConfig and/or types.ReporterConfig.\n You passed in: %v", value), - } -} - -var sharedParallelErrorMessage = "It looks like you are trying to run specs in parallel with go test.\nThis is unsupported and you should use the ginkgo CLI instead." - -func (g ginkgoErrors) InvalidParallelTotalConfiguration() error { - return GinkgoError{ - Heading: "-ginkgo.parallel.total must be >= 1", - Message: sharedParallelErrorMessage, - DocLink: "spec-parallelization", - } -} - -func (g ginkgoErrors) InvalidParallelProcessConfiguration() error { - return GinkgoError{ - Heading: "-ginkgo.parallel.process is one-indexed and must be <= ginkgo.parallel.total", - Message: sharedParallelErrorMessage, - DocLink: "spec-parallelization", - } -} - -func (g ginkgoErrors) MissingParallelHostConfiguration() error { - return GinkgoError{ - Heading: "-ginkgo.parallel.host is missing", - Message: sharedParallelErrorMessage, - DocLink: "spec-parallelization", - } -} - -func (g ginkgoErrors) UnreachableParallelHost(host string) error { - return GinkgoError{ - Heading: "Could not reach ginkgo.parallel.host:" + host, - Message: sharedParallelErrorMessage, - DocLink: "spec-parallelization", - } -} - -func (g ginkgoErrors) DryRunInParallelConfiguration() error { - return GinkgoError{ - Heading: "Ginkgo only performs -dryRun in serial mode.", - Message: "Please try running ginkgo -dryRun again, but without -p or -procs to ensure the suite is running in series.", - } -} - -func (g ginkgoErrors) GracePeriodCannotBeZero() error { - return GinkgoError{ - Heading: "Ginkgo requires a positive --grace-period.", - Message: "Please set --grace-period to a positive duration. The default is 30s.", - } -} - -func (g ginkgoErrors) ConflictingVerbosityConfiguration() error { - return GinkgoError{ - Heading: "Conflicting reporter verbosity settings.", - Message: "You can't set more than one of -v, -vv and --succinct. Please pick one!", - } -} - -func (g ginkgoErrors) InvalidOutputInterceptorModeConfiguration(value string) error { - return GinkgoError{ - Heading: fmt.Sprintf("Invalid value '%s' for --output-interceptor-mode.", value), - Message: "You must choose one of 'dup', 'swap', or 'none'.", - } -} - -func (g ginkgoErrors) InvalidGoFlagCount() error { - return GinkgoError{ - Heading: "Use of go test -count", - Message: "Ginkgo does not support using go test -count to rerun suites. Only -count=1 is allowed. To repeat suite runs, please use the ginkgo cli and `ginkgo -until-it-fails` or `ginkgo -repeat=N`.", - } -} - -func (g ginkgoErrors) InvalidGoFlagParallel() error { - return GinkgoError{ - Heading: "Use of go test -parallel", - Message: "Go test's implementation of parallelization does not actually parallelize Ginkgo specs. Please use the ginkgo cli and `ginkgo -p` or `ginkgo -procs=N` instead.", - } -} - -func (g ginkgoErrors) BothRepeatAndUntilItFails() error { - return GinkgoError{ - Heading: "--repeat and --until-it-fails are both set", - Message: "--until-it-fails directs Ginkgo to rerun specs indefinitely until they fail. --repeat directs Ginkgo to rerun specs a set number of times. You can't set both... which would you like?", - } -} - -func (g ginkgoErrors) ExpectFilenameNotPath(flag string, path string) error { - return GinkgoError{ - Heading: fmt.Sprintf("%s expects a filename but was given a path: %s", flag, path), - Message: fmt.Sprintf("%s takes a filename, not a path. Use --output-dir to specify a directory to collect all test outputs.", flag), - } -} - -func (g ginkgoErrors) FlagAfterPositionalParameter() error { - return GinkgoError{ - Heading: "Malformed arguments - detected a flag after the package liste", - Message: "Make sure all flags appear {{bold}}after{{/}} the Ginkgo subcommand and {{bold}}before{{/}} your list of packages (or './...').\n{{gray}}e.g. 'ginkgo run -p my_package' is valid but `ginkgo -p run my_package` is not.\n{{gray}}e.g. 'ginkgo -p -vet=\"\" ./...' is valid but 'ginkgo -p ./... -vet=\"\"' is not{{/}}", - } -} - -/* Stack-Trace parsing errors */ - -func (g ginkgoErrors) FailedToParseStackTrace(message string) error { - return GinkgoError{ - Heading: "Failed to Parse Stack Trace", - Message: message, - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/file_filter.go b/vendor/github.com/onsi/ginkgo/v2/types/file_filter.go deleted file mode 100644 index cc21df71..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/file_filter.go +++ /dev/null @@ -1,106 +0,0 @@ -package types - -import ( - "regexp" - "strconv" - "strings" -) - -func ParseFileFilters(filters []string) (FileFilters, error) { - ffs := FileFilters{} - for _, filter := range filters { - ff := FileFilter{} - if filter == "" { - return nil, GinkgoErrors.InvalidFileFilter(filter) - } - components := strings.Split(filter, ":") - if !(len(components) == 1 || len(components) == 2) { - return nil, GinkgoErrors.InvalidFileFilter(filter) - } - - var err error - ff.Filename, err = regexp.Compile(components[0]) - if err != nil { - return nil, err - } - if len(components) == 2 { - lineFilters := strings.Split(components[1], ",") - for _, lineFilter := range lineFilters { - components := strings.Split(lineFilter, "-") - if len(components) == 1 { - line, err := strconv.Atoi(strings.TrimSpace(components[0])) - if err != nil { - return nil, GinkgoErrors.InvalidFileFilter(filter) - } - ff.LineFilters = append(ff.LineFilters, LineFilter{line, line + 1}) - } else if len(components) == 2 { - line1, err := strconv.Atoi(strings.TrimSpace(components[0])) - if err != nil { - return nil, GinkgoErrors.InvalidFileFilter(filter) - } - line2, err := strconv.Atoi(strings.TrimSpace(components[1])) - if err != nil { - return nil, GinkgoErrors.InvalidFileFilter(filter) - } - ff.LineFilters = append(ff.LineFilters, LineFilter{line1, line2}) - } else { - return nil, GinkgoErrors.InvalidFileFilter(filter) - } - } - } - ffs = append(ffs, ff) - } - return ffs, nil -} - -type FileFilter struct { - Filename *regexp.Regexp - LineFilters LineFilters -} - -func (f FileFilter) Matches(locations []CodeLocation) bool { - for _, location := range locations { - if f.Filename.MatchString(location.FileName) && - f.LineFilters.Matches(location.LineNumber) { - return true - } - - } - return false -} - -type FileFilters []FileFilter - -func (ffs FileFilters) Matches(locations []CodeLocation) bool { - for _, ff := range ffs { - if ff.Matches(locations) { - return true - } - } - - return false -} - -type LineFilter struct { - Min int - Max int -} - -func (lf LineFilter) Matches(line int) bool { - return lf.Min <= line && line < lf.Max -} - -type LineFilters []LineFilter - -func (lfs LineFilters) Matches(line int) bool { - if len(lfs) == 0 { - return true - } - - for _, lf := range lfs { - if lf.Matches(line) { - return true - } - } - return false -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/flags.go b/vendor/github.com/onsi/ginkgo/v2/types/flags.go deleted file mode 100644 index 8409653f..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/flags.go +++ /dev/null @@ -1,490 +0,0 @@ -package types - -import ( - "flag" - "fmt" - "io" - "reflect" - "strings" - "time" - - "github.com/onsi/ginkgo/v2/formatter" -) - -type GinkgoFlag struct { - Name string - KeyPath string - SectionKey string - - Usage string - UsageArgument string - UsageDefaultValue string - - DeprecatedName string - DeprecatedDocLink string - DeprecatedVersion string - - ExportAs string - AlwaysExport bool -} - -type GinkgoFlags []GinkgoFlag - -func (f GinkgoFlags) CopyAppend(flags ...GinkgoFlag) GinkgoFlags { - out := GinkgoFlags{} - out = append(out, f...) - out = append(out, flags...) - return out -} - -func (f GinkgoFlags) WithPrefix(prefix string) GinkgoFlags { - if prefix == "" { - return f - } - out := GinkgoFlags{} - for _, flag := range f { - if flag.Name != "" { - flag.Name = prefix + "." + flag.Name - } - if flag.DeprecatedName != "" { - flag.DeprecatedName = prefix + "." + flag.DeprecatedName - } - if flag.ExportAs != "" { - flag.ExportAs = prefix + "." + flag.ExportAs - } - out = append(out, flag) - } - return out -} - -func (f GinkgoFlags) SubsetWithNames(names ...string) GinkgoFlags { - out := GinkgoFlags{} - for _, flag := range f { - for _, name := range names { - if flag.Name == name { - out = append(out, flag) - break - } - } - } - return out -} - -type GinkgoFlagSection struct { - Key string - Style string - Succinct bool - Heading string - Description string -} - -type GinkgoFlagSections []GinkgoFlagSection - -func (gfs GinkgoFlagSections) Lookup(key string) (GinkgoFlagSection, bool) { - for _, section := range gfs { - if section.Key == key { - return section, true - } - } - - return GinkgoFlagSection{}, false -} - -type GinkgoFlagSet struct { - flags GinkgoFlags - bindings any - - sections GinkgoFlagSections - extraGoFlagsSection GinkgoFlagSection - - flagSet *flag.FlagSet -} - -// Call NewGinkgoFlagSet to create GinkgoFlagSet that creates and binds to it's own *flag.FlagSet -func NewGinkgoFlagSet(flags GinkgoFlags, bindings any, sections GinkgoFlagSections) (GinkgoFlagSet, error) { - return bindFlagSet(GinkgoFlagSet{ - flags: flags, - bindings: bindings, - sections: sections, - }, nil) -} - -// Call NewGinkgoFlagSet to create GinkgoFlagSet that extends an existing *flag.FlagSet -func NewAttachedGinkgoFlagSet(flagSet *flag.FlagSet, flags GinkgoFlags, bindings any, sections GinkgoFlagSections, extraGoFlagsSection GinkgoFlagSection) (GinkgoFlagSet, error) { - return bindFlagSet(GinkgoFlagSet{ - flags: flags, - bindings: bindings, - sections: sections, - extraGoFlagsSection: extraGoFlagsSection, - }, flagSet) -} - -func bindFlagSet(f GinkgoFlagSet, flagSet *flag.FlagSet) (GinkgoFlagSet, error) { - if flagSet == nil { - f.flagSet = flag.NewFlagSet("", flag.ContinueOnError) - //suppress all output as Ginkgo is responsible for formatting usage - f.flagSet.SetOutput(io.Discard) - } else { - f.flagSet = flagSet - //we're piggybacking on an existing flagset (typically go test) so we have limited control - //on user feedback - f.flagSet.Usage = f.substituteUsage - } - - for _, flag := range f.flags { - name := flag.Name - - deprecatedUsage := "[DEPRECATED]" - deprecatedName := flag.DeprecatedName - if name != "" { - deprecatedUsage = fmt.Sprintf("[DEPRECATED] use --%s instead", name) - } else if flag.Usage != "" { - deprecatedUsage += " " + flag.Usage - } - - value, ok := valueAtKeyPath(f.bindings, flag.KeyPath) - if !ok { - return GinkgoFlagSet{}, fmt.Errorf("could not load KeyPath: %s", flag.KeyPath) - } - - iface, addr := value.Interface(), value.Addr().Interface() - - switch value.Type() { - case reflect.TypeOf(string("")): - if name != "" { - f.flagSet.StringVar(addr.(*string), name, iface.(string), flag.Usage) - } - if deprecatedName != "" { - f.flagSet.StringVar(addr.(*string), deprecatedName, iface.(string), deprecatedUsage) - } - case reflect.TypeOf(int64(0)): - if name != "" { - f.flagSet.Int64Var(addr.(*int64), name, iface.(int64), flag.Usage) - } - if deprecatedName != "" { - f.flagSet.Int64Var(addr.(*int64), deprecatedName, iface.(int64), deprecatedUsage) - } - case reflect.TypeOf(float64(0)): - if name != "" { - f.flagSet.Float64Var(addr.(*float64), name, iface.(float64), flag.Usage) - } - if deprecatedName != "" { - f.flagSet.Float64Var(addr.(*float64), deprecatedName, iface.(float64), deprecatedUsage) - } - case reflect.TypeOf(int(0)): - if name != "" { - f.flagSet.IntVar(addr.(*int), name, iface.(int), flag.Usage) - } - if deprecatedName != "" { - f.flagSet.IntVar(addr.(*int), deprecatedName, iface.(int), deprecatedUsage) - } - case reflect.TypeOf(bool(true)): - if name != "" { - f.flagSet.BoolVar(addr.(*bool), name, iface.(bool), flag.Usage) - } - if deprecatedName != "" { - f.flagSet.BoolVar(addr.(*bool), deprecatedName, iface.(bool), deprecatedUsage) - } - case reflect.TypeOf(time.Duration(0)): - if name != "" { - f.flagSet.DurationVar(addr.(*time.Duration), name, iface.(time.Duration), flag.Usage) - } - if deprecatedName != "" { - f.flagSet.DurationVar(addr.(*time.Duration), deprecatedName, iface.(time.Duration), deprecatedUsage) - } - - case reflect.TypeOf([]string{}): - if name != "" { - f.flagSet.Var(stringSliceVar{value}, name, flag.Usage) - } - if deprecatedName != "" { - f.flagSet.Var(stringSliceVar{value}, deprecatedName, deprecatedUsage) - } - default: - return GinkgoFlagSet{}, fmt.Errorf("unsupported type %T", iface) - } - } - - return f, nil -} - -func (f GinkgoFlagSet) IsZero() bool { - return f.flagSet == nil -} - -func (f GinkgoFlagSet) WasSet(name string) bool { - found := false - f.flagSet.Visit(func(f *flag.Flag) { - if f.Name == name { - found = true - } - }) - - return found -} - -func (f GinkgoFlagSet) Lookup(name string) *flag.Flag { - return f.flagSet.Lookup(name) -} - -func (f GinkgoFlagSet) Parse(args []string) ([]string, error) { - if f.IsZero() { - return args, nil - } - err := f.flagSet.Parse(args) - if err != nil { - return []string{}, err - } - return f.flagSet.Args(), nil -} - -func (f GinkgoFlagSet) ValidateDeprecations(deprecationTracker *DeprecationTracker) { - if f.IsZero() { - return - } - f.flagSet.Visit(func(flag *flag.Flag) { - for _, ginkgoFlag := range f.flags { - if ginkgoFlag.DeprecatedName != "" && strings.HasSuffix(flag.Name, ginkgoFlag.DeprecatedName) { - message := fmt.Sprintf("--%s is deprecated", ginkgoFlag.DeprecatedName) - if ginkgoFlag.Name != "" { - message = fmt.Sprintf("--%s is deprecated, use --%s instead", ginkgoFlag.DeprecatedName, ginkgoFlag.Name) - } else if ginkgoFlag.Usage != "" { - message += " " + ginkgoFlag.Usage - } - - deprecationTracker.TrackDeprecation(Deprecation{ - Message: message, - DocLink: ginkgoFlag.DeprecatedDocLink, - Version: ginkgoFlag.DeprecatedVersion, - }) - } - } - }) -} - -func (f GinkgoFlagSet) Usage() string { - if f.IsZero() { - return "" - } - groupedFlags := map[GinkgoFlagSection]GinkgoFlags{} - ungroupedFlags := GinkgoFlags{} - managedFlags := map[string]bool{} - extraGoFlags := []*flag.Flag{} - - for _, flag := range f.flags { - managedFlags[flag.Name] = true - managedFlags[flag.DeprecatedName] = true - - if flag.Name == "" { - continue - } - - section, ok := f.sections.Lookup(flag.SectionKey) - if ok { - groupedFlags[section] = append(groupedFlags[section], flag) - } else { - ungroupedFlags = append(ungroupedFlags, flag) - } - } - - f.flagSet.VisitAll(func(flag *flag.Flag) { - if !managedFlags[flag.Name] { - extraGoFlags = append(extraGoFlags, flag) - } - }) - - out := "" - for _, section := range f.sections { - flags := groupedFlags[section] - if len(flags) == 0 { - continue - } - out += f.usageForSection(section) - if section.Succinct { - succinctFlags := []string{} - for _, flag := range flags { - if flag.Name != "" { - succinctFlags = append(succinctFlags, fmt.Sprintf("--%s", flag.Name)) - } - } - out += formatter.Fiw(1, formatter.COLS, section.Style+strings.Join(succinctFlags, ", ")+"{{/}}\n") - } else { - for _, flag := range flags { - out += f.usageForFlag(flag, section.Style) - } - } - out += "\n" - } - if len(ungroupedFlags) > 0 { - for _, flag := range ungroupedFlags { - out += f.usageForFlag(flag, "") - } - out += "\n" - } - if len(extraGoFlags) > 0 { - out += f.usageForSection(f.extraGoFlagsSection) - for _, goFlag := range extraGoFlags { - out += f.usageForGoFlag(goFlag) - } - } - - return out -} - -func (f GinkgoFlagSet) substituteUsage() { - fmt.Fprintln(f.flagSet.Output(), f.Usage()) -} - -func valueAtKeyPath(root any, keyPath string) (reflect.Value, bool) { - if len(keyPath) == 0 { - return reflect.Value{}, false - } - - val := reflect.ValueOf(root) - components := strings.Split(keyPath, ".") - for _, component := range components { - val = reflect.Indirect(val) - switch val.Kind() { - case reflect.Map: - val = val.MapIndex(reflect.ValueOf(component)) - if val.Kind() == reflect.Interface { - val = reflect.ValueOf(val.Interface()) - } - case reflect.Struct: - val = val.FieldByName(component) - default: - return reflect.Value{}, false - } - if (val == reflect.Value{}) { - return reflect.Value{}, false - } - } - - return val, true -} - -func (f GinkgoFlagSet) usageForSection(section GinkgoFlagSection) string { - out := formatter.F(section.Style + "{{bold}}{{underline}}" + section.Heading + "{{/}}\n") - if section.Description != "" { - out += formatter.Fiw(0, formatter.COLS, section.Description+"\n") - } - return out -} - -func (f GinkgoFlagSet) usageForFlag(flag GinkgoFlag, style string) string { - argument := flag.UsageArgument - defValue := flag.UsageDefaultValue - if argument == "" { - value, _ := valueAtKeyPath(f.bindings, flag.KeyPath) - switch value.Type() { - case reflect.TypeOf(string("")): - argument = "string" - case reflect.TypeOf(int64(0)), reflect.TypeOf(int(0)): - argument = "int" - case reflect.TypeOf(time.Duration(0)): - argument = "duration" - case reflect.TypeOf(float64(0)): - argument = "float" - case reflect.TypeOf([]string{}): - argument = "string" - } - } - if argument != "" { - argument = "[" + argument + "] " - } - if defValue != "" { - defValue = fmt.Sprintf("(default: %s)", defValue) - } - hyphens := "--" - if len(flag.Name) == 1 { - hyphens = "-" - } - - out := formatter.Fi(1, style+"%s%s{{/}} %s{{gray}}%s{{/}}\n", hyphens, flag.Name, argument, defValue) - out += formatter.Fiw(2, formatter.COLS, "{{light-gray}}%s{{/}}\n", flag.Usage) - return out -} - -func (f GinkgoFlagSet) usageForGoFlag(goFlag *flag.Flag) string { - //Taken directly from the flag package - out := fmt.Sprintf(" -%s", goFlag.Name) - name, usage := flag.UnquoteUsage(goFlag) - if len(name) > 0 { - out += " " + name - } - if len(out) <= 4 { - out += "\t" - } else { - out += "\n \t" - } - out += strings.ReplaceAll(usage, "\n", "\n \t") - out += "\n" - return out -} - -type stringSliceVar struct { - slice reflect.Value -} - -func (ssv stringSliceVar) String() string { return "" } -func (ssv stringSliceVar) Set(s string) error { - ssv.slice.Set(reflect.AppendSlice(ssv.slice, reflect.ValueOf([]string{s}))) - return nil -} - -// given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured. -func GenerateFlagArgs(flags GinkgoFlags, bindings any) ([]string, error) { - result := []string{} - for _, flag := range flags { - name := flag.ExportAs - if name == "" { - name = flag.Name - } - if name == "" { - continue - } - - value, ok := valueAtKeyPath(bindings, flag.KeyPath) - if !ok { - return []string{}, fmt.Errorf("could not load KeyPath: %s", flag.KeyPath) - } - - iface := value.Interface() - switch value.Type() { - case reflect.TypeOf(string("")): - if iface.(string) != "" || flag.AlwaysExport { - result = append(result, fmt.Sprintf("--%s=%s", name, iface)) - } - case reflect.TypeOf(int64(0)): - if iface.(int64) != 0 || flag.AlwaysExport { - result = append(result, fmt.Sprintf("--%s=%d", name, iface)) - } - case reflect.TypeOf(float64(0)): - if iface.(float64) != 0 || flag.AlwaysExport { - result = append(result, fmt.Sprintf("--%s=%f", name, iface)) - } - case reflect.TypeOf(int(0)): - if iface.(int) != 0 || flag.AlwaysExport { - result = append(result, fmt.Sprintf("--%s=%d", name, iface)) - } - case reflect.TypeOf(bool(true)): - if iface.(bool) { - result = append(result, fmt.Sprintf("--%s", name)) - } - case reflect.TypeOf(time.Duration(0)): - if iface.(time.Duration) != time.Duration(0) || flag.AlwaysExport { - result = append(result, fmt.Sprintf("--%s=%s", name, iface)) - } - - case reflect.TypeOf([]string{}): - strings := iface.([]string) - for _, s := range strings { - result = append(result, fmt.Sprintf("--%s=%s", name, s)) - } - default: - return []string{}, fmt.Errorf("unsupported type %T", iface) - } - } - - return result, nil -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/label_filter.go b/vendor/github.com/onsi/ginkgo/v2/types/label_filter.go deleted file mode 100644 index 40a909b6..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/label_filter.go +++ /dev/null @@ -1,583 +0,0 @@ -package types - -import ( - "fmt" - "regexp" - "strings" -) - -var DEBUG_LABEL_FILTER_PARSING = false - -type LabelFilter func([]string) bool - -func matchLabelAction(label string) LabelFilter { - expected := strings.ToLower(label) - return func(labels []string) bool { - for i := range labels { - if strings.ToLower(labels[i]) == expected { - return true - } - } - return false - } -} - -func matchLabelRegexAction(regex *regexp.Regexp) LabelFilter { - return func(labels []string) bool { - for i := range labels { - if regex.MatchString(labels[i]) { - return true - } - } - return false - } -} - -func notAction(filter LabelFilter) LabelFilter { - return func(labels []string) bool { return !filter(labels) } -} - -func andAction(a, b LabelFilter) LabelFilter { - return func(labels []string) bool { return a(labels) && b(labels) } -} - -func orAction(a, b LabelFilter) LabelFilter { - return func(labels []string) bool { return a(labels) || b(labels) } -} - -func labelSetFor(key string, labels []string) map[string]bool { - key = strings.ToLower(strings.TrimSpace(key)) - out := map[string]bool{} - for _, label := range labels { - components := strings.SplitN(label, ":", 2) - if len(components) < 2 { - continue - } - if key == strings.ToLower(strings.TrimSpace(components[0])) { - out[strings.ToLower(strings.TrimSpace(components[1]))] = true - } - } - - return out -} - -func isEmptyLabelSetAction(key string) LabelFilter { - return func(labels []string) bool { - return len(labelSetFor(key, labels)) == 0 - } -} - -func containsAnyLabelSetAction(key string, expectedValues []string) LabelFilter { - return func(labels []string) bool { - set := labelSetFor(key, labels) - for _, value := range expectedValues { - if set[value] { - return true - } - } - return false - } -} - -func containsAllLabelSetAction(key string, expectedValues []string) LabelFilter { - return func(labels []string) bool { - set := labelSetFor(key, labels) - for _, value := range expectedValues { - if !set[value] { - return false - } - } - return true - } -} - -func consistsOfLabelSetAction(key string, expectedValues []string) LabelFilter { - return func(labels []string) bool { - set := labelSetFor(key, labels) - if len(set) != len(expectedValues) { - return false - } - for _, value := range expectedValues { - if !set[value] { - return false - } - } - return true - } -} - -func isSubsetOfLabelSetAction(key string, expectedValues []string) LabelFilter { - expectedSet := map[string]bool{} - for _, value := range expectedValues { - expectedSet[value] = true - } - return func(labels []string) bool { - set := labelSetFor(key, labels) - for value := range set { - if !expectedSet[value] { - return false - } - } - return true - } -} - -type lfToken uint - -const ( - lfTokenInvalid lfToken = iota - - lfTokenRoot - lfTokenOpenGroup - lfTokenCloseGroup - lfTokenNot - lfTokenAnd - lfTokenOr - lfTokenRegexp - lfTokenLabel - lfTokenSetKey - lfTokenSetOperation - lfTokenSetArgument - lfTokenEOF -) - -func (l lfToken) Precedence() int { - switch l { - case lfTokenRoot, lfTokenOpenGroup: - return 0 - case lfTokenOr: - return 1 - case lfTokenAnd: - return 2 - case lfTokenNot: - return 3 - case lfTokenSetOperation: - return 4 - } - return -1 -} - -func (l lfToken) String() string { - switch l { - case lfTokenRoot: - return "ROOT" - case lfTokenOpenGroup: - return "(" - case lfTokenCloseGroup: - return ")" - case lfTokenNot: - return "!" - case lfTokenAnd: - return "&&" - case lfTokenOr: - return "||" - case lfTokenRegexp: - return "/regexp/" - case lfTokenLabel: - return "label" - case lfTokenSetKey: - return "set_key" - case lfTokenSetOperation: - return "set_operation" - case lfTokenSetArgument: - return "set_argument" - case lfTokenEOF: - return "EOF" - } - return "INVALID" -} - -type treeNode struct { - token lfToken - location int - value string - - parent *treeNode - leftNode *treeNode - rightNode *treeNode -} - -func (tn *treeNode) setRightNode(node *treeNode) { - tn.rightNode = node - node.parent = tn -} - -func (tn *treeNode) setLeftNode(node *treeNode) { - tn.leftNode = node - node.parent = tn -} - -func (tn *treeNode) firstAncestorWithPrecedenceLEQ(precedence int) *treeNode { - if tn.token.Precedence() <= precedence { - return tn - } - return tn.parent.firstAncestorWithPrecedenceLEQ(precedence) -} - -func (tn *treeNode) firstUnmatchedOpenNode() *treeNode { - if tn.token == lfTokenOpenGroup { - return tn - } - if tn.parent == nil { - return nil - } - return tn.parent.firstUnmatchedOpenNode() -} - -func (tn *treeNode) constructLabelFilter(input string) (LabelFilter, error) { - switch tn.token { - case lfTokenOpenGroup: - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, "Mismatched '(' - could not find matching ')'.") - case lfTokenLabel: - return matchLabelAction(tn.value), nil - case lfTokenRegexp: - re, err := regexp.Compile(tn.value) - if err != nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("RegExp compilation error: %s", err)) - } - return matchLabelRegexAction(re), nil - case lfTokenSetOperation: - tokenSetOperation := strings.ToLower(tn.value) - if tokenSetOperation == "isempty" { - return isEmptyLabelSetAction(tn.leftNode.value), nil - } - if tn.rightNode == nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("Set operation '%s' is missing an argument.", tn.value)) - } - - rawValues := strings.Split(tn.rightNode.value, ",") - values := make([]string, len(rawValues)) - for i := range rawValues { - values[i] = strings.ToLower(strings.TrimSpace(rawValues[i])) - if strings.ContainsAny(values[i], "&|!,()/") { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, fmt.Sprintf("Invalid label value '%s' in set operation argument.", values[i])) - } else if values[i] == "" { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, "Empty label value in set operation argument.") - } - } - switch tokenSetOperation { - case "containsany": - return containsAnyLabelSetAction(tn.leftNode.value, values), nil - case "containsall": - return containsAllLabelSetAction(tn.leftNode.value, values), nil - case "consistsof": - return consistsOfLabelSetAction(tn.leftNode.value, values), nil - case "issubsetof": - return isSubsetOfLabelSetAction(tn.leftNode.value, values), nil - } - } - - if tn.rightNode == nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, -1, "Unexpected EOF.") - } - rightLF, err := tn.rightNode.constructLabelFilter(input) - if err != nil { - return nil, err - } - - switch tn.token { - case lfTokenRoot, lfTokenCloseGroup: - return rightLF, nil - case lfTokenNot: - return notAction(rightLF), nil - } - - if tn.leftNode == nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("Malformed tree - '%s' is missing left operand.", tn.token)) - } - leftLF, err := tn.leftNode.constructLabelFilter(input) - if err != nil { - return nil, err - } - - switch tn.token { - case lfTokenAnd: - return andAction(leftLF, rightLF), nil - case lfTokenOr: - return orAction(leftLF, rightLF), nil - } - - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("Invalid token '%s'.", tn.token)) -} - -func (tn *treeNode) tokenString() string { - out := fmt.Sprintf("<%s", tn.token) - if tn.value != "" { - out += " | " + tn.value - } - out += ">" - return out -} - -func (tn *treeNode) toString(indent int) string { - out := tn.tokenString() + "\n" - if tn.leftNode != nil { - out += fmt.Sprintf("%s |_(L)_%s", strings.Repeat(" ", indent), tn.leftNode.toString(indent+1)) - } - if tn.rightNode != nil { - out += fmt.Sprintf("%s |_(R)_%s", strings.Repeat(" ", indent), tn.rightNode.toString(indent+1)) - } - return out -} - -var validSetOperations = map[string]string{ - "containsany": "containsAny", - "containsall": "containsAll", - "consistsof": "consistsOf", - "issubsetof": "isSubsetOf", - "isempty": "isEmpty", -} - -func tokenize(input string) func() (*treeNode, error) { - lastToken := lfTokenInvalid - lastValue := "" - runes, i := []rune(input), 0 - - peekIs := func(r rune) bool { - if i+1 < len(runes) { - return runes[i+1] == r - } - return false - } - - consumeUntil := func(cutset string) (string, int) { - j := i - for ; j < len(runes); j++ { - if strings.ContainsRune(cutset, runes[j]) { - break - } - } - return string(runes[i:j]), j - i - } - - return func() (*treeNode, error) { - for i < len(runes) && runes[i] == ' ' { - i += 1 - } - - if i >= len(runes) { - return &treeNode{token: lfTokenEOF}, nil - } - - node := &treeNode{location: i} - defer func() { - lastToken = node.token - lastValue = node.value - }() - - if lastToken == lfTokenSetKey { - //we should get a valid set operation next - value, n := consumeUntil(" )") - if validSetOperations[strings.ToLower(value)] == "" { - return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, fmt.Sprintf("Invalid set operation '%s'.", value)) - } - i += n - node.token, node.value = lfTokenSetOperation, value - return node, nil - } - if lastToken == lfTokenSetOperation { - //we should get an argument next, if we aren't isempty - var arg = "" - origI := i - if runes[i] == '{' { - i += 1 - value, n := consumeUntil("}") - if i+n >= len(runes) { - return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-1, "Missing closing '}' in set operation argument?") - } - i += n + 1 - arg = value - } else { - value, n := consumeUntil("&|!,()/") - i += n - arg = strings.TrimSpace(value) - } - if strings.ToLower(lastValue) == "isempty" && arg != "" { - return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf("isEmpty does not take arguments, was passed '%s'.", arg)) - } - if arg == "" && strings.ToLower(lastValue) != "isempty" { - if i < len(runes) && runes[i] == '/' { - return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, "Set operations do not support regular expressions.") - } else { - return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf("Set operation '%s' requires an argument.", lastValue)) - } - } - // note that we sent an empty SetArgument token if we are isempty - node.token, node.value = lfTokenSetArgument, arg - return node, nil - } - - switch runes[i] { - case '&': - if !peekIs('&') { - return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Invalid token '&'. Did you mean '&&'?") - } - i += 2 - node.token = lfTokenAnd - case '|': - if !peekIs('|') { - return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Invalid token '|'. Did you mean '||'?") - } - i += 2 - node.token = lfTokenOr - case '!': - i += 1 - node.token = lfTokenNot - case ',': - i += 1 - node.token = lfTokenOr - case '(': - i += 1 - node.token = lfTokenOpenGroup - case ')': - i += 1 - node.token = lfTokenCloseGroup - case '/': - i += 1 - value, n := consumeUntil("/") - i += n + 1 - node.token, node.value = lfTokenRegexp, value - default: - value, n := consumeUntil("&|!,()/:") - i += n - value = strings.TrimSpace(value) - - //are we the beginning of a set operation? - if i < len(runes) && runes[i] == ':' { - if peekIs(' ') { - if value == "" { - return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Missing set key.") - } - i += 1 - //we are the beginning of a set operation - node.token, node.value = lfTokenSetKey, value - return node, nil - } - additionalValue, n := consumeUntil("&|!,()/") - additionalValue = strings.TrimSpace(additionalValue) - if additionalValue == ":" { - return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Missing set operation.") - } - i += n - value += additionalValue - } - - valueToCheckForSetOperation := strings.ToLower(value) - for setOperation := range validSetOperations { - idx := strings.Index(valueToCheckForSetOperation, " "+setOperation) - if idx > 0 { - return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-n+idx+1, fmt.Sprintf("Looks like you are using the set operator '%s' but did not provide a set key. Did you forget the ':'?", validSetOperations[setOperation])) - } - } - - node.token, node.value = lfTokenLabel, strings.TrimSpace(value) - } - return node, nil - } -} - -func MustParseLabelFilter(input string) LabelFilter { - filter, err := ParseLabelFilter(input) - if err != nil { - panic(err) - } - return filter -} - -func ParseLabelFilter(input string) (LabelFilter, error) { - if DEBUG_LABEL_FILTER_PARSING { - fmt.Println("\n==============") - fmt.Println("Input: ", input) - fmt.Print("Tokens: ") - } - if input == "" { - return func(_ []string) bool { return true }, nil - } - nextToken := tokenize(input) - - root := &treeNode{token: lfTokenRoot} - current := root -LOOP: - for { - node, err := nextToken() - if err != nil { - return nil, err - } - - if DEBUG_LABEL_FILTER_PARSING { - fmt.Print(node.tokenString() + " ") - } - - switch node.token { - case lfTokenEOF: - break LOOP - case lfTokenLabel, lfTokenRegexp, lfTokenSetKey: - if current.rightNode != nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, "Found two adjacent labels. You need an operator between them.") - } - current.setRightNode(node) - case lfTokenNot, lfTokenOpenGroup: - if current.rightNode != nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Invalid token '%s'.", node.token)) - } - current.setRightNode(node) - current = node - case lfTokenAnd, lfTokenOr: - if current.rightNode == nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Operator '%s' missing left hand operand.", node.token)) - } - nodeToStealFrom := current.firstAncestorWithPrecedenceLEQ(node.token.Precedence()) - node.setLeftNode(nodeToStealFrom.rightNode) - nodeToStealFrom.setRightNode(node) - current = node - case lfTokenSetOperation: - if current.rightNode == nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Set operation '%s' missing left hand operand.", node.value)) - } - node.setLeftNode(current.rightNode) - current.setRightNode(node) - current = node - case lfTokenSetArgument: - if current.rightNode != nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Unexpected set argument '%s'.", node.token)) - } - current.setRightNode(node) - case lfTokenCloseGroup: - firstUnmatchedOpenNode := current.firstUnmatchedOpenNode() - if firstUnmatchedOpenNode == nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, "Mismatched ')' - could not find matching '('.") - } - if firstUnmatchedOpenNode == current && current.rightNode == nil { - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, "Found empty '()' group.") - } - firstUnmatchedOpenNode.token = lfTokenCloseGroup //signify the group is now closed - current = firstUnmatchedOpenNode.parent - default: - return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Unknown token '%s'.", node.token)) - } - } - if DEBUG_LABEL_FILTER_PARSING { - fmt.Printf("\n Tree:\n%s", root.toString(0)) - } - return root.constructLabelFilter(input) -} - -func ValidateAndCleanupLabel(label string, cl CodeLocation) (string, error) { - out := strings.TrimSpace(label) - if out == "" { - return "", GinkgoErrors.InvalidEmptyLabel(cl) - } - if strings.ContainsAny(out, "&|!,()/") { - return "", GinkgoErrors.InvalidLabel(label, cl) - } - if out[0] == ':' { - return "", GinkgoErrors.InvalidLabel(label, cl) - } - if strings.Contains(out, ":") { - components := strings.SplitN(out, ":", 2) - if len(components) < 2 || components[1] == "" { - return "", GinkgoErrors.InvalidLabel(label, cl) - } - } - return out, nil -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go b/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go deleted file mode 100644 index 63f7a9f6..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go +++ /dev/null @@ -1,190 +0,0 @@ -package types - -import ( - "encoding/json" - "fmt" - "time" -) - -// ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports -// and across the network connection when running in parallel -type ReportEntryValue struct { - raw any //unexported to prevent gob from freaking out about unregistered structs - AsJSON string - Representation string -} - -func WrapEntryValue(value any) ReportEntryValue { - return ReportEntryValue{ - raw: value, - } -} - -func (rev ReportEntryValue) GetRawValue() any { - return rev.raw -} - -func (rev ReportEntryValue) String() string { - if rev.raw == nil { - return "" - } - if colorableStringer, ok := rev.raw.(ColorableStringer); ok { - return colorableStringer.ColorableString() - } - - if stringer, ok := rev.raw.(fmt.Stringer); ok { - return stringer.String() - } - if rev.Representation != "" { - return rev.Representation - } - return fmt.Sprintf("%+v", rev.raw) -} - -func (rev ReportEntryValue) MarshalJSON() ([]byte, error) { - //All this to capture the representation at encoding-time, not creating time - //This way users can Report on pointers and get their final values at reporting-time - out := struct { - AsJSON string - Representation string - }{ - Representation: rev.String(), - } - asJSON, err := json.Marshal(rev.raw) - if err != nil { - return nil, err - } - out.AsJSON = string(asJSON) - - return json.Marshal(out) -} - -func (rev *ReportEntryValue) UnmarshalJSON(data []byte) error { - in := struct { - AsJSON string - Representation string - }{} - err := json.Unmarshal(data, &in) - if err != nil { - return err - } - rev.AsJSON = in.AsJSON - rev.Representation = in.Representation - return json.Unmarshal([]byte(in.AsJSON), &(rev.raw)) -} - -func (rev ReportEntryValue) GobEncode() ([]byte, error) { - return rev.MarshalJSON() -} - -func (rev *ReportEntryValue) GobDecode(data []byte) error { - return rev.UnmarshalJSON(data) -} - -// ReportEntry captures information attached to `SpecReport` via `AddReportEntry` -type ReportEntry struct { - // Visibility captures the visibility policy for this ReportEntry - Visibility ReportEntryVisibility - // Location captures the location of the AddReportEntry call - Location CodeLocation - - Time time.Time //need this for backwards compatibility - TimelineLocation TimelineLocation - - // Name captures the name of this report - Name string - // Value captures the (optional) object passed into AddReportEntry - this can be - // anything the user wants. The value passed to AddReportEntry is wrapped in a ReportEntryValue to make - // encoding/decoding the value easier. To access the raw value call entry.GetRawValue() - Value ReportEntryValue -} - -// ColorableStringer is an interface that ReportEntry values can satisfy. If they do then ColorableString() is used to generate their representation. -type ColorableStringer interface { - ColorableString() string -} - -// StringRepresentation() returns the string representation of the value associated with the ReportEntry -- -// if value is nil, empty string is returned -// if value is a `ColorableStringer` then `Value.ColorableString()` is returned -// if value is a `fmt.Stringer` then `Value.String()` is returned -// otherwise the value is formatted with "%+v" -func (entry ReportEntry) StringRepresentation() string { - return entry.Value.String() -} - -// GetRawValue returns the Value object that was passed to AddReportEntry -// If called in-process this will be the same object that was passed into AddReportEntry. -// If used from a rehydrated JSON file _or_ in a ReportAfterSuite when running in parallel this will be -// a JSON-decoded {}interface. If you want to reconstitute your original object you can decode the entry.Value.AsJSON -// field yourself. -func (entry ReportEntry) GetRawValue() any { - return entry.Value.GetRawValue() -} - -func (entry ReportEntry) GetTimelineLocation() TimelineLocation { - return entry.TimelineLocation -} - -type ReportEntries []ReportEntry - -func (re ReportEntries) HasVisibility(visibilities ...ReportEntryVisibility) bool { - for _, entry := range re { - if entry.Visibility.Is(visibilities...) { - return true - } - } - return false -} - -func (re ReportEntries) WithVisibility(visibilities ...ReportEntryVisibility) ReportEntries { - out := ReportEntries{} - - for _, entry := range re { - if entry.Visibility.Is(visibilities...) { - out = append(out, entry) - } - } - - return out -} - -// ReportEntryVisibility governs the visibility of ReportEntries in Ginkgo's console reporter -type ReportEntryVisibility uint - -const ( - // Always print out this ReportEntry - ReportEntryVisibilityAlways ReportEntryVisibility = iota - // Only print out this ReportEntry if the spec fails or if the test is run with -v - ReportEntryVisibilityFailureOrVerbose - // Never print out this ReportEntry (note that ReportEntrys are always encoded in machine readable reports (e.g. JSON, JUnit, etc.)) - ReportEntryVisibilityNever -) - -var revEnumSupport = NewEnumSupport(map[uint]string{ - uint(ReportEntryVisibilityAlways): "always", - uint(ReportEntryVisibilityFailureOrVerbose): "failure-or-verbose", - uint(ReportEntryVisibilityNever): "never", -}) - -func (rev ReportEntryVisibility) String() string { - return revEnumSupport.String(uint(rev)) -} -func (rev *ReportEntryVisibility) UnmarshalJSON(b []byte) error { - out, err := revEnumSupport.UnmarshJSON(b) - *rev = ReportEntryVisibility(out) - return err -} -func (rev ReportEntryVisibility) MarshalJSON() ([]byte, error) { - return revEnumSupport.MarshJSON(uint(rev)) -} - -func (v ReportEntryVisibility) Is(visibilities ...ReportEntryVisibility) bool { - for _, visibility := range visibilities { - if v == visibility { - return true - } - } - - return false -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/types.go b/vendor/github.com/onsi/ginkgo/v2/types/types.go deleted file mode 100644 index ddcbec1b..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/types.go +++ /dev/null @@ -1,922 +0,0 @@ -package types - -import ( - "encoding/json" - "fmt" - "os" - "sort" - "strings" - "time" -) - -const GINKGO_FOCUS_EXIT_CODE = 197 - -var GINKGO_TIME_FORMAT = "01/02/06 15:04:05.999" - -func init() { - if os.Getenv("GINKGO_TIME_FORMAT") != "" { - GINKGO_TIME_FORMAT = os.Getenv("GINKGO_TIME_FORMAT") - } -} - -// Report captures information about a Ginkgo test run -type Report struct { - //SuitePath captures the absolute path to the test suite - SuitePath string - - //SuiteDescription captures the description string passed to the DSL's RunSpecs() function - SuiteDescription string - - //SuiteLabels captures any labels attached to the suite by the DSL's RunSpecs() function - SuiteLabels []string - - //SuiteSucceeded captures the success or failure status of the test run - //If true, the test run is considered successful. - //If false, the test run is considered unsuccessful - SuiteSucceeded bool - - //SuiteHasProgrammaticFocus captures whether the test suite has a test or set of tests that are programmatically focused - //(i.e an `FIt` or an `FDescribe` - SuiteHasProgrammaticFocus bool - - //SpecialSuiteFailureReasons may contain special failure reasons - //For example, a test suite might be considered "failed" even if none of the individual specs - //have a failure state. For example, if the user has configured --fail-on-pending the test suite - //will have failed if there are pending tests even though all non-pending tests may have passed. In such - //cases, Ginkgo populates SpecialSuiteFailureReasons with a clear message indicating the reason for the failure. - //SpecialSuiteFailureReasons is also populated if the test suite is interrupted by the user. - //Since multiple special failure reasons can occur, this field is a slice. - SpecialSuiteFailureReasons []string - - //PreRunStats contains a set of stats captured before the test run begins. This is primarily used - //by Ginkgo's reporter to tell the user how many specs are in the current suite (PreRunStats.TotalSpecs) - //and how many it intends to run (PreRunStats.SpecsThatWillRun) after applying any relevant focus or skip filters. - PreRunStats PreRunStats - - //StartTime and EndTime capture the start and end time of the test run - StartTime time.Time - EndTime time.Time - - //RunTime captures the duration of the test run - RunTime time.Duration - - //SuiteConfig captures the Ginkgo configuration governing this test run - //SuiteConfig includes information necessary for reproducing an identical test run, - //such as the random seed and any filters applied during the test run - SuiteConfig SuiteConfig - - //SpecReports is a list of all SpecReports generated by this test run - //It is empty when the SuiteReport is provided to ReportBeforeSuite - SpecReports SpecReports -} - -// PreRunStats contains a set of stats captured before the test run begins. This is primarily used -// by Ginkgo's reporter to tell the user how many specs are in the current suite (PreRunStats.TotalSpecs) -// and how many it intends to run (PreRunStats.SpecsThatWillRun) after applying any relevant focus or skip filters. -type PreRunStats struct { - TotalSpecs int - SpecsThatWillRun int -} - -// Add is used by Ginkgo's parallel aggregation mechanisms to combine test run reports form individual parallel processes -// to form a complete final report. -func (report Report) Add(other Report) Report { - report.SuiteSucceeded = report.SuiteSucceeded && other.SuiteSucceeded - - if other.StartTime.Before(report.StartTime) { - report.StartTime = other.StartTime - } - - if other.EndTime.After(report.EndTime) { - report.EndTime = other.EndTime - } - - specialSuiteFailureReasons := []string{} - reasonsLookup := map[string]bool{} - for _, reasons := range [][]string{report.SpecialSuiteFailureReasons, other.SpecialSuiteFailureReasons} { - for _, reason := range reasons { - if !reasonsLookup[reason] { - reasonsLookup[reason] = true - specialSuiteFailureReasons = append(specialSuiteFailureReasons, reason) - } - } - } - report.SpecialSuiteFailureReasons = specialSuiteFailureReasons - report.RunTime = report.EndTime.Sub(report.StartTime) - - reports := make(SpecReports, len(report.SpecReports)+len(other.SpecReports)) - copy(reports, report.SpecReports) - offset := len(report.SpecReports) - for i := range other.SpecReports { - reports[i+offset] = other.SpecReports[i] - } - - report.SpecReports = reports - return report -} - -// SpecReport captures information about a Ginkgo spec. -type SpecReport struct { - // ContainerHierarchyTexts is a slice containing the text strings of - // all Describe/Context/When containers in this spec's hierarchy. - ContainerHierarchyTexts []string - - // ContainerHierarchyLocations is a slice containing the CodeLocations of - // all Describe/Context/When containers in this spec's hierarchy. - ContainerHierarchyLocations []CodeLocation - - // ContainerHierarchyLabels is a slice containing the labels of - // all Describe/Context/When containers in this spec's hierarchy - ContainerHierarchyLabels [][]string - - // LeafNodeType, LeadNodeLocation, LeafNodeLabels and LeafNodeText capture the NodeType, CodeLocation, and text - // of the Ginkgo node being tested (typically an NodeTypeIt node, though this can also be - // one of the NodeTypesForSuiteLevelNodes node types) - LeafNodeType NodeType - LeafNodeLocation CodeLocation - LeafNodeLabels []string - LeafNodeText string - - // State captures whether the spec has passed, failed, etc. - State SpecState - - // IsSerial captures whether the spec has the Serial decorator - IsSerial bool - - // IsInOrderedContainer captures whether the spec appears in an Ordered container - IsInOrderedContainer bool - - // StartTime and EndTime capture the start and end time of the spec - StartTime time.Time - EndTime time.Time - - // RunTime captures the duration of the spec - RunTime time.Duration - - // ParallelProcess captures the parallel process that this spec ran on - ParallelProcess int - - // RunningInParallel captures whether this spec is part of a suite that ran in parallel - RunningInParallel bool - - //Failure is populated if a spec has failed, panicked, been interrupted, or skipped by the user (e.g. calling Skip()) - //It includes detailed information about the Failure - Failure Failure - - // NumAttempts captures the number of times this Spec was run. - // Flakey specs can be retried with ginkgo --flake-attempts=N or the use of the FlakeAttempts decorator. - // Repeated specs can be retried with the use of the MustPassRepeatedly decorator - NumAttempts int - - // MaxFlakeAttempts captures whether the spec has been retried with ginkgo --flake-attempts=N or the use of the FlakeAttempts decorator. - MaxFlakeAttempts int - - // MaxMustPassRepeatedly captures whether the spec has the MustPassRepeatedly decorator - MaxMustPassRepeatedly int - - // CapturedGinkgoWriterOutput contains text printed to the GinkgoWriter - CapturedGinkgoWriterOutput string - - // CapturedStdOutErr contains text printed to stdout/stderr (when running in parallel) - // This is always empty when running in series or calling CurrentSpecReport() - // It is used internally by Ginkgo's reporter - CapturedStdOutErr string - - // ReportEntries contains any reports added via `AddReportEntry` - ReportEntries ReportEntries - - // ProgressReports contains any progress reports generated during this spec. These can either be manually triggered, or automatically generated by Ginkgo via the PollProgressAfter() decorator - ProgressReports []ProgressReport - - // AdditionalFailures contains any failures that occurred after the initial spec failure. These typically occur in cleanup nodes after the initial failure and are only emitted when running in verbose mode. - AdditionalFailures []AdditionalFailure - - // SpecEvents capture additional events that occur during the spec run - SpecEvents SpecEvents -} - -func (report SpecReport) MarshalJSON() ([]byte, error) { - //All this to avoid emitting an empty Failure struct in the JSON - out := struct { - ContainerHierarchyTexts []string - ContainerHierarchyLocations []CodeLocation - ContainerHierarchyLabels [][]string - LeafNodeType NodeType - LeafNodeLocation CodeLocation - LeafNodeLabels []string - LeafNodeText string - State SpecState - StartTime time.Time - EndTime time.Time - RunTime time.Duration - ParallelProcess int - Failure *Failure `json:",omitempty"` - NumAttempts int - MaxFlakeAttempts int - MaxMustPassRepeatedly int - CapturedGinkgoWriterOutput string `json:",omitempty"` - CapturedStdOutErr string `json:",omitempty"` - ReportEntries ReportEntries `json:",omitempty"` - ProgressReports []ProgressReport `json:",omitempty"` - AdditionalFailures []AdditionalFailure `json:",omitempty"` - SpecEvents SpecEvents `json:",omitempty"` - }{ - ContainerHierarchyTexts: report.ContainerHierarchyTexts, - ContainerHierarchyLocations: report.ContainerHierarchyLocations, - ContainerHierarchyLabels: report.ContainerHierarchyLabels, - LeafNodeType: report.LeafNodeType, - LeafNodeLocation: report.LeafNodeLocation, - LeafNodeLabels: report.LeafNodeLabels, - LeafNodeText: report.LeafNodeText, - State: report.State, - StartTime: report.StartTime, - EndTime: report.EndTime, - RunTime: report.RunTime, - ParallelProcess: report.ParallelProcess, - Failure: nil, - ReportEntries: nil, - NumAttempts: report.NumAttempts, - MaxFlakeAttempts: report.MaxFlakeAttempts, - MaxMustPassRepeatedly: report.MaxMustPassRepeatedly, - CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput, - CapturedStdOutErr: report.CapturedStdOutErr, - } - - if !report.Failure.IsZero() { - out.Failure = &(report.Failure) - } - if len(report.ReportEntries) > 0 { - out.ReportEntries = report.ReportEntries - } - if len(report.ProgressReports) > 0 { - out.ProgressReports = report.ProgressReports - } - if len(report.AdditionalFailures) > 0 { - out.AdditionalFailures = report.AdditionalFailures - } - if len(report.SpecEvents) > 0 { - out.SpecEvents = report.SpecEvents - } - - return json.Marshal(out) -} - -// CombinedOutput returns a single string representation of both CapturedStdOutErr and CapturedGinkgoWriterOutput -// Note that both are empty when using CurrentSpecReport() so CurrentSpecReport().CombinedOutput() will always be empty. -// CombinedOutput() is used internally by Ginkgo's reporter. -func (report SpecReport) CombinedOutput() string { - if report.CapturedStdOutErr == "" { - return report.CapturedGinkgoWriterOutput - } - if report.CapturedGinkgoWriterOutput == "" { - return report.CapturedStdOutErr - } - return report.CapturedStdOutErr + "\n" + report.CapturedGinkgoWriterOutput -} - -// Failed returns true if report.State is one of the SpecStateFailureStates -// (SpecStateFailed, SpecStatePanicked, SpecStateinterrupted, SpecStateAborted) -func (report SpecReport) Failed() bool { - return report.State.Is(SpecStateFailureStates) -} - -// FullText returns a concatenation of all the report.ContainerHierarchyTexts and report.LeafNodeText -func (report SpecReport) FullText() string { - texts := []string{} - texts = append(texts, report.ContainerHierarchyTexts...) - if report.LeafNodeText != "" { - texts = append(texts, report.LeafNodeText) - } - return strings.Join(texts, " ") -} - -// Labels returns a deduped set of all the spec's Labels. -func (report SpecReport) Labels() []string { - out := []string{} - seen := map[string]bool{} - for _, labels := range report.ContainerHierarchyLabels { - for _, label := range labels { - if !seen[label] { - seen[label] = true - out = append(out, label) - } - } - } - for _, label := range report.LeafNodeLabels { - if !seen[label] { - seen[label] = true - out = append(out, label) - } - } - - return out -} - -// MatchesLabelFilter returns true if the spec satisfies the passed in label filter query -func (report SpecReport) MatchesLabelFilter(query string) (bool, error) { - filter, err := ParseLabelFilter(query) - if err != nil { - return false, err - } - return filter(report.Labels()), nil -} - -// FileName() returns the name of the file containing the spec -func (report SpecReport) FileName() string { - return report.LeafNodeLocation.FileName -} - -// LineNumber() returns the line number of the leaf node -func (report SpecReport) LineNumber() int { - return report.LeafNodeLocation.LineNumber -} - -// FailureMessage() returns the failure message (or empty string if the test hasn't failed) -func (report SpecReport) FailureMessage() string { - return report.Failure.Message -} - -// FailureLocation() returns the location of the failure (or an empty CodeLocation if the test hasn't failed) -func (report SpecReport) FailureLocation() CodeLocation { - return report.Failure.Location -} - -// Timeline() returns a timeline view of the report -func (report SpecReport) Timeline() Timeline { - timeline := Timeline{} - if !report.Failure.IsZero() { - timeline = append(timeline, report.Failure) - if report.Failure.AdditionalFailure != nil { - timeline = append(timeline, *(report.Failure.AdditionalFailure)) - } - } - for _, additionalFailure := range report.AdditionalFailures { - timeline = append(timeline, additionalFailure) - } - for _, reportEntry := range report.ReportEntries { - timeline = append(timeline, reportEntry) - } - for _, progressReport := range report.ProgressReports { - timeline = append(timeline, progressReport) - } - for _, specEvent := range report.SpecEvents { - timeline = append(timeline, specEvent) - } - sort.Sort(timeline) - return timeline -} - -type SpecReports []SpecReport - -// WithLeafNodeType returns the subset of SpecReports with LeafNodeType matching one of the requested NodeTypes -func (reports SpecReports) WithLeafNodeType(nodeTypes NodeType) SpecReports { - count := 0 - for i := range reports { - if reports[i].LeafNodeType.Is(nodeTypes) { - count++ - } - } - - out := make(SpecReports, count) - j := 0 - for i := range reports { - if reports[i].LeafNodeType.Is(nodeTypes) { - out[j] = reports[i] - j++ - } - } - return out -} - -// WithState returns the subset of SpecReports with State matching one of the requested SpecStates -func (reports SpecReports) WithState(states SpecState) SpecReports { - count := 0 - for i := range reports { - if reports[i].State.Is(states) { - count++ - } - } - - out, j := make(SpecReports, count), 0 - for i := range reports { - if reports[i].State.Is(states) { - out[j] = reports[i] - j++ - } - } - return out -} - -// CountWithState returns the number of SpecReports with State matching one of the requested SpecStates -func (reports SpecReports) CountWithState(states SpecState) int { - n := 0 - for i := range reports { - if reports[i].State.Is(states) { - n += 1 - } - } - return n -} - -// If the Spec passes, CountOfFlakedSpecs returns the number of SpecReports that failed after multiple attempts. -func (reports SpecReports) CountOfFlakedSpecs() int { - n := 0 - for i := range reports { - if reports[i].MaxFlakeAttempts > 1 && reports[i].State.Is(SpecStatePassed) && reports[i].NumAttempts > 1 { - n += 1 - } - } - return n -} - -// If the Spec fails, CountOfRepeatedSpecs returns the number of SpecReports that passed after multiple attempts -func (reports SpecReports) CountOfRepeatedSpecs() int { - n := 0 - for i := range reports { - if reports[i].MaxMustPassRepeatedly > 1 && reports[i].State.Is(SpecStateFailureStates) && reports[i].NumAttempts > 1 { - n += 1 - } - } - return n -} - -// TimelineLocation captures the location of an event in the spec's timeline -type TimelineLocation struct { - //Offset is the offset (in bytes) of the event relative to the GinkgoWriter stream - Offset int `json:",omitempty"` - - //Order is the order of the event with respect to other events. The absolute value of Order - //is irrelevant. All that matters is that an event with a lower Order occurs before ane vent with a higher Order - Order int `json:",omitempty"` - - Time time.Time -} - -// TimelineEvent represent an event on the timeline -// consumers of Timeline will need to check the concrete type of each entry to determine how to handle it -type TimelineEvent interface { - GetTimelineLocation() TimelineLocation -} - -type Timeline []TimelineEvent - -func (t Timeline) Len() int { return len(t) } -func (t Timeline) Less(i, j int) bool { - return t[i].GetTimelineLocation().Order < t[j].GetTimelineLocation().Order -} -func (t Timeline) Swap(i, j int) { t[i], t[j] = t[j], t[i] } -func (t Timeline) WithoutHiddenReportEntries() Timeline { - out := Timeline{} - for _, event := range t { - if reportEntry, isReportEntry := event.(ReportEntry); isReportEntry && reportEntry.Visibility == ReportEntryVisibilityNever { - continue - } - out = append(out, event) - } - return out -} - -func (t Timeline) WithoutVeryVerboseSpecEvents() Timeline { - out := Timeline{} - for _, event := range t { - if specEvent, isSpecEvent := event.(SpecEvent); isSpecEvent && specEvent.IsOnlyVisibleAtVeryVerbose() { - continue - } - out = append(out, event) - } - return out -} - -// Failure captures failure information for an individual test -type Failure struct { - // Message - the failure message passed into Fail(...). When using a matcher library - // like Gomega, this will contain the failure message generated by Gomega. - // - // Message is also populated if the user has called Skip(...). - Message string - - // Location - the CodeLocation where the failure occurred - // This CodeLocation will include a fully-populated StackTrace - Location CodeLocation - - TimelineLocation TimelineLocation - - // ForwardedPanic - if the failure represents a captured panic (i.e. Summary.State == SpecStatePanicked) - // then ForwardedPanic will be populated with a string representation of the captured panic. - ForwardedPanic string `json:",omitempty"` - - // FailureNodeContext - one of three contexts describing the node in which the failure occurred: - // FailureNodeIsLeafNode means the failure occurred in the leaf node of the associated SpecReport. None of the other FailureNode fields will be populated - // FailureNodeAtTopLevel means the failure occurred in a non-leaf node that is defined at the top-level of the spec (i.e. not in a container). FailureNodeType and FailureNodeLocation will be populated. - // FailureNodeInContainer means the failure occurred in a non-leaf node that is defined within a container. FailureNodeType, FailureNodeLocation, and FailureNodeContainerIndex will be populated. - // - // FailureNodeType will contain the NodeType of the node in which the failure occurred. - // FailureNodeLocation will contain the CodeLocation of the node in which the failure occurred. - // If populated, FailureNodeContainerIndex will be the index into SpecReport.ContainerHierarchyTexts and SpecReport.ContainerHierarchyLocations that represents the parent container of the node in which the failure occurred. - FailureNodeContext FailureNodeContext `json:",omitempty"` - - FailureNodeType NodeType `json:",omitempty"` - - FailureNodeLocation CodeLocation `json:",omitempty"` - - FailureNodeContainerIndex int `json:",omitempty"` - - //ProgressReport is populated if the spec was interrupted or timed out - ProgressReport ProgressReport `json:",omitempty"` - - //AdditionalFailure is non-nil if a follow-on failure occurred within the same node after the primary failure. This only happens when a node has timed out or been interrupted. In such cases the AdditionalFailure can include information about where/why the spec was stuck. - AdditionalFailure *AdditionalFailure `json:",omitempty"` -} - -func (f Failure) IsZero() bool { - return f.Message == "" && (f.Location == CodeLocation{}) -} - -func (f Failure) GetTimelineLocation() TimelineLocation { - return f.TimelineLocation -} - -// FailureNodeContext captures the location context for the node containing the failing line of code -type FailureNodeContext uint - -const ( - FailureNodeContextInvalid FailureNodeContext = iota - - FailureNodeIsLeafNode - FailureNodeAtTopLevel - FailureNodeInContainer -) - -var fncEnumSupport = NewEnumSupport(map[uint]string{ - uint(FailureNodeContextInvalid): "INVALID FAILURE NODE CONTEXT", - uint(FailureNodeIsLeafNode): "leaf-node", - uint(FailureNodeAtTopLevel): "top-level", - uint(FailureNodeInContainer): "in-container", -}) - -func (fnc FailureNodeContext) String() string { - return fncEnumSupport.String(uint(fnc)) -} -func (fnc *FailureNodeContext) UnmarshalJSON(b []byte) error { - out, err := fncEnumSupport.UnmarshJSON(b) - *fnc = FailureNodeContext(out) - return err -} -func (fnc FailureNodeContext) MarshalJSON() ([]byte, error) { - return fncEnumSupport.MarshJSON(uint(fnc)) -} - -// AdditionalFailure capturs any additional failures that occur after the initial failure of a psec -// these typically occur in clean up nodes after the spec has failed. -// We can't simply use Failure as we want to track the SpecState to know what kind of failure this is -type AdditionalFailure struct { - State SpecState - Failure Failure -} - -func (f AdditionalFailure) GetTimelineLocation() TimelineLocation { - return f.Failure.TimelineLocation -} - -// SpecState captures the state of a spec -// To determine if a given `state` represents a failure state, use `state.Is(SpecStateFailureStates)` -type SpecState uint - -const ( - SpecStateInvalid SpecState = 0 - - SpecStatePending SpecState = 1 << iota - SpecStateSkipped - SpecStatePassed - SpecStateFailed - SpecStateAborted - SpecStatePanicked - SpecStateInterrupted - SpecStateTimedout -) - -var ssEnumSupport = NewEnumSupport(map[uint]string{ - uint(SpecStateInvalid): "INVALID SPEC STATE", - uint(SpecStatePending): "pending", - uint(SpecStateSkipped): "skipped", - uint(SpecStatePassed): "passed", - uint(SpecStateFailed): "failed", - uint(SpecStateAborted): "aborted", - uint(SpecStatePanicked): "panicked", - uint(SpecStateInterrupted): "interrupted", - uint(SpecStateTimedout): "timedout", -}) - -func (ss SpecState) String() string { - return ssEnumSupport.String(uint(ss)) -} -func (ss SpecState) GomegaString() string { - return ssEnumSupport.String(uint(ss)) -} -func (ss *SpecState) UnmarshalJSON(b []byte) error { - out, err := ssEnumSupport.UnmarshJSON(b) - *ss = SpecState(out) - return err -} -func (ss SpecState) MarshalJSON() ([]byte, error) { - return ssEnumSupport.MarshJSON(uint(ss)) -} - -var SpecStateFailureStates = SpecStateFailed | SpecStateTimedout | SpecStateAborted | SpecStatePanicked | SpecStateInterrupted - -func (ss SpecState) Is(states SpecState) bool { - return ss&states != 0 -} - -// ProgressReport captures the progress of the current spec. It is, effectively, a structured Ginkgo-aware stack trace -type ProgressReport struct { - Message string `json:",omitempty"` - ParallelProcess int `json:",omitempty"` - RunningInParallel bool `json:",omitempty"` - - ContainerHierarchyTexts []string `json:",omitempty"` - LeafNodeText string `json:",omitempty"` - LeafNodeLocation CodeLocation `json:",omitempty"` - SpecStartTime time.Time `json:",omitempty"` - - CurrentNodeType NodeType `json:",omitempty"` - CurrentNodeText string `json:",omitempty"` - CurrentNodeLocation CodeLocation `json:",omitempty"` - CurrentNodeStartTime time.Time `json:",omitempty"` - - CurrentStepText string `json:",omitempty"` - CurrentStepLocation CodeLocation `json:",omitempty"` - CurrentStepStartTime time.Time `json:",omitempty"` - - AdditionalReports []string `json:",omitempty"` - - CapturedGinkgoWriterOutput string `json:",omitempty"` - TimelineLocation TimelineLocation `json:",omitempty"` - - Goroutines []Goroutine `json:",omitempty"` -} - -func (pr ProgressReport) IsZero() bool { - return pr.CurrentNodeType == NodeTypeInvalid -} - -func (pr ProgressReport) Time() time.Time { - return pr.TimelineLocation.Time -} - -func (pr ProgressReport) SpecGoroutine() Goroutine { - for _, goroutine := range pr.Goroutines { - if goroutine.IsSpecGoroutine { - return goroutine - } - } - return Goroutine{} -} - -func (pr ProgressReport) HighlightedGoroutines() []Goroutine { - out := []Goroutine{} - for _, goroutine := range pr.Goroutines { - if goroutine.IsSpecGoroutine || !goroutine.HasHighlights() { - continue - } - out = append(out, goroutine) - } - return out -} - -func (pr ProgressReport) OtherGoroutines() []Goroutine { - out := []Goroutine{} - for _, goroutine := range pr.Goroutines { - if goroutine.IsSpecGoroutine || goroutine.HasHighlights() { - continue - } - out = append(out, goroutine) - } - return out -} - -func (pr ProgressReport) WithoutCapturedGinkgoWriterOutput() ProgressReport { - out := pr - out.CapturedGinkgoWriterOutput = "" - return out -} - -func (pr ProgressReport) WithoutOtherGoroutines() ProgressReport { - out := pr - filteredGoroutines := []Goroutine{} - for _, goroutine := range pr.Goroutines { - if goroutine.IsSpecGoroutine || goroutine.HasHighlights() { - filteredGoroutines = append(filteredGoroutines, goroutine) - } - } - out.Goroutines = filteredGoroutines - return out -} - -func (pr ProgressReport) GetTimelineLocation() TimelineLocation { - return pr.TimelineLocation -} - -type Goroutine struct { - ID uint64 - State string - Stack []FunctionCall - IsSpecGoroutine bool -} - -func (g Goroutine) IsZero() bool { - return g.ID == 0 -} - -func (g Goroutine) HasHighlights() bool { - for _, fc := range g.Stack { - if fc.Highlight { - return true - } - } - - return false -} - -type FunctionCall struct { - Function string - Filename string - Line int - Highlight bool `json:",omitempty"` - Source []string `json:",omitempty"` - SourceHighlight int `json:",omitempty"` -} - -// NodeType captures the type of a given Ginkgo Node -type NodeType uint - -const ( - NodeTypeInvalid NodeType = 0 - - NodeTypeContainer NodeType = 1 << iota - NodeTypeIt - - NodeTypeBeforeEach - NodeTypeJustBeforeEach - NodeTypeAfterEach - NodeTypeJustAfterEach - - NodeTypeBeforeAll - NodeTypeAfterAll - - NodeTypeBeforeSuite - NodeTypeSynchronizedBeforeSuite - NodeTypeAfterSuite - NodeTypeSynchronizedAfterSuite - - NodeTypeReportBeforeEach - NodeTypeReportAfterEach - NodeTypeReportBeforeSuite - NodeTypeReportAfterSuite - - NodeTypeCleanupInvalid - NodeTypeCleanupAfterEach - NodeTypeCleanupAfterAll - NodeTypeCleanupAfterSuite -) - -var NodeTypesForContainerAndIt = NodeTypeContainer | NodeTypeIt -var NodeTypesForSuiteLevelNodes = NodeTypeBeforeSuite | NodeTypeSynchronizedBeforeSuite | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite | NodeTypeCleanupAfterSuite -var NodeTypesAllowedDuringCleanupInterrupt = NodeTypeAfterEach | NodeTypeJustAfterEach | NodeTypeAfterAll | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeCleanupAfterEach | NodeTypeCleanupAfterAll | NodeTypeCleanupAfterSuite -var NodeTypesAllowedDuringReportInterrupt = NodeTypeReportBeforeEach | NodeTypeReportAfterEach | NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite - -var ntEnumSupport = NewEnumSupport(map[uint]string{ - uint(NodeTypeInvalid): "INVALID NODE TYPE", - uint(NodeTypeContainer): "Container", - uint(NodeTypeIt): "It", - uint(NodeTypeBeforeEach): "BeforeEach", - uint(NodeTypeJustBeforeEach): "JustBeforeEach", - uint(NodeTypeAfterEach): "AfterEach", - uint(NodeTypeJustAfterEach): "JustAfterEach", - uint(NodeTypeBeforeAll): "BeforeAll", - uint(NodeTypeAfterAll): "AfterAll", - uint(NodeTypeBeforeSuite): "BeforeSuite", - uint(NodeTypeSynchronizedBeforeSuite): "SynchronizedBeforeSuite", - uint(NodeTypeAfterSuite): "AfterSuite", - uint(NodeTypeSynchronizedAfterSuite): "SynchronizedAfterSuite", - uint(NodeTypeReportBeforeEach): "ReportBeforeEach", - uint(NodeTypeReportAfterEach): "ReportAfterEach", - uint(NodeTypeReportBeforeSuite): "ReportBeforeSuite", - uint(NodeTypeReportAfterSuite): "ReportAfterSuite", - uint(NodeTypeCleanupInvalid): "DeferCleanup", - uint(NodeTypeCleanupAfterEach): "DeferCleanup (Each)", - uint(NodeTypeCleanupAfterAll): "DeferCleanup (All)", - uint(NodeTypeCleanupAfterSuite): "DeferCleanup (Suite)", -}) - -func (nt NodeType) String() string { - return ntEnumSupport.String(uint(nt)) -} -func (nt *NodeType) UnmarshalJSON(b []byte) error { - out, err := ntEnumSupport.UnmarshJSON(b) - *nt = NodeType(out) - return err -} -func (nt NodeType) MarshalJSON() ([]byte, error) { - return ntEnumSupport.MarshJSON(uint(nt)) -} - -func (nt NodeType) Is(nodeTypes NodeType) bool { - return nt&nodeTypes != 0 -} - -/* -SpecEvent captures a vareity of events that can occur when specs run. See SpecEventType for the list of available events. -*/ -type SpecEvent struct { - SpecEventType SpecEventType - - CodeLocation CodeLocation - TimelineLocation TimelineLocation - - Message string `json:",omitempty"` - Duration time.Duration `json:",omitempty"` - NodeType NodeType `json:",omitempty"` - Attempt int `json:",omitempty"` -} - -func (se SpecEvent) GetTimelineLocation() TimelineLocation { - return se.TimelineLocation -} - -func (se SpecEvent) IsOnlyVisibleAtVeryVerbose() bool { - return se.SpecEventType.Is(SpecEventByEnd | SpecEventNodeStart | SpecEventNodeEnd) -} - -func (se SpecEvent) GomegaString() string { - out := &strings.Builder{} - out.WriteString("[" + se.SpecEventType.String() + " SpecEvent] ") - if se.Message != "" { - out.WriteString("Message=") - out.WriteString(`"` + se.Message + `",`) - } - if se.Duration != 0 { - out.WriteString("Duration=" + se.Duration.String() + ",") - } - if se.NodeType != NodeTypeInvalid { - out.WriteString("NodeType=" + se.NodeType.String() + ",") - } - if se.Attempt != 0 { - out.WriteString(fmt.Sprintf("Attempt=%d", se.Attempt) + ",") - } - out.WriteString("CL=" + se.CodeLocation.String() + ",") - out.WriteString(fmt.Sprintf("TL.Offset=%d", se.TimelineLocation.Offset)) - - return out.String() -} - -type SpecEvents []SpecEvent - -func (se SpecEvents) WithType(seType SpecEventType) SpecEvents { - out := SpecEvents{} - for _, event := range se { - if event.SpecEventType.Is(seType) { - out = append(out, event) - } - } - return out -} - -type SpecEventType uint - -const ( - SpecEventInvalid SpecEventType = 0 - - SpecEventByStart SpecEventType = 1 << iota - SpecEventByEnd - SpecEventNodeStart - SpecEventNodeEnd - SpecEventSpecRepeat - SpecEventSpecRetry -) - -var seEnumSupport = NewEnumSupport(map[uint]string{ - uint(SpecEventInvalid): "INVALID SPEC EVENT", - uint(SpecEventByStart): "By", - uint(SpecEventByEnd): "By (End)", - uint(SpecEventNodeStart): "Node", - uint(SpecEventNodeEnd): "Node (End)", - uint(SpecEventSpecRepeat): "Repeat", - uint(SpecEventSpecRetry): "Retry", -}) - -func (se SpecEventType) String() string { - return seEnumSupport.String(uint(se)) -} -func (se *SpecEventType) UnmarshalJSON(b []byte) error { - out, err := seEnumSupport.UnmarshJSON(b) - *se = SpecEventType(out) - return err -} -func (se SpecEventType) MarshalJSON() ([]byte, error) { - return seEnumSupport.MarshJSON(uint(se)) -} - -func (se SpecEventType) Is(specEventTypes SpecEventType) bool { - return se&specEventTypes != 0 -} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go deleted file mode 100644 index 158ac2fd..00000000 --- a/vendor/github.com/onsi/ginkgo/v2/types/version.go +++ /dev/null @@ -1,3 +0,0 @@ -package types - -const VERSION = "2.23.4" diff --git a/vendor/github.com/quic-go/quic-go/.golangci.yml b/vendor/github.com/quic-go/quic-go/.golangci.yml index 656fa76d..cd2a3f87 100644 --- a/vendor/github.com/quic-go/quic-go/.golangci.yml +++ b/vendor/github.com/quic-go/quic-go/.golangci.yml @@ -9,11 +9,13 @@ linters: - govet - ineffassign - misspell + - nolintlint - prealloc - staticcheck - unconvert - unparam - unused + - usetesting settings: depguard: rules: @@ -35,9 +37,31 @@ linters: deny: - pkg: crypto/rsa desc: "use crypto/ed25519 instead" + ginkgo: + list-mode: original + deny: + - pkg: github.com/onsi/ginkgo + desc: "use standard Go tests" + - pkg: github.com/onsi/ginkgo/v2 + desc: "use standard Go tests" + - pkg: github.com/onsi/gomega + desc: "use standard Go tests" + http3-internal: + list-mode: lax + files: + - '**/http3/**' + deny: + - pkg: 'github.com/quic-go/quic-go/internal' + desc: 'no dependency on quic-go/internal' + allow: + - 'github.com/quic-go/quic-go/internal/synctest' misspell: ignore-rules: - ect + # see https://github.com/ldez/usetesting/issues/10 + usetesting: + context-background: false + context-todo: false exclusions: generated: lax presets: diff --git a/vendor/github.com/quic-go/quic-go/Changelog.md b/vendor/github.com/quic-go/quic-go/Changelog.md deleted file mode 100644 index 82df5fb2..00000000 --- a/vendor/github.com/quic-go/quic-go/Changelog.md +++ /dev/null @@ -1,109 +0,0 @@ -# Changelog - -## v0.22.0 (2021-07-25) - -- Use `ReadBatch` to read multiple UDP packets from the socket with a single syscall -- Add a config option (`Config.DisableVersionNegotiationPackets`) to disable sending of Version Negotiation packets -- Drop support for QUIC draft versions 32 and 34 -- Remove the `RetireBugBackwardsCompatibilityMode`, which was intended to mitigate a bug when retiring connection IDs in quic-go in v0.17.2 and ealier - -## v0.21.2 (2021-07-15) - -- Update qtls (for Go 1.15, 1.16 and 1.17rc1) to include the fix for the crypto/tls panic (see https://groups.google.com/g/golang-dev/c/5LJ2V7rd-Ag/m/YGLHVBZ6AAAJ for details) - -## v0.21.0 (2021-06-01) - -- quic-go now supports RFC 9000! - -## v0.20.0 (2021-03-19) - -- Remove the `quic.Config.HandshakeTimeout`. Introduce a `quic.Config.HandshakeIdleTimeout`. - -## v0.17.1 (2020-06-20) - -- Supports QUIC WG draft-29. -- Improve bundling of ACK frames (#2543). - -## v0.16.0 (2020-05-31) - -- Supports QUIC WG draft-28. - -## v0.15.0 (2020-03-01) - -- Supports QUIC WG draft-27. -- Add support for 0-RTT. -- Remove `Session.Close()`. Applications need to pass an application error code to the transport using `Session.CloseWithError()`. -- Make the TLS Cipher Suites configurable (via `tls.Config.CipherSuites`). - -## v0.14.0 (2019-12-04) - -- Supports QUIC WG draft-24. - -## v0.13.0 (2019-11-05) - -- Supports QUIC WG draft-23. -- Add an `EarlyListener` that allows sending of 0.5-RTT data. -- Add a `TokenStore` to store address validation tokens. -- Issue and use new connection IDs during a connection. - -## v0.12.0 (2019-08-05) - -- Implement HTTP/3. -- Rename `quic.Cookie` to `quic.Token` and `quic.Config.AcceptCookie` to `quic.Config.AcceptToken`. -- Distinguish between Retry tokens and tokens sent in NEW_TOKEN frames. -- Enforce application protocol negotiation (via `tls.Config.NextProtos`). -- Use a varint for error codes. -- Add support for [quic-trace](https://github.com/google/quic-trace). -- Add a context to `Listener.Accept`, `Session.Accept{Uni}Stream` and `Session.Open{Uni}StreamSync`. -- Implement TLS key updates. - -## v0.11.0 (2019-04-05) - -- Drop support for gQUIC. For qQUIC support, please switch to the *gquic* branch. -- Implement QUIC WG draft-19. -- Use [qtls](https://github.com/marten-seemann/qtls) for TLS 1.3. -- Return a `tls.ConnectionState` from `quic.Session.ConnectionState()`. -- Remove the error return values from `quic.Stream.CancelRead()` and `quic.Stream.CancelWrite()` - -## v0.10.0 (2018-08-28) - -- Add support for QUIC 44, drop support for QUIC 42. - -## v0.9.0 (2018-08-15) - -- Add a `quic.Config` option for the length of the connection ID (for IETF QUIC). -- Split Session.Close into one method for regular closing and one for closing with an error. - -## v0.8.0 (2018-06-26) - -- Add support for unidirectional streams (for IETF QUIC). -- Add a `quic.Config` option for the maximum number of incoming streams. -- Add support for QUIC 42 and 43. -- Add dial functions that use a context. -- Multiplex clients on a net.PacketConn, when using Dial(conn). - -## v0.7.0 (2018-02-03) - -- The lower boundary for packets included in ACKs is now derived, and the value sent in STOP_WAITING frames is ignored. -- Remove `DialNonFWSecure` and `DialAddrNonFWSecure`. -- Expose the `ConnectionState` in the `Session` (experimental API). -- Implement packet pacing. - -## v0.6.0 (2017-12-12) - -- Add support for QUIC 39, drop support for QUIC 35 - 37 -- Added `quic.Config` options for maximal flow control windows -- Add a `quic.Config` option for QUIC versions -- Add a `quic.Config` option to request omission of the connection ID from a server -- Add a `quic.Config` option to configure the source address validation -- Add a `quic.Config` option to configure the handshake timeout -- Add a `quic.Config` option to configure the idle timeout -- Add a `quic.Config` option to configure keep-alive -- Rename the STK to Cookie -- Implement `net.Conn`-style deadlines for streams -- Remove the `tls.Config` from the `quic.Config`. The `tls.Config` must now be passed to the `Dial` and `Listen` functions as a separate parameter. See the [Godoc](https://godoc.org/github.com/quic-go/quic-go) for details. -- Changed the log level environment variable to only accept strings ("DEBUG", "INFO", "ERROR"), see [the wiki](https://github.com/quic-go/quic-go/wiki/Logging) for more details. -- Rename the `h2quic.QuicRoundTripper` to `h2quic.RoundTripper` -- Changed `h2quic.Server.Serve()` to accept a `net.PacketConn` -- Drop support for Go 1.7 and 1.8. -- Various bugfixes diff --git a/vendor/github.com/quic-go/quic-go/README.md b/vendor/github.com/quic-go/quic-go/README.md index ccc9e213..85751dbe 100644 --- a/vendor/github.com/quic-go/quic-go/README.md +++ b/vendor/github.com/quic-go/quic-go/README.md @@ -1,11 +1,14 @@ +
+ +
+ # A QUIC implementation in pure Go - [![Documentation](https://img.shields.io/badge/docs-quic--go.net-red?style=flat)](https://quic-go.net/docs/) [![PkgGoDev](https://pkg.go.dev/badge/github.com/quic-go/quic-go)](https://pkg.go.dev/github.com/quic-go/quic-go) [![Code Coverage](https://img.shields.io/codecov/c/github/quic-go/quic-go/master.svg?style=flat-square)](https://codecov.io/gh/quic-go/quic-go/) -[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/quic-go.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:quic-go) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/quic-go.svg)](https://issues.oss-fuzz.com/issues?q=quic-go) quic-go is an implementation of the QUIC protocol ([RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000), [RFC 9001](https://datatracker.ietf.org/doc/html/rfc9001), [RFC 9002](https://datatracker.ietf.org/doc/html/rfc9002)) in Go. It has support for HTTP/3 ([RFC 9114](https://datatracker.ietf.org/doc/html/rfc9114)), including QPACK ([RFC 9204](https://datatracker.ietf.org/doc/html/rfc9204)) and HTTP Datagrams ([RFC 9297](https://datatracker.ietf.org/doc/html/rfc9297)). @@ -15,6 +18,7 @@ In addition to these base RFCs, it also implements the following RFCs: * Datagram Packetization Layer Path MTU Discovery (DPLPMTUD, [RFC 8899](https://datatracker.ietf.org/doc/html/rfc8899)) * QUIC Version 2 ([RFC 9369](https://datatracker.ietf.org/doc/html/rfc9369)) * QUIC Event Logging using qlog ([draft-ietf-quic-qlog-main-schema](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-main-schema/) and [draft-ietf-quic-qlog-quic-events](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-quic-events/)) +* QUIC Stream Resets with Partial Delivery ([draft-ietf-quic-reliable-stream-reset](https://datatracker.ietf.org/doc/html/draft-ietf-quic-reliable-stream-reset-07)) Support for WebTransport over HTTP/3 ([draft-ietf-webtrans-http3](https://datatracker.ietf.org/doc/draft-ietf-webtrans-http3/)) is implemented in [webtransport-go](https://github.com/quic-go/webtransport-go). @@ -33,6 +37,7 @@ Detailed documentation can be found on [quic-go.net](https://quic-go.net/docs/). | [gost](https://github.com/go-gost/gost) | A simple security tunnel written in Go | ![GitHub Repo stars](https://img.shields.io/github/stars/go-gost/gost?style=flat-square) | | [Hysteria](https://github.com/apernet/hysteria) | A powerful, lightning fast and censorship resistant proxy | ![GitHub Repo stars](https://img.shields.io/github/stars/apernet/hysteria?style=flat-square) | | [Mercure](https://github.com/dunglas/mercure) | An open, easy, fast, reliable and battery-efficient solution for real-time communications | ![GitHub Repo stars](https://img.shields.io/github/stars/dunglas/mercure?style=flat-square) | +| [nodepass](https://github.com/yosebyte/nodepass) | A secure, efficient TCP/UDP tunneling solution that delivers fast, reliable access across network restrictions using pre-established TCP/QUIC connections | ![GitHub Repo stars](https://img.shields.io/github/stars/yosebyte/nodepass?style=flat-square) | | [OONI Probe](https://github.com/ooni/probe-cli) | Next generation OONI Probe. Library and CLI tool. | ![GitHub Repo stars](https://img.shields.io/github/stars/ooni/probe-cli?style=flat-square) | | [reverst](https://github.com/flipt-io/reverst) | Reverse Tunnels in Go over HTTP/3 and QUIC | ![GitHub Repo stars](https://img.shields.io/github/stars/flipt-io/reverst?style=flat-square) | | [RoadRunner](https://github.com/roadrunner-server/roadrunner) | High-performance PHP application server, process manager written in Go and powered with plugins | ![GitHub Repo stars](https://img.shields.io/github/stars/roadrunner-server/roadrunner?style=flat-square) | @@ -50,3 +55,7 @@ quic-go always aims to support the latest two Go releases. ## Contributing We are always happy to welcome new contributors! We have a number of self-contained issues that are suitable for first-time contributors, they are tagged with [help wanted](https://github.com/quic-go/quic-go/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). If you have any questions, please feel free to reach out by opening an issue or leaving a comment. + +## License + +The code is licensed under the MIT license. The logo and brand assets are excluded from the MIT license. See [assets/LICENSE.md](https://github.com/quic-go/quic-go/tree/master/assets/LICENSE.md) for the full usage policy and details. diff --git a/vendor/github.com/quic-go/quic-go/SECURITY.md b/vendor/github.com/quic-go/quic-go/SECURITY.md index c24c08f8..79fe1f56 100644 --- a/vendor/github.com/quic-go/quic-go/SECURITY.md +++ b/vendor/github.com/quic-go/quic-go/SECURITY.md @@ -1,19 +1,14 @@ # Security Policy -quic-go still in development. This means that there may be problems in our protocols, -or there may be mistakes in our implementations. -We take security vulnerabilities very seriously. If you discover a security issue, -please bring it to our attention right away! +quic-go is an implementation of the QUIC protocol and related standards. No software is perfect, and we take reports of potential security issues very seriously. ## Reporting a Vulnerability -If you find a vulnerability that may affect live deployments -- for example, by exposing -a remote execution exploit -- please [**report privately**](https://github.com/quic-go/quic-go/security/advisories/new). -Please **DO NOT file a public issue**. +If you discover a vulnerability that could affect production deployments (e.g., a remotely exploitable issue), please report it [**privately**](https://github.com/quic-go/quic-go/security/advisories/new). +Please **DO NOT file a public issue** for exploitable vulnerabilities. -If the issue is an implementation weakness that cannot be immediately exploited or -something not yet deployed, just discuss it openly. +If the issue is theoretical, non-exploitable, or related to an experimental feature, you may discuss it openly by filing a regular issue. -## Reporting a non security bug +## Reporting a non-security bug -For non-security bugs, please simply file a GitHub [issue](https://github.com/quic-go/quic-go/issues/new). +For bugs, feature requests, or other non-security concerns, please open a GitHub [issue](https://github.com/quic-go/quic-go/issues/new). diff --git a/vendor/github.com/quic-go/quic-go/client.go b/vendor/github.com/quic-go/quic-go/client.go index 26cd8358..63132f2d 100644 --- a/vendor/github.com/quic-go/quic-go/client.go +++ b/vendor/github.com/quic-go/quic-go/client.go @@ -16,7 +16,7 @@ var generateConnectionIDForInitial = protocol.GenerateConnectionIDForInitial // It resolves the address, and then creates a new UDP connection to dial the QUIC server. // When the QUIC connection is closed, this UDP connection is closed. // See [Dial] for more details. -func DialAddr(ctx context.Context, addr string, tlsConf *tls.Config, conf *Config) (Connection, error) { +func DialAddr(ctx context.Context, addr string, tlsConf *tls.Config, conf *Config) (*Conn, error) { udpConn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0}) if err != nil { return nil, err @@ -29,12 +29,17 @@ func DialAddr(ctx context.Context, addr string, tlsConf *tls.Config, conf *Confi if err != nil { return nil, err } - return tr.dial(ctx, udpAddr, addr, tlsConf, conf, false) + conn, err := tr.dial(ctx, udpAddr, addr, tlsConf, conf, false) + if err != nil { + tr.Close() + return nil, err + } + return conn, nil } // DialAddrEarly establishes a new 0-RTT QUIC connection to a server. // See [DialAddr] for more details. -func DialAddrEarly(ctx context.Context, addr string, tlsConf *tls.Config, conf *Config) (EarlyConnection, error) { +func DialAddrEarly(ctx context.Context, addr string, tlsConf *tls.Config, conf *Config) (*Conn, error) { udpConn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0}) if err != nil { return nil, err @@ -57,7 +62,7 @@ func DialAddrEarly(ctx context.Context, addr string, tlsConf *tls.Config, conf * // DialEarly establishes a new 0-RTT QUIC connection to a server using a net.PacketConn. // See [Dial] for more details. -func DialEarly(ctx context.Context, c net.PacketConn, addr net.Addr, tlsConf *tls.Config, conf *Config) (EarlyConnection, error) { +func DialEarly(ctx context.Context, c net.PacketConn, addr net.Addr, tlsConf *tls.Config, conf *Config) (*Conn, error) { dl, err := setupTransport(c, tlsConf, false) if err != nil { return nil, err @@ -74,12 +79,12 @@ func DialEarly(ctx context.Context, c net.PacketConn, addr net.Addr, tlsConf *tl // If the PacketConn satisfies the [OOBCapablePacketConn] interface (as a [net.UDPConn] does), // ECN and packet info support will be enabled. In this case, ReadMsgUDP and WriteMsgUDP // will be used instead of ReadFrom and WriteTo to read/write packets. -// The tls.Config must define an application protocol (using NextProtos). +// The [tls.Config] must define an application protocol (using tls.Config.NextProtos). // // This is a convenience function. More advanced use cases should instantiate a [Transport], // which offers configuration options for a more fine-grained control of the connection establishment, // including reusing the underlying UDP socket for multiple QUIC connections. -func Dial(ctx context.Context, c net.PacketConn, addr net.Addr, tlsConf *tls.Config, conf *Config) (Connection, error) { +func Dial(ctx context.Context, c net.PacketConn, addr net.Addr, tlsConf *tls.Config, conf *Config) (*Conn, error) { dl, err := setupTransport(c, tlsConf, false) if err != nil { return nil, err diff --git a/vendor/github.com/quic-go/quic-go/codecov.yml b/vendor/github.com/quic-go/quic-go/codecov.yml index 77e47fbe..58c94e9b 100644 --- a/vendor/github.com/quic-go/quic-go/codecov.yml +++ b/vendor/github.com/quic-go/quic-go/codecov.yml @@ -2,12 +2,13 @@ coverage: round: nearest ignore: - http3/gzip_reader.go + - example/ - interop/ - internal/handshake/cipher_suite.go + - internal/mocks/ - internal/utils/linkedlist/linkedlist.go - internal/testdata - - logging/connection_tracer_multiplexer.go - - logging/tracer_multiplexer.go + - internal/synctest - testutils/ - fuzzing/ - metrics/ diff --git a/vendor/github.com/quic-go/quic-go/config.go b/vendor/github.com/quic-go/quic-go/config.go index 540a3240..74c2054e 100644 --- a/vendor/github.com/quic-go/quic-go/config.go +++ b/vendor/github.com/quic-go/quic-go/config.go @@ -106,23 +106,24 @@ func populateConfig(config *Config) *Config { } return &Config{ - GetConfigForClient: config.GetConfigForClient, - Versions: versions, - HandshakeIdleTimeout: handshakeIdleTimeout, - MaxIdleTimeout: idleTimeout, - KeepAlivePeriod: config.KeepAlivePeriod, - InitialStreamReceiveWindow: initialStreamReceiveWindow, - MaxStreamReceiveWindow: maxStreamReceiveWindow, - InitialConnectionReceiveWindow: initialConnectionReceiveWindow, - MaxConnectionReceiveWindow: maxConnectionReceiveWindow, - AllowConnectionWindowIncrease: config.AllowConnectionWindowIncrease, - MaxIncomingStreams: maxIncomingStreams, - MaxIncomingUniStreams: maxIncomingUniStreams, - TokenStore: config.TokenStore, - EnableDatagrams: config.EnableDatagrams, - InitialPacketSize: initialPacketSize, - DisablePathMTUDiscovery: config.DisablePathMTUDiscovery, - Allow0RTT: config.Allow0RTT, - Tracer: config.Tracer, + GetConfigForClient: config.GetConfigForClient, + Versions: versions, + HandshakeIdleTimeout: handshakeIdleTimeout, + MaxIdleTimeout: idleTimeout, + KeepAlivePeriod: config.KeepAlivePeriod, + InitialStreamReceiveWindow: initialStreamReceiveWindow, + MaxStreamReceiveWindow: maxStreamReceiveWindow, + InitialConnectionReceiveWindow: initialConnectionReceiveWindow, + MaxConnectionReceiveWindow: maxConnectionReceiveWindow, + AllowConnectionWindowIncrease: config.AllowConnectionWindowIncrease, + MaxIncomingStreams: maxIncomingStreams, + MaxIncomingUniStreams: maxIncomingUniStreams, + TokenStore: config.TokenStore, + EnableDatagrams: config.EnableDatagrams, + InitialPacketSize: initialPacketSize, + DisablePathMTUDiscovery: config.DisablePathMTUDiscovery, + EnableStreamResetPartialDelivery: config.EnableStreamResetPartialDelivery, + Allow0RTT: config.Allow0RTT, + Tracer: config.Tracer, } } diff --git a/vendor/github.com/quic-go/quic-go/conn_id_generator.go b/vendor/github.com/quic-go/quic-go/conn_id_generator.go index e05fbd7f..133932a6 100644 --- a/vendor/github.com/quic-go/quic-go/conn_id_generator.go +++ b/vendor/github.com/quic-go/quic-go/conn_id_generator.go @@ -2,7 +2,10 @@ package quic import ( "fmt" + "slices" + "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/wire" @@ -11,11 +14,11 @@ import ( type connRunnerCallbacks struct { AddConnectionID func(protocol.ConnectionID) RemoveConnectionID func(protocol.ConnectionID) - RetireConnectionID func(protocol.ConnectionID) - ReplaceWithClosed func([]protocol.ConnectionID, []byte) + ReplaceWithClosed func([]protocol.ConnectionID, []byte, time.Duration) } -type connRunners map[transportID]connRunnerCallbacks +// The memory address of the Transport is used as the key. +type connRunners map[connRunner]connRunnerCallbacks func (cr connRunners) AddConnectionID(id protocol.ConnectionID) { for _, c := range cr { @@ -29,16 +32,15 @@ func (cr connRunners) RemoveConnectionID(id protocol.ConnectionID) { } } -func (cr connRunners) RetireConnectionID(id protocol.ConnectionID) { +func (cr connRunners) ReplaceWithClosed(ids []protocol.ConnectionID, b []byte, expiry time.Duration) { for _, c := range cr { - c.RetireConnectionID(id) + c.ReplaceWithClosed(ids, b, expiry) } } -func (cr connRunners) ReplaceWithClosed(ids []protocol.ConnectionID, b []byte) { - for _, c := range cr { - c.ReplaceWithClosed(ids, b) - } +type connIDToRetire struct { + t monotime.Time + connID protocol.ConnectionID } type connIDGenerator struct { @@ -47,6 +49,7 @@ type connIDGenerator struct { connRunners connRunners activeSrcConnIDs map[uint64]protocol.ConnectionID + connIDsToRetire []connIDToRetire // sorted by t initialClientDestConnID *protocol.ConnectionID // nil for the client statelessResetter *statelessResetter @@ -55,11 +58,11 @@ type connIDGenerator struct { } func newConnIDGenerator( - tID transportID, + runner connRunner, initialConnectionID protocol.ConnectionID, initialClientDestConnID *protocol.ConnectionID, // nil for the client statelessResetter *statelessResetter, - connRunner connRunnerCallbacks, + callbacks connRunnerCallbacks, queueControlFrame func(wire.Frame), generator ConnectionIDGenerator, ) *connIDGenerator { @@ -67,7 +70,7 @@ func newConnIDGenerator( generator: generator, activeSrcConnIDs: make(map[uint64]protocol.ConnectionID), statelessResetter: statelessResetter, - connRunners: map[transportID]connRunnerCallbacks{tID: connRunner}, + connRunners: map[connRunner]connRunnerCallbacks{runner: callbacks}, queueControlFrame: queueControlFrame, } m.activeSrcConnIDs[0] = initialConnectionID @@ -93,7 +96,7 @@ func (m *connIDGenerator) SetMaxActiveConnIDs(limit uint64) error { return nil } -func (m *connIDGenerator) Retire(seq uint64, sentWithDestConnID protocol.ConnectionID) error { +func (m *connIDGenerator) Retire(seq uint64, sentWithDestConnID protocol.ConnectionID, expiry monotime.Time) error { if seq > m.highestSeq { return &qerr.TransportError{ ErrorCode: qerr.ProtocolViolation, @@ -111,7 +114,8 @@ func (m *connIDGenerator) Retire(seq uint64, sentWithDestConnID protocol.Connect ErrorMessage: fmt.Sprintf("retired connection ID %d (%s), which was used as the Destination Connection ID on this packet", seq, connID), } } - m.connRunners.RetireConnectionID(connID) + m.queueConnIDForRetiring(connID, expiry) + delete(m.activeSrcConnIDs, seq) // Don't issue a replacement for the initial connection ID. if seq == 0 { @@ -120,6 +124,16 @@ func (m *connIDGenerator) Retire(seq uint64, sentWithDestConnID protocol.Connect return m.issueNewConnID() } +func (m *connIDGenerator) queueConnIDForRetiring(connID protocol.ConnectionID, expiry monotime.Time) { + idx := slices.IndexFunc(m.connIDsToRetire, func(c connIDToRetire) bool { + return c.t.After(expiry) + }) + if idx == -1 { + idx = len(m.connIDsToRetire) + } + m.connIDsToRetire = slices.Insert(m.connIDsToRetire, idx, connIDToRetire{t: expiry, connID: connID}) +} + func (m *connIDGenerator) issueNewConnID() error { connID, err := m.generator.GenerateConnectionID() if err != nil { @@ -136,13 +150,26 @@ func (m *connIDGenerator) issueNewConnID() error { return nil } -func (m *connIDGenerator) SetHandshakeComplete() { +func (m *connIDGenerator) SetHandshakeComplete(connIDExpiry monotime.Time) { if m.initialClientDestConnID != nil { - m.connRunners.RetireConnectionID(*m.initialClientDestConnID) + m.queueConnIDForRetiring(*m.initialClientDestConnID, connIDExpiry) m.initialClientDestConnID = nil } } +func (m *connIDGenerator) RemoveRetiredConnIDs(now monotime.Time) { + if len(m.connIDsToRetire) == 0 { + return + } + for _, c := range m.connIDsToRetire { + if c.t.After(now) { + break + } + m.connRunners.RemoveConnectionID(c.connID) + m.connIDsToRetire = m.connIDsToRetire[1:] + } +} + func (m *connIDGenerator) RemoveAll() { if m.initialClientDestConnID != nil { m.connRunners.RemoveConnectionID(*m.initialClientDestConnID) @@ -150,26 +177,32 @@ func (m *connIDGenerator) RemoveAll() { for _, connID := range m.activeSrcConnIDs { m.connRunners.RemoveConnectionID(connID) } + for _, c := range m.connIDsToRetire { + m.connRunners.RemoveConnectionID(c.connID) + } } -func (m *connIDGenerator) ReplaceWithClosed(connClose []byte) { - connIDs := make([]protocol.ConnectionID, 0, len(m.activeSrcConnIDs)+1) +func (m *connIDGenerator) ReplaceWithClosed(connClose []byte, expiry time.Duration) { + connIDs := make([]protocol.ConnectionID, 0, len(m.activeSrcConnIDs)+len(m.connIDsToRetire)+1) if m.initialClientDestConnID != nil { connIDs = append(connIDs, *m.initialClientDestConnID) } for _, connID := range m.activeSrcConnIDs { connIDs = append(connIDs, connID) } - m.connRunners.ReplaceWithClosed(connIDs, connClose) + for _, c := range m.connIDsToRetire { + connIDs = append(connIDs, c.connID) + } + m.connRunners.ReplaceWithClosed(connIDs, connClose, expiry) } -func (m *connIDGenerator) AddConnRunner(id transportID, r connRunnerCallbacks) { +func (m *connIDGenerator) AddConnRunner(runner connRunner, r connRunnerCallbacks) { // The transport might have already been added earlier. // This happens if the application migrates back to and old path. - if _, ok := m.connRunners[id]; ok { + if _, ok := m.connRunners[runner]; ok { return } - m.connRunners[id] = r + m.connRunners[runner] = r if m.initialClientDestConnID != nil { r.AddConnectionID(*m.initialClientDestConnID) } diff --git a/vendor/github.com/quic-go/quic-go/connection.go b/vendor/github.com/quic-go/quic-go/connection.go index 413266a5..9c756b32 100644 --- a/vendor/github.com/quic-go/quic-go/connection.go +++ b/vendor/github.com/quic-go/quic-go/connection.go @@ -10,6 +10,7 @@ import ( "net" "os" "reflect" + "slices" "strconv" "sync" "sync/atomic" @@ -18,34 +19,19 @@ import ( "github.com/quic-go/quic-go/internal/ackhandler" "github.com/quic-go/quic-go/internal/flowcontrol" "github.com/quic-go/quic-go/internal/handshake" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/utils/ringbuffer" "github.com/quic-go/quic-go/internal/wire" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" + "github.com/quic-go/quic-go/qlogwriter" ) type unpacker interface { UnpackLongHeader(hdr *wire.Header, data []byte) (*unpackedPacket, error) - UnpackShortHeader(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) -} - -type streamManager interface { - GetOrOpenSendStream(protocol.StreamID) (sendStreamI, error) - GetOrOpenReceiveStream(protocol.StreamID) (receiveStreamI, error) - OpenStream() (Stream, error) - OpenUniStream() (SendStream, error) - OpenStreamSync(context.Context) (Stream, error) - OpenUniStreamSync(context.Context) (SendStream, error) - AcceptStream(context.Context) (Stream, error) - AcceptUniStream(context.Context) (ReceiveStream, error) - DeleteStream(protocol.StreamID) error - UpdateLimits(*wire.TransportParameters) - HandleMaxStreamsFrame(*wire.MaxStreamsFrame) - CloseWithError(error) - ResetFor0RTT() - UseResetMaps() + UnpackShortHeader(rcvTime monotime.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) } type cryptoStreamHandler interface { @@ -65,7 +51,7 @@ type receivedPacket struct { buffer *packetBuffer remoteAddr net.Addr - rcvTime time.Time + rcvTime monotime.Time data []byte ecn protocol.ECN @@ -73,6 +59,11 @@ type receivedPacket struct { info packetInfo // only valid if the contained IP address is valid } +type receivedPacketWithDatagramID struct { + receivedPacket + datagramID qlog.DatagramID +} + func (p *receivedPacket) Size() protocol.ByteCount { return protocol.ByteCount(len(p.data)) } func (p *receivedPacket) Clone() *receivedPacket { @@ -88,9 +79,8 @@ func (p *receivedPacket) Clone() *receivedPacket { type connRunner interface { Add(protocol.ConnectionID, packetHandler) bool - Retire(protocol.ConnectionID) Remove(protocol.ConnectionID) - ReplaceWithClosed([]protocol.ConnectionID, []byte) + ReplaceWithClosed([]protocol.ConnectionID, []byte, time.Duration) AddResetToken(protocol.StatelessResetToken, packetHandler) RemoveResetToken(protocol.StatelessResetToken) } @@ -109,13 +99,32 @@ func (e *errCloseForRecreating) Error() string { return "closing connection in order to recreate it" } -var connTracingID atomic.Uint64 // to be accessed atomically -func nextConnTracingID() ConnectionTracingID { return ConnectionTracingID(connTracingID.Add(1)) } +var deadlineSendImmediately = monotime.Time(42 * time.Millisecond) // any value > time.Time{} and before time.Now() is fine -// A Connection is a QUIC connection -type connection struct { - tr *Transport +type blockMode uint8 +const ( + // blockModeNone means that the connection is not blocked. + blockModeNone blockMode = iota + // blockModeCongestionLimited means that the connection is congestion limited. + // In that case, we can still send acknowledgments and PTO probe packets. + blockModeCongestionLimited + // blockModeHardBlocked means that no packet can be sent, under no circumstances. This can happen when: + // * the send queue is full + // * the SentPacketHandler returns SendNone, e.g. when we are tracking the maximum number of packets + // In that case, the timer will be set to the idle timeout. + blockModeHardBlocked +) + +// A Conn is a QUIC connection between two peers. +// Calls to the connection (and to streams) can return the following types of errors: +// - [ApplicationError]: for errors triggered by the application running on top of QUIC +// - [TransportError]: for errors triggered by the QUIC transport (in many cases a misbehaving peer) +// - [IdleTimeoutError]: when the peer goes away unexpectedly (this is a [net.Error] timeout error) +// - [HandshakeTimeoutError]: when the cryptographic handshake takes too long (this is a [net.Error] timeout error) +// - [StatelessResetError]: when we receive a stateless reset +// - [VersionNegotiationError]: returned by the client, when there's no version overlap between the peers +type Conn struct { // Destination connection ID used during the handshake. // Used to check source connection ID on incoming packets. handshakeDestConnID protocol.ConnectionID @@ -137,11 +146,12 @@ type connection struct { largestRcvdAppData protocol.PacketNumber pathManagerOutgoing atomic.Pointer[pathManagerOutgoing] - streamsMap streamManager + streamsMap *streamsMap connIDManager *connIDManager connIDGenerator *connIDGenerator - rttStats *utils.RTTStats + rttStats *utils.RTTStats + connStats utils.ConnectionStats cryptoStreamManager *cryptoStreamManager sentPacketHandler ackhandler.SentPacketHandler @@ -159,7 +169,7 @@ type connection struct { currentMTUEstimate atomic.Uint32 - initialStream *cryptoStream + initialStream *initialCryptoStream handshakeStream *cryptoStream oneRTTStream *cryptoStream // only set for the server cryptoStreamHandler cryptoStreamHandler @@ -177,8 +187,8 @@ type connection struct { ctxCancel context.CancelCauseFunc handshakeCompleteChan chan struct{} - undecryptablePackets []receivedPacket // undecryptable packets, waiting for a change in encryption level - undecryptablePacketsToProcess []receivedPacket + undecryptablePackets []receivedPacketWithDatagramID // undecryptable packets, waiting for a change in encryption level + undecryptablePacketsToProcess []receivedPacketWithDatagramID earlyConnReadyChan chan struct{} sentFirstPacket bool @@ -190,19 +200,21 @@ type connection struct { versionNegotiated bool receivedFirstPacket bool + blocked blockMode + // the minimum of the max_idle_timeout values advertised by both endpoints idleTimeout time.Duration - creationTime time.Time + creationTime monotime.Time // The idle timeout is set based on the max of the time we received the last packet... - lastPacketReceivedTime time.Time + lastPacketReceivedTime monotime.Time // ... and the time we sent a new ack-eliciting packet after receiving a packet. - firstAckElicitingPacketAfterIdleSentTime time.Time + firstAckElicitingPacketAfterIdleSentTime monotime.Time // pacingDeadline is the time when the next packet should be sent - pacingDeadline time.Time + pacingDeadline monotime.Time peerParams *wire.TransportParameters - timer connectionTimer + timer *time.Timer // keepAlivePingSent stores whether a keep alive PING is in flight. // It is reset as soon as we receive a packet from the peer. keepAlivePingSent bool @@ -213,22 +225,34 @@ type connection struct { connStateMutex sync.Mutex connState ConnectionState - logID string - tracer *logging.ConnectionTracer - logger utils.Logger + logID string + qlogTrace qlogwriter.Trace + qlogger qlogwriter.Recorder + logger utils.Logger } -var ( - _ Connection = &connection{} - _ EarlyConnection = &connection{} - _ streamSender = &connection{} -) +var _ streamSender = &Conn{} + +type connTestHooks struct { + run func() error + earlyConnReady func() <-chan struct{} + context func() context.Context + handshakeComplete func() <-chan struct{} + closeWithTransportError func(TransportErrorCode) + destroy func(error) + handlePacket func(receivedPacket) +} + +type wrappedConn struct { + testHooks *connTestHooks + *Conn +} var newConnection = func( ctx context.Context, ctxCancel context.CancelCauseFunc, conn sendConn, - tr *Transport, + runner connRunner, origDestConnID protocol.ConnectionID, retrySrcConnID *protocol.ConnectionID, clientDestConnID protocol.ConnectionID, @@ -240,14 +264,14 @@ var newConnection = func( tlsConf *tls.Config, tokenGenerator *handshake.TokenGenerator, clientAddressValidated bool, - tracer *logging.ConnectionTracer, + rtt time.Duration, + qlogTrace qlogwriter.Trace, logger utils.Logger, v protocol.Version, -) quicConn { - s := &connection{ +) *wrappedConn { + s := &Conn{ ctx: ctx, ctxCancel: ctxCancel, - tr: tr, conn: conn, config: conf, handshakeDestConnID: destConnID, @@ -255,16 +279,18 @@ var newConnection = func( tokenGenerator: tokenGenerator, oneRTTStream: newCryptoStream(), perspective: protocol.PerspectiveServer, - tracer: tracer, + qlogTrace: qlogTrace, logger: logger, version: v, } + if qlogTrace != nil { + s.qlogger = qlogTrace.AddProducer() + } if origDestConnID.Len() > 0 { s.logID = origDestConnID.String() } else { s.logID = destConnID.String() } - runner := tr.connRunner() s.connIDManager = newConnIDManager( destConnID, func(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) }, @@ -272,28 +298,30 @@ var newConnection = func( s.queueControlFrame, ) s.connIDGenerator = newConnIDGenerator( - tr.id(), + runner, srcConnID, &clientDestConnID, statelessResetter, connRunnerCallbacks{ AddConnectionID: func(connID protocol.ConnectionID) { runner.Add(connID, s) }, RemoveConnectionID: runner.Remove, - RetireConnectionID: runner.Retire, ReplaceWithClosed: runner.ReplaceWithClosed, }, s.queueControlFrame, connIDGenerator, ) s.preSetup() - s.sentPacketHandler, s.receivedPacketHandler = ackhandler.NewAckHandler( + s.rttStats.SetInitialRTT(rtt) + s.sentPacketHandler = ackhandler.NewSentPacketHandler( 0, protocol.ByteCount(s.config.InitialPacketSize), s.rttStats, + &s.connStats, clientAddressValidated, s.conn.capabilities().ECN, + s.receivedPacketHandler.IgnorePacketsBelow, s.perspective, - s.tracer, + s.qlogger, s.logger, ) s.currentMTUEstimate.Store(uint32(estimateMaxPayloadSize(protocol.ByteCount(s.config.InitialPacketSize)))) @@ -329,14 +357,15 @@ var newConnection = func( ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs, InitialSourceConnectionID: srcConnID, RetrySourceConnectionID: retrySrcConnID, + EnableResetStreamAt: conf.EnableStreamResetPartialDelivery, } if s.config.EnableDatagrams { params.MaxDatagramFrameSize = wire.MaxDatagramSize } else { params.MaxDatagramFrameSize = protocol.InvalidByteCount } - if s.tracer != nil && s.tracer.SentTransportParameters != nil { - s.tracer.SentTransportParameters(params) + if s.qlogger != nil { + s.qlogTransportParameters(params, protocol.PerspectiveServer, false) } cs := handshake.NewCryptoSetupServer( clientDestConnID, @@ -346,22 +375,22 @@ var newConnection = func( tlsConf, conf.Allow0RTT, s.rttStats, - tracer, + s.qlogger, logger, s.version, ) s.cryptoStreamHandler = cs - s.packer = newPacketPacker(srcConnID, s.connIDManager.Get, s.initialStream, s.handshakeStream, s.sentPacketHandler, s.retransmissionQueue, cs, s.framer, s.receivedPacketHandler, s.datagramQueue, s.perspective) + s.packer = newPacketPacker(srcConnID, s.connIDManager.Get, s.initialStream, s.handshakeStream, s.sentPacketHandler, s.retransmissionQueue, cs, s.framer, &s.receivedPacketHandler, s.datagramQueue, s.perspective) s.unpacker = newPacketUnpacker(cs, s.srcConnIDLen) s.cryptoStreamManager = newCryptoStreamManager(s.initialStream, s.handshakeStream, s.oneRTTStream) - return s + return &wrappedConn{Conn: s} } // declare this as a variable, such that we can it mock it in the tests var newClientConnection = func( ctx context.Context, conn sendConn, - tr *Transport, + runner connRunner, destConnID protocol.ConnectionID, srcConnID protocol.ConnectionID, connIDGenerator ConnectionIDGenerator, @@ -371,12 +400,11 @@ var newClientConnection = func( initialPacketNumber protocol.PacketNumber, enable0RTT bool, hasNegotiatedVersion bool, - tracer *logging.ConnectionTracer, + qlogTrace qlogwriter.Trace, logger utils.Logger, v protocol.Version, -) quicConn { - s := &connection{ - tr: tr, +) *wrappedConn { + s := &Conn{ conn: conn, config: conf, origDestConnID: destConnID, @@ -385,11 +413,23 @@ var newClientConnection = func( perspective: protocol.PerspectiveClient, logID: destConnID.String(), logger: logger, - tracer: tracer, + qlogTrace: qlogTrace, versionNegotiated: hasNegotiatedVersion, version: v, } - runner := tr.connRunner() + if qlogTrace != nil { + s.qlogger = qlogTrace.AddProducer() + } + if s.qlogger != nil { + var srcAddr, destAddr *net.UDPAddr + if addr, ok := conn.LocalAddr().(*net.UDPAddr); ok { + srcAddr = addr + } + if addr, ok := conn.RemoteAddr().(*net.UDPAddr); ok { + destAddr = addr + } + s.qlogger.RecordEvent(startedConnectionEvent(srcAddr, destAddr)) + } s.connIDManager = newConnIDManager( destConnID, func(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) }, @@ -397,14 +437,13 @@ var newClientConnection = func( s.queueControlFrame, ) s.connIDGenerator = newConnIDGenerator( - tr.id(), + runner, srcConnID, nil, statelessResetter, connRunnerCallbacks{ AddConnectionID: func(connID protocol.ConnectionID) { runner.Add(connID, s) }, RemoveConnectionID: runner.Remove, - RetireConnectionID: runner.Retire, ReplaceWithClosed: runner.ReplaceWithClosed, }, s.queueControlFrame, @@ -412,14 +451,16 @@ var newClientConnection = func( ) s.ctx, s.ctxCancel = context.WithCancelCause(ctx) s.preSetup() - s.sentPacketHandler, s.receivedPacketHandler = ackhandler.NewAckHandler( + s.sentPacketHandler = ackhandler.NewSentPacketHandler( initialPacketNumber, protocol.ByteCount(s.config.InitialPacketSize), s.rttStats, + &s.connStats, false, // has no effect s.conn.capabilities().ECN, + s.receivedPacketHandler.IgnorePacketsBelow, s.perspective, - s.tracer, + s.qlogger, s.logger, ) s.currentMTUEstimate.Store(uint32(estimateMaxPayloadSize(protocol.ByteCount(s.config.InitialPacketSize)))) @@ -442,14 +483,15 @@ var newClientConnection = func( // See https://github.com/quic-go/quic-go/pull/3806. ActiveConnectionIDLimit: protocol.MaxActiveConnectionIDs, InitialSourceConnectionID: srcConnID, + EnableResetStreamAt: conf.EnableStreamResetPartialDelivery, } if s.config.EnableDatagrams { params.MaxDatagramFrameSize = wire.MaxDatagramSize } else { params.MaxDatagramFrameSize = protocol.InvalidByteCount } - if s.tracer != nil && s.tracer.SentTransportParameters != nil { - s.tracer.SentTransportParameters(params) + if s.qlogger != nil { + s.qlogTransportParameters(params, protocol.PerspectiveClient, false) } cs := handshake.NewCryptoSetupClient( destConnID, @@ -457,14 +499,14 @@ var newClientConnection = func( tlsConf, enable0RTT, s.rttStats, - tracer, + s.qlogger, logger, s.version, ) s.cryptoStreamHandler = cs s.cryptoStreamManager = newCryptoStreamManager(s.initialStream, s.handshakeStream, oneRTTStream) s.unpacker = newPacketUnpacker(cs, s.srcConnIDLen) - s.packer = newPacketPacker(srcConnID, s.connIDManager.Get, s.initialStream, s.handshakeStream, s.sentPacketHandler, s.retransmissionQueue, cs, s.framer, s.receivedPacketHandler, s.datagramQueue, s.perspective) + s.packer = newPacketPacker(srcConnID, s.connIDManager.Get, s.initialStream, s.handshakeStream, s.sentPacketHandler, s.retransmissionQueue, cs, s.framer, &s.receivedPacketHandler, s.datagramQueue, s.perspective) if len(tlsConf.ServerName) > 0 { s.tokenStoreKey = tlsConf.ServerName } else { @@ -473,120 +515,127 @@ var newClientConnection = func( if s.config.TokenStore != nil { if token := s.config.TokenStore.Pop(s.tokenStoreKey); token != nil { s.packer.SetToken(token.data) + s.rttStats.SetInitialRTT(token.rtt) } } - return s + return &wrappedConn{Conn: s} } -func (s *connection) preSetup() { - s.largestRcvdAppData = protocol.InvalidPacketNumber - s.initialStream = newCryptoStream() - s.handshakeStream = newCryptoStream() - s.sendQueue = newSendQueue(s.conn) - s.retransmissionQueue = newRetransmissionQueue() - s.frameParser = *wire.NewFrameParser(s.config.EnableDatagrams) - s.rttStats = &utils.RTTStats{} - s.connFlowController = flowcontrol.NewConnectionFlowController( - protocol.ByteCount(s.config.InitialConnectionReceiveWindow), - protocol.ByteCount(s.config.MaxConnectionReceiveWindow), +func (c *Conn) preSetup() { + c.largestRcvdAppData = protocol.InvalidPacketNumber + c.initialStream = newInitialCryptoStream(c.perspective == protocol.PerspectiveClient) + c.handshakeStream = newCryptoStream() + c.sendQueue = newSendQueue(c.conn) + c.retransmissionQueue = newRetransmissionQueue() + c.frameParser = *wire.NewFrameParser( + c.config.EnableDatagrams, + c.config.EnableStreamResetPartialDelivery, + false, // ACK_FREQUENCY is not supported yet + ) + c.rttStats = utils.NewRTTStats() + c.connFlowController = flowcontrol.NewConnectionFlowController( + protocol.ByteCount(c.config.InitialConnectionReceiveWindow), + protocol.ByteCount(c.config.MaxConnectionReceiveWindow), func(size protocol.ByteCount) bool { - if s.config.AllowConnectionWindowIncrease == nil { + if c.config.AllowConnectionWindowIncrease == nil { return true } - return s.config.AllowConnectionWindowIncrease(s, uint64(size)) + return c.config.AllowConnectionWindowIncrease(c, uint64(size)) }, - s.rttStats, - s.logger, + c.rttStats, + c.logger, ) - s.earlyConnReadyChan = make(chan struct{}) - s.streamsMap = newStreamsMap( - s.ctx, - s, - s.queueControlFrame, - s.newFlowController, - uint64(s.config.MaxIncomingStreams), - uint64(s.config.MaxIncomingUniStreams), - s.perspective, + c.earlyConnReadyChan = make(chan struct{}) + c.streamsMap = newStreamsMap( + c.ctx, + c, + c.queueControlFrame, + c.newFlowController, + uint64(c.config.MaxIncomingStreams), + uint64(c.config.MaxIncomingUniStreams), + c.perspective, ) - s.framer = newFramer(s.connFlowController) - s.receivedPackets.Init(8) - s.notifyReceivedPacket = make(chan struct{}, 1) - s.closeChan = make(chan struct{}, 1) - s.sendingScheduled = make(chan struct{}, 1) - s.handshakeCompleteChan = make(chan struct{}) + c.framer = newFramer(c.connFlowController) + c.receivedPackets.Init(8) + c.notifyReceivedPacket = make(chan struct{}, 1) + c.closeChan = make(chan struct{}, 1) + c.sendingScheduled = make(chan struct{}, 1) + c.handshakeCompleteChan = make(chan struct{}) - now := time.Now() - s.lastPacketReceivedTime = now - s.creationTime = now + now := monotime.Now() + c.lastPacketReceivedTime = now + c.creationTime = now - s.datagramQueue = newDatagramQueue(s.scheduleSending, s.logger) - s.connState.Version = s.version + c.receivedPacketHandler = *ackhandler.NewReceivedPacketHandler(c.logger) + + c.datagramQueue = newDatagramQueue(c.scheduleSending, c.logger) + c.connState.Version = c.version } // run the connection main loop -func (s *connection) run() (err error) { - defer func() { s.ctxCancel(err) }() +func (c *Conn) run() (err error) { + defer func() { c.ctxCancel(err) }() defer func() { // drain queued packets that will never be processed - s.receivedPacketMx.Lock() - defer s.receivedPacketMx.Unlock() + c.receivedPacketMx.Lock() + defer c.receivedPacketMx.Unlock() - for !s.receivedPackets.Empty() { - p := s.receivedPackets.PopFront() + for !c.receivedPackets.Empty() { + p := c.receivedPackets.PopFront() p.buffer.Decrement() p.buffer.MaybeRelease() } }() - s.timer = *newTimer() + c.timer = time.NewTimer(monotime.Until(c.idleTimeoutStartTime().Add(c.config.HandshakeIdleTimeout))) - if err := s.cryptoStreamHandler.StartHandshake(s.ctx); err != nil { + if err := c.cryptoStreamHandler.StartHandshake(c.ctx); err != nil { return err } - if err := s.handleHandshakeEvents(time.Now()); err != nil { + if err := c.handleHandshakeEvents(monotime.Now()); err != nil { return err } go func() { - if err := s.sendQueue.Run(); err != nil { - s.destroyImpl(err) + if err := c.sendQueue.Run(); err != nil { + c.destroyImpl(err) } }() - if s.perspective == protocol.PerspectiveClient { - s.scheduleSending() // so the ClientHello actually gets sent + if c.perspective == protocol.PerspectiveClient { + c.scheduleSending() // so the ClientHello actually gets sent } var sendQueueAvailable <-chan struct{} runLoop: for { - if s.framer.QueuedTooManyControlFrames() { - s.setCloseError(&closeError{err: &qerr.TransportError{ErrorCode: InternalError}}) + if c.framer.QueuedTooManyControlFrames() { + c.setCloseError(&closeError{err: &qerr.TransportError{ErrorCode: InternalError}}) break runLoop } // Close immediately if requested select { - case <-s.closeChan: + case <-c.closeChan: break runLoop default: } // no need to set a timer if we can send packets immediately - if s.pacingDeadline != deadlineSendImmediately { - s.maybeResetTimer() + if c.pacingDeadline != deadlineSendImmediately { + c.maybeResetTimer() } // 1st: handle undecryptable packets, if any. // This can only occur before completion of the handshake. - if len(s.undecryptablePacketsToProcess) > 0 { + if len(c.undecryptablePacketsToProcess) > 0 { var processedUndecryptablePacket bool - queue := s.undecryptablePacketsToProcess - s.undecryptablePacketsToProcess = nil + queue := c.undecryptablePacketsToProcess + c.undecryptablePacketsToProcess = nil for _, p := range queue { - processed, err := s.handleOnePacket(p) + processed, err := c.handleOnePacket(p.receivedPacket, p.datagramID) if err != nil { - s.setCloseError(&closeError{err: err}) + c.setCloseError(&closeError{err: err}) break runLoop } if processed { @@ -600,16 +649,16 @@ runLoop: } // 2nd: receive packets. - processed, err := s.handlePackets() // don't check receivedPackets.Len() in the run loop to avoid locking the mutex + processed, err := c.handlePackets() // don't check receivedPackets.Len() in the run loop to avoid locking the mutex if err != nil { - s.setCloseError(&closeError{err: err}) + c.setCloseError(&closeError{err: err}) break runLoop } // We don't need to wait for new events if: // * we processed packets: we probably need to send an ACK, and potentially more data // * the pacer allows us to send more packets immediately - shouldProceedImmediately := sendQueueAvailable == nil && (processed || s.pacingDeadline.Equal(deadlineSendImmediately)) + shouldProceedImmediately := sendQueueAvailable == nil && (processed || c.pacingDeadline.Equal(deadlineSendImmediately)) if !shouldProceedImmediately { // 3rd: wait for something to happen: // * closing of the connection @@ -618,16 +667,15 @@ runLoop: // * send queue available // * received packets select { - case <-s.closeChan: + case <-c.closeChan: break runLoop - case <-s.timer.Chan(): - s.timer.SetRead() - case <-s.sendingScheduled: + case <-c.timer.C: + case <-c.sendingScheduled: case <-sendQueueAvailable: - case <-s.notifyReceivedPacket: - wasProcessed, err := s.handlePackets() + case <-c.notifyReceivedPacket: + wasProcessed, err := c.handlePackets() if err != nil { - s.setCloseError(&closeError{err: err}) + c.setCloseError(&closeError{err: err}) break runLoop } // if we processed any undecryptable packets, jump to the resetting of the timers directly @@ -639,281 +687,385 @@ runLoop: // Check for loss detection timeout. // This could cause packets to be declared lost, and retransmissions to be enqueued. - now := time.Now() - if timeout := s.sentPacketHandler.GetLossDetectionTimeout(); !timeout.IsZero() && timeout.Before(now) { - if err := s.sentPacketHandler.OnLossDetectionTimeout(now); err != nil { - s.setCloseError(&closeError{err: err}) + now := monotime.Now() + if timeout := c.sentPacketHandler.GetLossDetectionTimeout(); !timeout.IsZero() && !timeout.After(now) { + if err := c.sentPacketHandler.OnLossDetectionTimeout(now); err != nil { + c.setCloseError(&closeError{err: err}) break runLoop } } - if keepAliveTime := s.nextKeepAliveTime(); !keepAliveTime.IsZero() && !now.Before(keepAliveTime) { + if keepAliveTime := c.nextKeepAliveTime(); !keepAliveTime.IsZero() && !now.Before(keepAliveTime) { // send a PING frame since there is no activity in the connection - s.logger.Debugf("Sending a keep-alive PING to keep the connection alive.") - s.framer.QueueControlFrame(&wire.PingFrame{}) - s.keepAlivePingSent = true - } else if !s.handshakeComplete && now.Sub(s.creationTime) >= s.config.handshakeTimeout() { - s.destroyImpl(qerr.ErrHandshakeTimeout) + c.logger.Debugf("Sending a keep-alive PING to keep the connection alive.") + c.framer.QueueControlFrame(&wire.PingFrame{}) + c.keepAlivePingSent = true + } else if !c.handshakeComplete && now.Sub(c.creationTime) >= c.config.handshakeTimeout() { + c.destroyImpl(qerr.ErrHandshakeTimeout) break runLoop } else { - idleTimeoutStartTime := s.idleTimeoutStartTime() - if (!s.handshakeComplete && now.Sub(idleTimeoutStartTime) >= s.config.HandshakeIdleTimeout) || - (s.handshakeComplete && now.After(s.nextIdleTimeoutTime())) { - s.destroyImpl(qerr.ErrIdleTimeout) + idleTimeoutStartTime := c.idleTimeoutStartTime() + if (!c.handshakeComplete && now.Sub(idleTimeoutStartTime) >= c.config.HandshakeIdleTimeout) || + (c.handshakeComplete && !now.Before(c.nextIdleTimeoutTime())) { + c.destroyImpl(qerr.ErrIdleTimeout) break runLoop } } - if s.perspective == protocol.PerspectiveClient { - pm := s.pathManagerOutgoing.Load() + c.connIDGenerator.RemoveRetiredConnIDs(now) + + if c.perspective == protocol.PerspectiveClient { + pm := c.pathManagerOutgoing.Load() if pm != nil { tr, ok := pm.ShouldSwitchPath() if ok { - s.switchToNewPath(tr, now) + c.switchToNewPath(tr, now) } } } - if s.sendQueue.WouldBlock() { + if c.sendQueue.WouldBlock() { // The send queue is still busy sending out packets. Wait until there's space to enqueue new packets. - sendQueueAvailable = s.sendQueue.Available() + sendQueueAvailable = c.sendQueue.Available() // Cancel the pacing timer, as we can't send any more packets until the send queue is available again. - s.pacingDeadline = time.Time{} + c.pacingDeadline = 0 + c.blocked = blockModeHardBlocked continue } - if s.closeErr.Load() != nil { + if c.closeErr.Load() != nil { break runLoop } - if err := s.triggerSending(now); err != nil { - s.setCloseError(&closeError{err: err}) + c.blocked = blockModeNone // sending might set it back to true if we're congestion limited + if err := c.triggerSending(now); err != nil { + c.setCloseError(&closeError{err: err}) break runLoop } - if s.sendQueue.WouldBlock() { + if c.sendQueue.WouldBlock() { // The send queue is still busy sending out packets. Wait until there's space to enqueue new packets. - sendQueueAvailable = s.sendQueue.Available() + sendQueueAvailable = c.sendQueue.Available() // Cancel the pacing timer, as we can't send any more packets until the send queue is available again. - s.pacingDeadline = time.Time{} + c.pacingDeadline = 0 + c.blocked = blockModeHardBlocked } else { sendQueueAvailable = nil } } - closeErr := s.closeErr.Load() - s.cryptoStreamHandler.Close() - s.sendQueue.Close() // close the send queue before sending the CONNECTION_CLOSE - s.handleCloseError(closeErr) - if s.tracer != nil && s.tracer.Close != nil { + closeErr := c.closeErr.Load() + c.cryptoStreamHandler.Close() + c.sendQueue.Close() // close the send queue before sending the CONNECTION_CLOSE + c.handleCloseError(closeErr) + if c.qlogger != nil { if e := (&errCloseForRecreating{}); !errors.As(closeErr.err, &e) { - s.tracer.Close() + c.qlogger.Close() } } - s.logger.Infof("Connection %s closed.", s.logID) - s.timer.Stop() + c.logger.Infof("Connection %s closed.", c.logID) + c.timer.Stop() return closeErr.err } // blocks until the early connection can be used -func (s *connection) earlyConnReady() <-chan struct{} { - return s.earlyConnReadyChan +func (c *Conn) earlyConnReady() <-chan struct{} { + return c.earlyConnReadyChan } -func (s *connection) HandshakeComplete() <-chan struct{} { - return s.handshakeCompleteChan +// Context returns a context that is cancelled when the connection is closed. +// The cancellation cause is set to the error that caused the connection to close. +func (c *Conn) Context() context.Context { + return c.ctx } -func (s *connection) Context() context.Context { - return s.ctx +func (c *Conn) supportsDatagrams() bool { + return c.peerParams.MaxDatagramFrameSize > 0 } -func (s *connection) supportsDatagrams() bool { - return s.peerParams.MaxDatagramFrameSize > 0 +// ConnectionState returns basic details about the QUIC connection. +func (c *Conn) ConnectionState() ConnectionState { + c.connStateMutex.Lock() + defer c.connStateMutex.Unlock() + + cs := c.cryptoStreamHandler.ConnectionState() + c.connState.TLS = cs.ConnectionState + c.connState.Used0RTT = cs.Used0RTT + if c.peerParams != nil { + c.connState.SupportsDatagrams.Remote = c.supportsDatagrams() + c.connState.SupportsStreamResetPartialDelivery.Remote = c.peerParams.EnableResetStreamAt + } + c.connState.SupportsDatagrams.Local = c.config.EnableDatagrams + c.connState.SupportsStreamResetPartialDelivery.Local = c.config.EnableStreamResetPartialDelivery + c.connState.GSO = c.conn.capabilities().GSO + return c.connState } -func (s *connection) ConnectionState() ConnectionState { - s.connStateMutex.Lock() - defer s.connStateMutex.Unlock() - cs := s.cryptoStreamHandler.ConnectionState() - s.connState.TLS = cs.ConnectionState - s.connState.Used0RTT = cs.Used0RTT - s.connState.GSO = s.conn.capabilities().GSO - return s.connState +// ConnectionStats contains statistics about the QUIC connection +type ConnectionStats struct { + // MinRTT is the estimate of the minimum RTT observed on the active network + // path. + MinRTT time.Duration + // LatestRTT is the last RTT sample observed on the active network path. + LatestRTT time.Duration + // SmoothedRTT is an exponentially weighted moving average of an endpoint's + // RTT samples. See https://www.rfc-editor.org/rfc/rfc9002#section-5.3 + SmoothedRTT time.Duration + // MeanDeviation estimates the variation in the RTT samples using a mean + // variation. See https://www.rfc-editor.org/rfc/rfc9002#section-5.3 + MeanDeviation time.Duration + + // BytesSent is the number of bytes sent on the underlying connection, + // including retransmissions. Does not include UDP or any other outer + // framing. + BytesSent uint64 + // PacketsSent is the number of packets sent on the underlying connection, + // including those that are determined to have been lost. + PacketsSent uint64 + // BytesReceived is the number of total bytes received on the underlying + // connection, including duplicate data for streams. Does not include UDP or + // any other outer framing. + BytesReceived uint64 + // PacketsReceived is the number of total packets received on the underlying + // connection, including packets that were not processable. + PacketsReceived uint64 + // BytesLost is the number of bytes lost on the underlying connection (does + // not monotonically increase, because packets that are declared lost can + // subsequently be received). Does not include UDP or any other outer + // framing. + BytesLost uint64 + // PacketsLost is the number of packets lost on the underlying connection + // (does not monotonically increase, because packets that are declared lost + // can subsequently be received). + PacketsLost uint64 +} + +func (c *Conn) ConnectionStats() ConnectionStats { + return ConnectionStats{ + MinRTT: c.rttStats.MinRTT(), + LatestRTT: c.rttStats.LatestRTT(), + SmoothedRTT: c.rttStats.SmoothedRTT(), + MeanDeviation: c.rttStats.MeanDeviation(), + + BytesSent: c.connStats.BytesSent.Load(), + PacketsSent: c.connStats.PacketsSent.Load(), + BytesReceived: c.connStats.BytesReceived.Load(), + PacketsReceived: c.connStats.PacketsReceived.Load(), + BytesLost: c.connStats.BytesLost.Load(), + PacketsLost: c.connStats.PacketsLost.Load(), + } } // Time when the connection should time out -func (s *connection) nextIdleTimeoutTime() time.Time { - idleTimeout := max(s.idleTimeout, s.rttStats.PTO(true)*3) - return s.idleTimeoutStartTime().Add(idleTimeout) +func (c *Conn) nextIdleTimeoutTime() monotime.Time { + idleTimeout := max(c.idleTimeout, c.rttStats.PTO(true)*3) + return c.idleTimeoutStartTime().Add(idleTimeout) } // Time when the next keep-alive packet should be sent. // It returns a zero time if no keep-alive should be sent. -func (s *connection) nextKeepAliveTime() time.Time { - if s.config.KeepAlivePeriod == 0 || s.keepAlivePingSent { - return time.Time{} +func (c *Conn) nextKeepAliveTime() monotime.Time { + if c.config.KeepAlivePeriod == 0 || c.keepAlivePingSent { + return 0 } - keepAliveInterval := max(s.keepAliveInterval, s.rttStats.PTO(true)*3/2) - return s.lastPacketReceivedTime.Add(keepAliveInterval) + keepAliveInterval := max(c.keepAliveInterval, c.rttStats.PTO(true)*3/2) + return c.lastPacketReceivedTime.Add(keepAliveInterval) } -func (s *connection) maybeResetTimer() { - var deadline time.Time - if !s.handshakeComplete { - deadline = s.creationTime.Add(s.config.handshakeTimeout()) - if t := s.idleTimeoutStartTime().Add(s.config.HandshakeIdleTimeout); t.Before(deadline) { +func (c *Conn) maybeResetTimer() { + var deadline monotime.Time + if !c.handshakeComplete { + deadline = c.creationTime.Add(c.config.handshakeTimeout()) + if t := c.idleTimeoutStartTime().Add(c.config.HandshakeIdleTimeout); t.Before(deadline) { deadline = t } } else { - if keepAliveTime := s.nextKeepAliveTime(); !keepAliveTime.IsZero() { - deadline = keepAliveTime + // A keep-alive packet is ack-eliciting, so it can only be sent if the connection is + // neither congestion limited nor hard-blocked. + if c.blocked != blockModeNone { + deadline = c.nextIdleTimeoutTime() } else { - deadline = s.nextIdleTimeoutTime() + if keepAliveTime := c.nextKeepAliveTime(); !keepAliveTime.IsZero() { + deadline = keepAliveTime + } else { + deadline = c.nextIdleTimeoutTime() + } } } + // If the connection is hard-blocked, we can't even send acknowledgments, + // nor can we send PTO probe packets. + if c.blocked == blockModeHardBlocked { + c.timer.Reset(monotime.Until(deadline)) + return + } - s.timer.SetTimer( - deadline, - s.receivedPacketHandler.GetAlarmTimeout(), - s.sentPacketHandler.GetLossDetectionTimeout(), - s.pacingDeadline, - ) + if t := c.receivedPacketHandler.GetAlarmTimeout(); !t.IsZero() && t.Before(deadline) { + deadline = t + } + if t := c.sentPacketHandler.GetLossDetectionTimeout(); !t.IsZero() && t.Before(deadline) { + deadline = t + } + if c.blocked == blockModeCongestionLimited { + c.timer.Reset(monotime.Until(deadline)) + return + } + + if !c.pacingDeadline.IsZero() && c.pacingDeadline.Before(deadline) { + deadline = c.pacingDeadline + } + c.timer.Reset(monotime.Until(deadline)) } -func (s *connection) idleTimeoutStartTime() time.Time { - startTime := s.lastPacketReceivedTime - if t := s.firstAckElicitingPacketAfterIdleSentTime; t.After(startTime) { +func (c *Conn) idleTimeoutStartTime() monotime.Time { + startTime := c.lastPacketReceivedTime + if t := c.firstAckElicitingPacketAfterIdleSentTime; !t.IsZero() && t.After(startTime) { startTime = t } return startTime } -func (s *connection) switchToNewPath(tr *Transport, now time.Time) { - initialPacketSize := protocol.ByteCount(s.config.InitialPacketSize) - s.sentPacketHandler.MigratedPath(now, initialPacketSize) +func (c *Conn) switchToNewPath(tr *Transport, now monotime.Time) { + initialPacketSize := protocol.ByteCount(c.config.InitialPacketSize) + c.sentPacketHandler.MigratedPath(now, initialPacketSize) maxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize) - if s.peerParams.MaxUDPPayloadSize > 0 && s.peerParams.MaxUDPPayloadSize < maxPacketSize { - maxPacketSize = s.peerParams.MaxUDPPayloadSize + if c.peerParams.MaxUDPPayloadSize > 0 && c.peerParams.MaxUDPPayloadSize < maxPacketSize { + maxPacketSize = c.peerParams.MaxUDPPayloadSize } - s.mtuDiscoverer.Reset(now, initialPacketSize, maxPacketSize) - s.conn = newSendConn(tr.conn, s.conn.RemoteAddr(), packetInfo{}, utils.DefaultLogger) // TODO: find a better way - s.sendQueue.Close() - s.sendQueue = newSendQueue(s.conn) + c.mtuDiscoverer.Reset(now, initialPacketSize, maxPacketSize) + c.conn = newSendConn(tr.conn, c.conn.RemoteAddr(), packetInfo{}, utils.DefaultLogger) // TODO: find a better way + c.sendQueue.Close() + c.sendQueue = newSendQueue(c.conn) go func() { - if err := s.sendQueue.Run(); err != nil { - s.destroyImpl(err) + if err := c.sendQueue.Run(); err != nil { + c.destroyImpl(err) } }() } -func (s *connection) handleHandshakeComplete(now time.Time) error { - defer close(s.handshakeCompleteChan) +func (c *Conn) handleHandshakeComplete(now monotime.Time) error { + defer close(c.handshakeCompleteChan) // Once the handshake completes, we have derived 1-RTT keys. // There's no point in queueing undecryptable packets for later decryption anymore. - s.undecryptablePackets = nil + c.undecryptablePackets = nil - s.connIDManager.SetHandshakeComplete() - s.connIDGenerator.SetHandshakeComplete() + c.connIDManager.SetHandshakeComplete() + c.connIDGenerator.SetHandshakeComplete(now.Add(3 * c.rttStats.PTO(false))) - if s.tracer != nil && s.tracer.ChoseALPN != nil { - s.tracer.ChoseALPN(s.cryptoStreamHandler.ConnectionState().NegotiatedProtocol) + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.ALPNInformation{ + ChosenALPN: c.cryptoStreamHandler.ConnectionState().NegotiatedProtocol, + }) } // The server applies transport parameters right away, but the client side has to wait for handshake completion. // During a 0-RTT connection, the client is only allowed to use the new transport parameters for 1-RTT packets. - if s.perspective == protocol.PerspectiveClient { - s.applyTransportParameters() + if c.perspective == protocol.PerspectiveClient { + c.applyTransportParameters() return nil } // All these only apply to the server side. - if err := s.handleHandshakeConfirmed(now); err != nil { + if err := c.handleHandshakeConfirmed(now); err != nil { return err } - ticket, err := s.cryptoStreamHandler.GetSessionTicket() + ticket, err := c.cryptoStreamHandler.GetSessionTicket() if err != nil { return err } if ticket != nil { // may be nil if session tickets are disabled via tls.Config.SessionTicketsDisabled - s.oneRTTStream.Write(ticket) - for s.oneRTTStream.HasData() { - s.queueControlFrame(s.oneRTTStream.PopCryptoFrame(protocol.MaxPostHandshakeCryptoFrameSize)) + c.oneRTTStream.Write(ticket) + for c.oneRTTStream.HasData() { + if cf := c.oneRTTStream.PopCryptoFrame(protocol.MaxPostHandshakeCryptoFrameSize); cf != nil { + c.queueControlFrame(cf) + } } } - token, err := s.tokenGenerator.NewToken(s.conn.RemoteAddr()) + token, err := c.tokenGenerator.NewToken(c.conn.RemoteAddr(), c.rttStats.SmoothedRTT()) if err != nil { return err } - s.queueControlFrame(&wire.NewTokenFrame{Token: token}) - s.queueControlFrame(&wire.HandshakeDoneFrame{}) + c.queueControlFrame(&wire.NewTokenFrame{Token: token}) + c.queueControlFrame(&wire.HandshakeDoneFrame{}) return nil } -func (s *connection) handleHandshakeConfirmed(now time.Time) error { - if err := s.dropEncryptionLevel(protocol.EncryptionHandshake, now); err != nil { +func (c *Conn) handleHandshakeConfirmed(now monotime.Time) error { + // Drop initial keys. + // On the client side, this should have happened when sending the first Handshake packet, + // but this is not guaranteed if the server misbehaves. + // See CVE-2025-59530 for more details. + if err := c.dropEncryptionLevel(protocol.EncryptionInitial, now); err != nil { + return err + } + if err := c.dropEncryptionLevel(protocol.EncryptionHandshake, now); err != nil { return err } - s.handshakeConfirmed = true - s.cryptoStreamHandler.SetHandshakeConfirmed() + c.handshakeConfirmed = true + c.cryptoStreamHandler.SetHandshakeConfirmed() - if !s.config.DisablePathMTUDiscovery && s.conn.capabilities().DF { - s.mtuDiscoverer.Start(now) + if !c.config.DisablePathMTUDiscovery && c.conn.capabilities().DF { + c.mtuDiscoverer.Start(now) } return nil } -func (s *connection) handlePackets() (wasProcessed bool, _ error) { - // Now process all packets in the receivedPackets channel. - // Limit the number of packets to the length of the receivedPackets channel, +const maxPacketsToProcess = 32 + +func (c *Conn) handlePackets() (wasProcessed bool, _ error) { + // Process packets from the receivedPackets queue. + // Limit the number of packets to process to maxPacketsToProcess, // so we eventually get a chance to send out an ACK when receiving a lot of packets. - s.receivedPacketMx.Lock() - numPackets := s.receivedPackets.Len() - if numPackets == 0 { - s.receivedPacketMx.Unlock() + c.receivedPacketMx.Lock() + + if c.receivedPackets.Empty() { + c.receivedPacketMx.Unlock() return false, nil } var hasMorePackets bool - for i := 0; i < numPackets; i++ { - if i > 0 { - s.receivedPacketMx.Lock() - } - p := s.receivedPackets.PopFront() - hasMorePackets = !s.receivedPackets.Empty() - s.receivedPacketMx.Unlock() + for range maxPacketsToProcess { + p := c.receivedPackets.PopFront() + c.receivedPacketMx.Unlock() - processed, err := s.handleOnePacket(p) + var datagramID qlog.DatagramID + if c.qlogger != nil && wire.IsLongHeaderPacket(p.data[0]) { + datagramID = qlog.CalculateDatagramID(p.data) + } + processed, err := c.handleOnePacket(p, datagramID) if err != nil { return false, err } if processed { wasProcessed = true } + c.receivedPacketMx.Lock() + hasMorePackets = !c.receivedPackets.Empty() if !hasMorePackets { break } - // only process a single packet at a time before handshake completion - if !s.handshakeComplete { + // Prioritize sending of new CRYPTO data. + // This is especially relevant when processing 0-RTT packets. + if !c.handshakeComplete && (c.initialStream.HasData() || c.handshakeStream.HasData()) { break } } + c.receivedPacketMx.Unlock() + if hasMorePackets { select { - case s.notifyReceivedPacket <- struct{}{}: + case c.notifyReceivedPacket <- struct{}{}: default: } } return wasProcessed, nil } -func (s *connection) handleOnePacket(rp receivedPacket) (wasProcessed bool, _ error) { - s.sentPacketHandler.ReceivedBytes(rp.Size(), rp.rcvTime) +func (c *Conn) handleOnePacket(rp receivedPacket, datagramID qlog.DatagramID) (wasProcessed bool, _ error) { + c.sentPacketHandler.ReceivedBytes(rp.Size(), rp.rcvTime) if wire.IsVersionNegotiationPacket(rp.data) { - s.handleVersionNegotiationPacket(rp) - return false, nil + return false, c.handleVersionNegotiationPacket(rp) } var counter uint8 @@ -925,19 +1077,28 @@ func (s *connection) handleOnePacket(rp receivedPacket) (wasProcessed bool, _ er p = *(p.Clone()) p.data = data - destConnID, err := wire.ParseConnectionID(p.data, s.srcConnIDLen) + destConnID, err := wire.ParseConnectionID(p.data, c.srcConnIDLen) if err != nil { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropHeaderParseError) + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: len(data)}, + DatagramID: datagramID, + Trigger: qlog.PacketDropHeaderParseError, + }) } - s.logger.Debugf("error parsing packet, couldn't parse connection ID: %s", err) + c.logger.Debugf("error parsing packet, couldn't parse connection ID: %s", err) break } if destConnID != lastConnID { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnknownConnectionID) + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{DestConnectionID: destConnID}, + Raw: qlog.RawInfo{Length: len(data)}, + DatagramID: datagramID, + Trigger: qlog.PacketDropUnknownConnectionID, + }) } - s.logger.Debugf("coalesced packet has different destination connection ID: %s, expected %s", destConnID, lastConnID) + c.logger.Debugf("coalesced packet has different destination connection ID: %s, expected %s", destConnID, lastConnID) break } } @@ -945,23 +1106,36 @@ func (s *connection) handleOnePacket(rp receivedPacket) (wasProcessed bool, _ er if wire.IsLongHeaderPacket(p.data[0]) { hdr, packetData, rest, err := wire.ParsePacket(p.data) if err != nil { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - dropReason := logging.PacketDropHeaderParseError + if c.qlogger != nil { if err == wire.ErrUnsupportedVersion { - dropReason = logging.PacketDropUnsupportedVersion + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{Version: hdr.Version}, + Raw: qlog.RawInfo{Length: len(data)}, + DatagramID: datagramID, + Trigger: qlog.PacketDropUnsupportedVersion, + }) + } else { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: len(data)}, + DatagramID: datagramID, + Trigger: qlog.PacketDropHeaderParseError, + }) } - s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), dropReason) } - s.logger.Debugf("error parsing packet: %s", err) + c.logger.Debugf("error parsing packet: %s", err) break } lastConnID = hdr.DestConnectionID - if hdr.Version != s.version { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedVersion) + if hdr.Version != c.version { + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: len(data)}, + DatagramID: datagramID, + Trigger: qlog.PacketDropUnexpectedVersion, + }) } - s.logger.Debugf("Dropping packet with version %x. Expected %x.", hdr.Version, s.version) + c.logger.Debugf("Dropping packet with version %x. Expected %x.", hdr.Version, c.version) break } @@ -971,13 +1145,13 @@ func (s *connection) handleOnePacket(rp receivedPacket) (wasProcessed bool, _ er counter++ // only log if this actually a coalesced packet - if s.logger.Debug() && (counter > 1 || len(rest) > 0) { - s.logger.Debugf("Parsed a coalesced packet. Part %d: %d bytes. Remaining: %d bytes.", counter, len(packetData), len(rest)) + if c.logger.Debug() && (counter > 1 || len(rest) > 0) { + c.logger.Debugf("Parsed a coalesced packet. Part %d: %d bytes. Remaining: %d bytes.", counter, len(packetData), len(rest)) } p.data = packetData - processed, err := s.handleLongHeaderPacket(p, hdr) + processed, err := c.handleLongHeaderPacket(p, hdr, datagramID) if err != nil { return false, err } @@ -989,7 +1163,7 @@ func (s *connection) handleOnePacket(rp receivedPacket) (wasProcessed bool, _ er if counter > 0 { p.buffer.Split() } - processed, err := s.handleShortHeaderPacket(p, counter > 0) + processed, err := c.handleShortHeaderPacket(p, counter > 0, datagramID) if err != nil { return false, err } @@ -1001,10 +1175,15 @@ func (s *connection) handleOnePacket(rp receivedPacket) (wasProcessed bool, _ er } p.buffer.MaybeRelease() + c.blocked = blockModeNone return wasProcessed, nil } -func (s *connection) handleShortHeaderPacket(p receivedPacket, isCoalesced bool) (wasProcessed bool, _ error) { +func (c *Conn) handleShortHeaderPacket( + p receivedPacket, + isCoalesced bool, + datagramID qlog.DatagramID, // only for logging +) (wasProcessed bool, _ error) { var wasQueued bool defer func() { @@ -1014,12 +1193,20 @@ func (s *connection) handleShortHeaderPacket(p receivedPacket, isCoalesced bool) } }() - destConnID, err := wire.ParseConnectionID(p.data, s.srcConnIDLen) + destConnID, err := wire.ParseConnectionID(p.data, c.srcConnIDLen) if err != nil { - s.tracer.DroppedPacket(logging.PacketType1RTT, protocol.InvalidPacketNumber, protocol.ByteCount(len(p.data)), logging.PacketDropHeaderParseError) + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketType1RTT, + PacketNumber: protocol.InvalidPacketNumber, + }, + Raw: qlog.RawInfo{Length: len(p.data)}, + DatagramID: datagramID, + Trigger: qlog.PacketDropHeaderParseError, + }) return false, nil } - pn, pnLen, keyPhase, data, err := s.unpacker.UnpackShortHeader(p.rcvTime, p.data) + pn, pnLen, keyPhase, data, err := c.unpacker.UnpackShortHeader(p.rcvTime, p.data) if err != nil { // Stateless reset packets (see RFC 9000, section 10.3): // * fill the entire UDP datagram (i.e. they cannot be part of a coalesced packet) @@ -1028,97 +1215,109 @@ func (s *connection) handleShortHeaderPacket(p receivedPacket, isCoalesced bool) // * are at least 21 bytes long if !isCoalesced && len(p.data) >= protocol.MinReceivedStatelessResetSize && p.data[0]&0b11000000 == 0b01000000 { token := protocol.StatelessResetToken(p.data[len(p.data)-16:]) - if s.connIDManager.IsActiveStatelessResetToken(token) { + if c.connIDManager.IsActiveStatelessResetToken(token) { return false, &StatelessResetError{} } } - wasQueued, err = s.handleUnpackError(err, p, logging.PacketType1RTT) + wasQueued, err = c.handleUnpackError(err, p, qlog.PacketType1RTT, datagramID) return false, err } - s.largestRcvdAppData = max(s.largestRcvdAppData, pn) + c.largestRcvdAppData = max(c.largestRcvdAppData, pn) - if s.logger.Debug() { - s.logger.Debugf("<- Reading packet %d (%d bytes) for connection %s, 1-RTT", pn, p.Size(), destConnID) - wire.LogShortHeader(s.logger, destConnID, pn, pnLen, keyPhase) + if c.logger.Debug() { + c.logger.Debugf("<- Reading packet %d (%d bytes) for connection %s, 1-RTT", pn, p.Size(), destConnID) + wire.LogShortHeader(c.logger, destConnID, pn, pnLen, keyPhase) } - if s.receivedPacketHandler.IsPotentiallyDuplicate(pn, protocol.Encryption1RTT) { - s.logger.Debugf("Dropping (potentially) duplicate packet.") - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketType1RTT, pn, p.Size(), logging.PacketDropDuplicate) + if c.receivedPacketHandler.IsPotentiallyDuplicate(pn, protocol.Encryption1RTT) { + c.logger.Debugf("Dropping (potentially) duplicate packet.") + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketType1RTT, + PacketNumber: pn, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + DatagramID: datagramID, + Trigger: qlog.PacketDropDuplicate, + }) } return false, nil } - var log func([]logging.Frame) - if s.tracer != nil && s.tracer.ReceivedShortHeaderPacket != nil { - log = func(frames []logging.Frame) { - s.tracer.ReceivedShortHeaderPacket( - &logging.ShortHeader{ + var log func([]qlog.Frame) + if c.qlogger != nil { + log = func(frames []qlog.Frame) { + c.qlogger.RecordEvent(qlog.PacketReceived{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketType1RTT, DestConnectionID: destConnID, PacketNumber: pn, - PacketNumberLen: pnLen, - KeyPhase: keyPhase, + KeyPhaseBit: keyPhase, }, - p.Size(), - p.ecn, - frames, - ) + Raw: qlog.RawInfo{ + Length: int(p.Size()), + PayloadLength: int(p.Size() - wire.ShortHeaderLen(destConnID, pnLen)), + }, + DatagramID: datagramID, + Frames: frames, + ECN: toQlogECN(p.ecn), + }) } } - isNonProbing, pathChallenge, err := s.handleUnpackedShortHeaderPacket(destConnID, pn, data, p.ecn, p.rcvTime, log) + isNonProbing, pathChallenge, err := c.handleUnpackedShortHeaderPacket(destConnID, pn, data, p.ecn, p.rcvTime, log) if err != nil { return false, err } // In RFC 9000, only the client can migrate between paths. - if s.perspective == protocol.PerspectiveClient { + if c.perspective == protocol.PerspectiveClient { return true, nil } - if addrsEqual(p.remoteAddr, s.RemoteAddr()) { + if addrsEqual(p.remoteAddr, c.RemoteAddr()) { return true, nil } var shouldSwitchPath bool - if s.pathManager == nil { - s.pathManager = newPathManager( - s.connIDManager.GetConnIDForPath, - s.connIDManager.RetireConnIDForPath, - s.logger, + if c.pathManager == nil { + c.pathManager = newPathManager( + c.connIDManager.GetConnIDForPath, + c.connIDManager.RetireConnIDForPath, + c.logger, ) } - destConnID, frames, shouldSwitchPath := s.pathManager.HandlePacket(p.remoteAddr, p.rcvTime, pathChallenge, isNonProbing) + destConnID, frames, shouldSwitchPath := c.pathManager.HandlePacket(p.remoteAddr, p.rcvTime, pathChallenge, isNonProbing) if len(frames) > 0 { - probe, buf, err := s.packer.PackPathProbePacket(destConnID, frames, s.version) + probe, buf, err := c.packer.PackPathProbePacket(destConnID, frames, c.version) if err != nil { return true, err } - s.logger.Debugf("sending path probe packet to %s", p.remoteAddr) - s.logShortHeaderPacket(probe.DestConnID, probe.Ack, probe.Frames, probe.StreamFrames, probe.PacketNumber, probe.PacketNumberLen, probe.KeyPhase, protocol.ECNNon, buf.Len(), false) - s.registerPackedShortHeaderPacket(probe, protocol.ECNNon, p.rcvTime) - s.sendQueue.SendProbe(buf, p.remoteAddr) + c.logger.Debugf("sending path probe packet to %s", p.remoteAddr) + c.logShortHeaderPacketWithDatagramID(probe, protocol.ECNNon, buf.Len(), false, datagramID) + c.registerPackedShortHeaderPacket(probe, protocol.ECNNon, p.rcvTime) + c.sendQueue.SendProbe(buf, p.remoteAddr) } // We only switch paths in response to the highest-numbered non-probing packet, // see section 9.3 of RFC 9000. - if !shouldSwitchPath || pn != s.largestRcvdAppData { + if !shouldSwitchPath || pn != c.largestRcvdAppData { return true, nil } - s.pathManager.SwitchToPath(p.remoteAddr) - s.sentPacketHandler.MigratedPath(p.rcvTime, protocol.ByteCount(s.config.InitialPacketSize)) + c.pathManager.SwitchToPath(p.remoteAddr) + c.sentPacketHandler.MigratedPath(p.rcvTime, protocol.ByteCount(c.config.InitialPacketSize)) maxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize) - if s.peerParams.MaxUDPPayloadSize > 0 && s.peerParams.MaxUDPPayloadSize < maxPacketSize { - maxPacketSize = s.peerParams.MaxUDPPayloadSize + if c.peerParams.MaxUDPPayloadSize > 0 && c.peerParams.MaxUDPPayloadSize < maxPacketSize { + maxPacketSize = c.peerParams.MaxUDPPayloadSize } - s.mtuDiscoverer.Reset( + c.mtuDiscoverer.Reset( p.rcvTime, - protocol.ByteCount(s.config.InitialPacketSize), + protocol.ByteCount(c.config.InitialPacketSize), maxPacketSize, ) - s.conn.ChangeRemoteAddr(p.remoteAddr, p.info) + c.conn.ChangeRemoteAddr(p.remoteAddr, p.info) return true, nil } -func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header) (wasProcessed bool, _ error) { +func (c *Conn) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header, datagramID qlog.DatagramID) (wasProcessed bool, _ error) { var wasQueued bool defer func() { @@ -1129,63 +1328,100 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header) }() if hdr.Type == protocol.PacketTypeRetry { - return s.handleRetryPacket(hdr, p.data, p.rcvTime), nil + return c.handleRetryPacket(hdr, p.data, p.rcvTime), nil } // The server can change the source connection ID with the first Handshake packet. // After this, all packets with a different source connection have to be ignored. - if s.receivedFirstPacket && hdr.Type == protocol.PacketTypeInitial && hdr.SrcConnectionID != s.handshakeDestConnID { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeInitial, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnknownConnectionID) + if c.receivedFirstPacket && hdr.Type == protocol.PacketTypeInitial && hdr.SrcConnectionID != c.handshakeDestConnID { + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeInitial, + PacketNumber: protocol.InvalidPacketNumber, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + DatagramID: datagramID, + Trigger: qlog.PacketDropUnknownConnectionID, + }) } - s.logger.Debugf("Dropping Initial packet (%d bytes) with unexpected source connection ID: %s (expected %s)", p.Size(), hdr.SrcConnectionID, s.handshakeDestConnID) + c.logger.Debugf("Dropping Initial packet (%d bytes) with unexpected source connection ID: %s (expected %s)", p.Size(), hdr.SrcConnectionID, c.handshakeDestConnID) return false, nil } // drop 0-RTT packets, if we are a client - if s.perspective == protocol.PerspectiveClient && hdr.Type == protocol.PacketType0RTT { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketType0RTT, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket) + if c.perspective == protocol.PerspectiveClient && hdr.Type == protocol.PacketType0RTT { + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketType0RTT, + PacketNumber: protocol.InvalidPacketNumber, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + DatagramID: datagramID, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } return false, nil } - packet, err := s.unpacker.UnpackLongHeader(hdr, p.data) + packet, err := c.unpacker.UnpackLongHeader(hdr, p.data) if err != nil { - wasQueued, err = s.handleUnpackError(err, p, logging.PacketTypeFromHeader(hdr)) + wasQueued, err = c.handleUnpackError(err, p, toQlogPacketType(hdr.Type), datagramID) return false, err } - if s.logger.Debug() { - s.logger.Debugf("<- Reading packet %d (%d bytes) for connection %s, %s", packet.hdr.PacketNumber, p.Size(), hdr.DestConnectionID, packet.encryptionLevel) - packet.hdr.Log(s.logger) + if c.logger.Debug() { + c.logger.Debugf("<- Reading packet %d (%d bytes) for connection %s, %s", packet.hdr.PacketNumber, p.Size(), hdr.DestConnectionID, packet.encryptionLevel) + packet.hdr.Log(c.logger) } - if pn := packet.hdr.PacketNumber; s.receivedPacketHandler.IsPotentiallyDuplicate(pn, packet.encryptionLevel) { - s.logger.Debugf("Dropping (potentially) duplicate packet.") - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), pn, p.Size(), logging.PacketDropDuplicate) + if pn := packet.hdr.PacketNumber; c.receivedPacketHandler.IsPotentiallyDuplicate(pn, packet.encryptionLevel) { + c.logger.Debugf("Dropping (potentially) duplicate packet.") + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: toQlogPacketType(packet.hdr.Type), + DestConnectionID: hdr.DestConnectionID, + SrcConnectionID: hdr.SrcConnectionID, + PacketNumber: pn, + Version: packet.hdr.Version, + }, + Raw: qlog.RawInfo{Length: int(p.Size()), PayloadLength: int(packet.hdr.Length)}, + DatagramID: datagramID, + Trigger: qlog.PacketDropDuplicate, + }) } return false, nil } - if err := s.handleUnpackedLongHeaderPacket(packet, p.ecn, p.rcvTime, p.Size()); err != nil { + if err := c.handleUnpackedLongHeaderPacket(packet, p.ecn, p.rcvTime, datagramID, p.Size()); err != nil { return false, err } return true, nil } -func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.PacketType) (wasQueued bool, _ error) { +func (c *Conn) handleUnpackError(err error, p receivedPacket, pt qlog.PacketType, datagramID qlog.DatagramID) (wasQueued bool, _ error) { switch err { case handshake.ErrKeysDropped: - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropKeyUnavailable) + if c.qlogger != nil { + connID, _ := wire.ParseConnectionID(p.data, c.srcConnIDLen) + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: pt, + DestConnectionID: connID, + PacketNumber: protocol.InvalidPacketNumber, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + DatagramID: datagramID, + Trigger: qlog.PacketDropKeyUnavailable, + }) } - s.logger.Debugf("Dropping %s packet (%d bytes) because we already dropped the keys.", pt, p.Size()) + c.logger.Debugf("Dropping %s packet (%d bytes) because we already dropped the keys.", pt, p.Size()) return false, nil case handshake.ErrKeysNotYetAvailable: // Sealer for this encryption level not yet available. // Try again later. - s.tryQueueingUndecryptablePacket(p, pt) + c.tryQueueingUndecryptablePacket(p, pt, datagramID) return true, nil case wire.ErrInvalidReservedBits: return false, &qerr.TransportError{ @@ -1194,19 +1430,39 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P } case handshake.ErrDecryptionFailed: // This might be a packet injected by an attacker. Drop it. - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropPayloadDecryptError) + if c.qlogger != nil { + connID, _ := wire.ParseConnectionID(p.data, c.srcConnIDLen) + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: pt, + DestConnectionID: connID, + PacketNumber: protocol.InvalidPacketNumber, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + DatagramID: datagramID, + Trigger: qlog.PacketDropPayloadDecryptError, + }) } - s.logger.Debugf("Dropping %s packet (%d bytes) that could not be unpacked. Error: %s", pt, p.Size(), err) + c.logger.Debugf("Dropping %s packet (%d bytes) that could not be unpacked. Error: %s", pt, p.Size(), err) return false, nil default: var headerErr *headerParseError if errors.As(err, &headerErr) { // This might be a packet injected by an attacker. Drop it. - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError) + if c.qlogger != nil { + connID, _ := wire.ParseConnectionID(p.data, c.srcConnIDLen) + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: pt, + DestConnectionID: connID, + PacketNumber: protocol.InvalidPacketNumber, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + DatagramID: datagramID, + Trigger: qlog.PacketDropHeaderParseError, + }) } - s.logger.Debugf("Dropping %s packet (%d bytes) for which we couldn't unpack the header. Error: %s", pt, p.Size(), err) + c.logger.Debugf("Dropping %s packet (%d bytes) for which we couldn't unpack the header. Error: %s", pt, p.Size(), err) return false, nil } // This is an error returned by the AEAD (other than ErrDecryptionFailed). @@ -1215,214 +1471,308 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P } } -func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime time.Time) bool /* was this a valid Retry */ { - if s.perspective == protocol.PerspectiveServer { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) +func (c *Conn) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime monotime.Time) bool /* was this a valid Retry */ { + if c.perspective == protocol.PerspectiveServer { + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeRetry, + SrcConnectionID: hdr.SrcConnectionID, + DestConnectionID: hdr.DestConnectionID, + Version: hdr.Version, + }, + Raw: qlog.RawInfo{Length: len(data)}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } - s.logger.Debugf("Ignoring Retry.") + c.logger.Debugf("Ignoring Retry.") return false } - if s.receivedFirstPacket { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) + if c.receivedFirstPacket { + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeRetry, + SrcConnectionID: hdr.SrcConnectionID, + DestConnectionID: hdr.DestConnectionID, + Version: hdr.Version, + }, + Raw: qlog.RawInfo{Length: len(data)}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } - s.logger.Debugf("Ignoring Retry, since we already received a packet.") + c.logger.Debugf("Ignoring Retry, since we already received a packet.") return false } - destConnID := s.connIDManager.Get() + destConnID := c.connIDManager.Get() if hdr.SrcConnectionID == destConnID { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeRetry, + SrcConnectionID: hdr.SrcConnectionID, + DestConnectionID: hdr.DestConnectionID, + Version: hdr.Version, + }, + Raw: qlog.RawInfo{Length: len(data)}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } - s.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.") + c.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.") return false } // If a token is already set, this means that we already received a Retry from the server. // Ignore this Retry packet. - if s.receivedRetry { - s.logger.Debugf("Ignoring Retry, since a Retry was already received.") + if c.receivedRetry { + c.logger.Debugf("Ignoring Retry, since a Retry was already received.") return false } tag := handshake.GetRetryIntegrityTag(data[:len(data)-16], destConnID, hdr.Version) if !bytes.Equal(data[len(data)-16:], tag[:]) { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropPayloadDecryptError) + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeRetry, + SrcConnectionID: hdr.SrcConnectionID, + DestConnectionID: hdr.DestConnectionID, + Version: hdr.Version, + }, + Raw: qlog.RawInfo{Length: len(data)}, + Trigger: qlog.PacketDropPayloadDecryptError, + }) } - s.logger.Debugf("Ignoring spoofed Retry. Integrity Tag doesn't match.") + c.logger.Debugf("Ignoring spoofed Retry. Integrity Tag doesn't match.") return false } newDestConnID := hdr.SrcConnectionID - s.receivedRetry = true - s.sentPacketHandler.ResetForRetry(rcvTime) - s.handshakeDestConnID = newDestConnID - s.retrySrcConnID = &newDestConnID - s.cryptoStreamHandler.ChangeConnectionID(newDestConnID) - s.packer.SetToken(hdr.Token) - s.connIDManager.ChangeInitialConnID(newDestConnID) + c.receivedRetry = true + c.sentPacketHandler.ResetForRetry(rcvTime) + c.handshakeDestConnID = newDestConnID + c.retrySrcConnID = &newDestConnID + c.cryptoStreamHandler.ChangeConnectionID(newDestConnID) + c.packer.SetToken(hdr.Token) + c.connIDManager.ChangeInitialConnID(newDestConnID) - if s.logger.Debug() { - s.logger.Debugf("<- Received Retry:") - (&wire.ExtendedHeader{Header: *hdr}).Log(s.logger) - s.logger.Debugf("Switching destination connection ID to: %s", hdr.SrcConnectionID) + if c.logger.Debug() { + c.logger.Debugf("<- Received Retry:") + (&wire.ExtendedHeader{Header: *hdr}).Log(c.logger) + c.logger.Debugf("Switching destination connection ID to: %s", hdr.SrcConnectionID) } - if s.tracer != nil && s.tracer.ReceivedRetry != nil { - s.tracer.ReceivedRetry(hdr) + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketReceived{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeRetry, + DestConnectionID: destConnID, + SrcConnectionID: newDestConnID, + Version: hdr.Version, + Token: &qlog.Token{Raw: hdr.Token}, + }, + Raw: qlog.RawInfo{Length: len(data)}, + }) } - s.scheduleSending() + c.scheduleSending() return true } -func (s *connection) handleVersionNegotiationPacket(p receivedPacket) { - if s.perspective == protocol.PerspectiveServer || // servers never receive version negotiation packets - s.receivedFirstPacket || s.versionNegotiated { // ignore delayed / duplicated version negotiation packets - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket) +func (c *Conn) handleVersionNegotiationPacket(p receivedPacket) error { + if c.perspective == protocol.PerspectiveServer || // servers never receive version negotiation packets + c.receivedFirstPacket || c.versionNegotiated { // ignore delayed / duplicated version negotiation packets + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{PacketType: qlog.PacketTypeVersionNegotiation}, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } - return + return nil } src, dest, supportedVersions, err := wire.ParseVersionNegotiationPacket(p.data) if err != nil { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError) + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{PacketType: qlog.PacketTypeVersionNegotiation}, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropHeaderParseError, + }) } - s.logger.Debugf("Error parsing Version Negotiation packet: %s", err) - return + c.logger.Debugf("Error parsing Version Negotiation packet: %s", err) + return nil } - for _, v := range supportedVersions { - if v == s.version { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedVersion) - } - // The Version Negotiation packet contains the version that we offered. - // This might be a packet sent by an attacker, or it was corrupted. - return + if slices.Contains(supportedVersions, c.version) { + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{PacketType: qlog.PacketTypeVersionNegotiation}, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedVersion, + }) } + // The Version Negotiation packet contains the version that we offered. + // This might be a packet sent by an attacker, or it was corrupted. + return nil } - s.logger.Infof("Received a Version Negotiation packet. Supported Versions: %s", supportedVersions) - if s.tracer != nil && s.tracer.ReceivedVersionNegotiationPacket != nil { - s.tracer.ReceivedVersionNegotiationPacket(dest, src, supportedVersions) + c.logger.Infof("Received a Version Negotiation packet. Supported Versions: %s", supportedVersions) + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.VersionNegotiationReceived{ + Header: qlog.PacketHeaderVersionNegotiation{ + DestConnectionID: dest, + SrcConnectionID: src, + }, + SupportedVersions: supportedVersions, + }) } - newVersion, ok := protocol.ChooseSupportedVersion(s.config.Versions, supportedVersions) + newVersion, ok := protocol.ChooseSupportedVersion(c.config.Versions, supportedVersions) if !ok { - s.destroyImpl(&VersionNegotiationError{ - Ours: s.config.Versions, + c.destroyImpl(&VersionNegotiationError{ + Ours: c.config.Versions, Theirs: supportedVersions, }) - s.logger.Infof("No compatible QUIC version found.") - return + c.logger.Infof("No compatible QUIC version found.") + return nil } - if s.tracer != nil && s.tracer.NegotiatedVersion != nil { - s.tracer.NegotiatedVersion(newVersion, s.config.Versions, supportedVersions) + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.VersionInformation{ + ChosenVersion: newVersion, + ClientVersions: c.config.Versions, + ServerVersions: supportedVersions, + }) } - s.logger.Infof("Switching to QUIC version %s.", newVersion) - nextPN, _ := s.sentPacketHandler.PeekPacketNumber(protocol.EncryptionInitial) - s.destroyImpl(&errCloseForRecreating{ + c.logger.Infof("Switching to QUIC version %s.", newVersion) + nextPN, _ := c.sentPacketHandler.PeekPacketNumber(protocol.EncryptionInitial) + return &errCloseForRecreating{ nextPacketNumber: nextPN, nextVersion: newVersion, - }) + } } -func (s *connection) handleUnpackedLongHeaderPacket( +func (c *Conn) handleUnpackedLongHeaderPacket( packet *unpackedPacket, ecn protocol.ECN, - rcvTime time.Time, + rcvTime monotime.Time, + datagramID qlog.DatagramID, // only for logging packetSize protocol.ByteCount, // only for logging ) error { - if !s.receivedFirstPacket { - s.receivedFirstPacket = true - if !s.versionNegotiated && s.tracer != nil && s.tracer.NegotiatedVersion != nil { - var clientVersions, serverVersions []protocol.Version - switch s.perspective { + if !c.receivedFirstPacket { + c.receivedFirstPacket = true + if !c.versionNegotiated && c.qlogger != nil { + var clientVersions, serverVersions []Version + switch c.perspective { case protocol.PerspectiveClient: - clientVersions = s.config.Versions + clientVersions = c.config.Versions case protocol.PerspectiveServer: - serverVersions = s.config.Versions + serverVersions = c.config.Versions } - s.tracer.NegotiatedVersion(s.version, clientVersions, serverVersions) + c.qlogger.RecordEvent(qlog.VersionInformation{ + ChosenVersion: c.version, + ClientVersions: clientVersions, + ServerVersions: serverVersions, + }) } // The server can change the source connection ID with the first Handshake packet. - if s.perspective == protocol.PerspectiveClient && packet.hdr.SrcConnectionID != s.handshakeDestConnID { + if c.perspective == protocol.PerspectiveClient && packet.hdr.SrcConnectionID != c.handshakeDestConnID { cid := packet.hdr.SrcConnectionID - s.logger.Debugf("Received first packet. Switching destination connection ID to: %s", cid) - s.handshakeDestConnID = cid - s.connIDManager.ChangeInitialConnID(cid) + c.logger.Debugf("Received first packet. Switching destination connection ID to: %s", cid) + c.handshakeDestConnID = cid + c.connIDManager.ChangeInitialConnID(cid) } // We create the connection as soon as we receive the first packet from the client. // We do that before authenticating the packet. // That means that if the source connection ID was corrupted, // we might have created a connection with an incorrect source connection ID. // Once we authenticate the first packet, we need to update it. - if s.perspective == protocol.PerspectiveServer { - if packet.hdr.SrcConnectionID != s.handshakeDestConnID { - s.handshakeDestConnID = packet.hdr.SrcConnectionID - s.connIDManager.ChangeInitialConnID(packet.hdr.SrcConnectionID) + if c.perspective == protocol.PerspectiveServer { + if packet.hdr.SrcConnectionID != c.handshakeDestConnID { + c.handshakeDestConnID = packet.hdr.SrcConnectionID + c.connIDManager.ChangeInitialConnID(packet.hdr.SrcConnectionID) } - if s.tracer != nil && s.tracer.StartedConnection != nil { - s.tracer.StartedConnection( - s.conn.LocalAddr(), - s.conn.RemoteAddr(), - packet.hdr.SrcConnectionID, - packet.hdr.DestConnectionID, - ) + if c.qlogger != nil { + var srcAddr, destAddr *net.UDPAddr + if addr, ok := c.conn.LocalAddr().(*net.UDPAddr); ok { + srcAddr = addr + } + if addr, ok := c.conn.RemoteAddr().(*net.UDPAddr); ok { + destAddr = addr + } + c.qlogger.RecordEvent(startedConnectionEvent(srcAddr, destAddr)) } } } - if s.perspective == protocol.PerspectiveServer && packet.encryptionLevel == protocol.EncryptionHandshake && - !s.droppedInitialKeys { + if c.perspective == protocol.PerspectiveServer && packet.encryptionLevel == protocol.EncryptionHandshake && + !c.droppedInitialKeys { // On the server side, Initial keys are dropped as soon as the first Handshake packet is received. // See Section 4.9.1 of RFC 9001. - if err := s.dropEncryptionLevel(protocol.EncryptionInitial, rcvTime); err != nil { + if err := c.dropEncryptionLevel(protocol.EncryptionInitial, rcvTime); err != nil { return err } } - s.lastPacketReceivedTime = rcvTime - s.firstAckElicitingPacketAfterIdleSentTime = time.Time{} - s.keepAlivePingSent = false + c.lastPacketReceivedTime = rcvTime + c.firstAckElicitingPacketAfterIdleSentTime = 0 + c.keepAlivePingSent = false if packet.hdr.Type == protocol.PacketType0RTT { - s.largestRcvdAppData = max(s.largestRcvdAppData, packet.hdr.PacketNumber) + c.largestRcvdAppData = max(c.largestRcvdAppData, packet.hdr.PacketNumber) } - var log func([]logging.Frame) - if s.tracer != nil && s.tracer.ReceivedLongHeaderPacket != nil { - log = func(frames []logging.Frame) { - s.tracer.ReceivedLongHeaderPacket(packet.hdr, packetSize, ecn, frames) + var log func([]qlog.Frame) + if c.qlogger != nil { + log = func(frames []qlog.Frame) { + var token *qlog.Token + if len(packet.hdr.Token) > 0 { + token = &qlog.Token{Raw: packet.hdr.Token} + } + c.qlogger.RecordEvent(qlog.PacketReceived{ + Header: qlog.PacketHeader{ + PacketType: toQlogPacketType(packet.hdr.Type), + DestConnectionID: packet.hdr.DestConnectionID, + SrcConnectionID: packet.hdr.SrcConnectionID, + PacketNumber: packet.hdr.PacketNumber, + Version: packet.hdr.Version, + Token: token, + }, + Raw: qlog.RawInfo{ + Length: int(packetSize), + PayloadLength: int(packet.hdr.Length), + }, + DatagramID: datagramID, + Frames: frames, + ECN: toQlogECN(ecn), + }) } } - isAckEliciting, _, _, err := s.handleFrames(packet.data, packet.hdr.DestConnectionID, packet.encryptionLevel, log, rcvTime) + isAckEliciting, _, _, err := c.handleFrames(packet.data, packet.hdr.DestConnectionID, packet.encryptionLevel, log, rcvTime) if err != nil { return err } - return s.receivedPacketHandler.ReceivedPacket(packet.hdr.PacketNumber, ecn, packet.encryptionLevel, rcvTime, isAckEliciting) + c.sentPacketHandler.ReceivedPacket(packet.encryptionLevel, rcvTime) + return c.receivedPacketHandler.ReceivedPacket(packet.hdr.PacketNumber, ecn, packet.encryptionLevel, rcvTime, isAckEliciting) } -func (s *connection) handleUnpackedShortHeaderPacket( +func (c *Conn) handleUnpackedShortHeaderPacket( destConnID protocol.ConnectionID, pn protocol.PacketNumber, data []byte, ecn protocol.ECN, - rcvTime time.Time, - log func([]logging.Frame), + rcvTime monotime.Time, + log func([]qlog.Frame), ) (isNonProbing bool, pathChallenge *wire.PathChallengeFrame, _ error) { - s.lastPacketReceivedTime = rcvTime - s.firstAckElicitingPacketAfterIdleSentTime = time.Time{} - s.keepAlivePingSent = false + c.lastPacketReceivedTime = rcvTime + c.firstAckElicitingPacketAfterIdleSentTime = 0 + c.keepAlivePingSent = false - isAckEliciting, isNonProbing, pathChallenge, err := s.handleFrames(data, destConnID, protocol.Encryption1RTT, log, rcvTime) + isAckEliciting, isNonProbing, pathChallenge, err := c.handleFrames(data, destConnID, protocol.Encryption1RTT, log, rcvTime) if err != nil { return false, nil, err } - if err := s.receivedPacketHandler.ReceivedPacket(pn, ecn, protocol.Encryption1RTT, rcvTime, isAckEliciting); err != nil { + c.sentPacketHandler.ReceivedPacket(protocol.Encryption1RTT, rcvTime) + if err := c.receivedPacketHandler.ReceivedPacket(pn, ecn, protocol.Encryption1RTT, rcvTime, isAckEliciting); err != nil { return false, nil, err } return isNonProbing, pathChallenge, nil @@ -1430,54 +1780,118 @@ func (s *connection) handleUnpackedShortHeaderPacket( // handleFrames parses the frames, one after the other, and handles them. // It returns the last PATH_CHALLENGE frame contained in the packet, if any. -func (s *connection) handleFrames( +func (c *Conn) handleFrames( data []byte, destConnID protocol.ConnectionID, encLevel protocol.EncryptionLevel, - log func([]logging.Frame), - rcvTime time.Time, + log func([]qlog.Frame), + rcvTime monotime.Time, ) (isAckEliciting, isNonProbing bool, pathChallenge *wire.PathChallengeFrame, _ error) { // Only used for tracing. // If we're not tracing, this slice will always remain empty. - var frames []logging.Frame + var frames []qlog.Frame if log != nil { - frames = make([]logging.Frame, 0, 4) + frames = make([]qlog.Frame, 0, 4) } - handshakeWasComplete := s.handshakeComplete + handshakeWasComplete := c.handshakeComplete var handleErr error + var skipHandling bool + for len(data) > 0 { - l, frame, err := s.frameParser.ParseNext(data, encLevel, s.version) + frameType, l, err := c.frameParser.ParseType(data, encLevel) if err != nil { + // The frame parser skips over PADDING frames, and returns an io.EOF if the PADDING + // frames were the last frames in this packet. + if err == io.EOF { + break + } return false, false, nil, err } data = data[l:] - if frame == nil { - break - } - if ackhandler.IsFrameAckEliciting(frame) { + + if ackhandler.IsFrameTypeAckEliciting(frameType) { isAckEliciting = true } - if !wire.IsProbingFrame(frame) { + if !wire.IsProbingFrameType(frameType) { isNonProbing = true } - if log != nil { - frames = append(frames, toLoggingFrame(frame)) - } - // An error occurred handling a previous frame. - // Don't handle the current frame. - if handleErr != nil { - continue - } - pc, err := s.handleFrame(frame, encLevel, destConnID, rcvTime) - if err != nil { - if log == nil { + + // We're inlining common cases, to avoid using interfaces + // Fast path: STREAM, DATAGRAM and ACK + if frameType.IsStreamFrameType() { + streamFrame, l, err := c.frameParser.ParseStreamFrame(frameType, data, c.version) + if err != nil { return false, false, nil, err } - // If we're logging, we need to keep parsing (but not handling) all frames. + data = data[l:] + + if log != nil { + frames = append(frames, toQlogFrame(streamFrame)) + } + // an error occurred handling a previous frame, don't handle the current frame + if skipHandling { + continue + } + wire.LogFrame(c.logger, streamFrame, false) + handleErr = c.streamsMap.HandleStreamFrame(streamFrame, rcvTime) + } else if frameType.IsAckFrameType() { + ackFrame, l, err := c.frameParser.ParseAckFrame(frameType, data, encLevel, c.version) + if err != nil { + return false, false, nil, err + } + data = data[l:] + if log != nil { + frames = append(frames, toQlogFrame(ackFrame)) + } + // an error occurred handling a previous frame, don't handle the current frame + if skipHandling { + continue + } + wire.LogFrame(c.logger, ackFrame, false) + handleErr = c.handleAckFrame(ackFrame, encLevel, rcvTime) + } else if frameType.IsDatagramFrameType() { + datagramFrame, l, err := c.frameParser.ParseDatagramFrame(frameType, data, c.version) + if err != nil { + return false, false, nil, err + } + data = data[l:] + + if log != nil { + frames = append(frames, toQlogFrame(datagramFrame)) + } + // an error occurred handling a previous frame, don't handle the current frame + if skipHandling { + continue + } + wire.LogFrame(c.logger, datagramFrame, false) + handleErr = c.handleDatagramFrame(datagramFrame) + } else { + frame, l, err := c.frameParser.ParseLessCommonFrame(frameType, data, c.version) + if err != nil { + return false, false, nil, err + } + data = data[l:] + + if log != nil { + frames = append(frames, toQlogFrame(frame)) + } + // an error occurred handling a previous frame, don't handle the current frame + if skipHandling { + continue + } + pc, err := c.handleFrame(frame, encLevel, destConnID, rcvTime) + if pc != nil { + pathChallenge = pc + } handleErr = err } - if pc != nil { - pathChallenge = pc + + if handleErr != nil { + // if we're logging, we need to keep parsing (but not handling) all frames + skipHandling = true + if log == nil { + return false, false, nil, handleErr + } } } @@ -1492,61 +1906,55 @@ func (s *connection) handleFrames( // This ensures that we correctly handle the following case on the server side: // We receive a Handshake packet that contains the CRYPTO frame that allows us to complete the handshake, // and an ACK serialized after that CRYPTO frame. In this case, we still want to process the ACK frame. - if !handshakeWasComplete && s.handshakeComplete { - if err := s.handleHandshakeComplete(rcvTime); err != nil { + if !handshakeWasComplete && c.handshakeComplete { + if err := c.handleHandshakeComplete(rcvTime); err != nil { return false, false, nil, err } } return } -func (s *connection) handleFrame( +func (c *Conn) handleFrame( f wire.Frame, encLevel protocol.EncryptionLevel, destConnID protocol.ConnectionID, - rcvTime time.Time, + rcvTime monotime.Time, ) (pathChallenge *wire.PathChallengeFrame, _ error) { var err error - wire.LogFrame(s.logger, f, false) + wire.LogFrame(c.logger, f, false) switch frame := f.(type) { case *wire.CryptoFrame: - err = s.handleCryptoFrame(frame, encLevel, rcvTime) - case *wire.StreamFrame: - err = s.handleStreamFrame(frame, rcvTime) - case *wire.AckFrame: - err = s.handleAckFrame(frame, encLevel, rcvTime) + err = c.handleCryptoFrame(frame, encLevel, rcvTime) case *wire.ConnectionCloseFrame: - err = s.handleConnectionCloseFrame(frame) + err = c.handleConnectionCloseFrame(frame) case *wire.ResetStreamFrame: - err = s.handleResetStreamFrame(frame, rcvTime) + err = c.streamsMap.HandleResetStreamFrame(frame, rcvTime) case *wire.MaxDataFrame: - s.handleMaxDataFrame(frame) + c.connFlowController.UpdateSendWindow(frame.MaximumData) case *wire.MaxStreamDataFrame: - err = s.handleMaxStreamDataFrame(frame) + err = c.streamsMap.HandleMaxStreamDataFrame(frame) case *wire.MaxStreamsFrame: - s.handleMaxStreamsFrame(frame) + c.streamsMap.HandleMaxStreamsFrame(frame) case *wire.DataBlockedFrame: case *wire.StreamDataBlockedFrame: - err = s.handleStreamDataBlockedFrame(frame) + err = c.streamsMap.HandleStreamDataBlockedFrame(frame) case *wire.StreamsBlockedFrame: case *wire.StopSendingFrame: - err = s.handleStopSendingFrame(frame) + err = c.streamsMap.HandleStopSendingFrame(frame) case *wire.PingFrame: case *wire.PathChallengeFrame: - s.handlePathChallengeFrame(frame) + c.handlePathChallengeFrame(frame) pathChallenge = frame case *wire.PathResponseFrame: - err = s.handlePathResponseFrame(frame) + err = c.handlePathResponseFrame(frame) case *wire.NewTokenFrame: - err = s.handleNewTokenFrame(frame) + err = c.handleNewTokenFrame(frame) case *wire.NewConnectionIDFrame: - err = s.handleNewConnectionIDFrame(frame) + err = c.connIDManager.Add(frame) case *wire.RetireConnectionIDFrame: - err = s.handleRetireConnectionIDFrame(frame, destConnID) + err = c.connIDGenerator.Retire(frame.SequenceNumber, destConnID, rcvTime.Add(3*c.rttStats.PTO(false))) case *wire.HandshakeDoneFrame: - err = s.handleHandshakeDoneFrame(rcvTime) - case *wire.DatagramFrame: - err = s.handleDatagramFrame(frame) + err = c.handleHandshakeDoneFrame(rcvTime) default: err = fmt.Errorf("unexpected frame type: %s", reflect.ValueOf(&frame).Elem().Type().Name()) } @@ -1554,27 +1962,35 @@ func (s *connection) handleFrame( } // handlePacket is called by the server with a new packet -func (s *connection) handlePacket(p receivedPacket) { - s.receivedPacketMx.Lock() +func (c *Conn) handlePacket(p receivedPacket) { + c.receivedPacketMx.Lock() // Discard packets once the amount of queued packets is larger than // the channel size, protocol.MaxConnUnprocessedPackets - if s.receivedPackets.Len() >= protocol.MaxConnUnprocessedPackets { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropDOSPrevention) + if c.receivedPackets.Len() >= protocol.MaxConnUnprocessedPackets { + if c.qlogger != nil { + var datagramID qlog.DatagramID + if wire.IsLongHeaderPacket(p.data[0]) { + datagramID = qlog.CalculateDatagramID(p.data) + } + c.qlogger.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: int(p.Size())}, + DatagramID: datagramID, + Trigger: qlog.PacketDropDOSPrevention, + }) } - s.receivedPacketMx.Unlock() + c.receivedPacketMx.Unlock() return } - s.receivedPackets.PushBack(p) - s.receivedPacketMx.Unlock() + c.receivedPackets.PushBack(p) + c.receivedPacketMx.Unlock() select { - case s.notifyReceivedPacket <- struct{}{}: + case c.notifyReceivedPacket <- struct{}{}: default: } } -func (s *connection) handleConnectionCloseFrame(frame *wire.ConnectionCloseFrame) error { +func (c *Conn) handleConnectionCloseFrame(frame *wire.ConnectionCloseFrame) error { if frame.IsApplicationError { return &qerr.ApplicationError{ Remote: true, @@ -1590,25 +2006,25 @@ func (s *connection) handleConnectionCloseFrame(frame *wire.ConnectionCloseFrame } } -func (s *connection) handleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) error { - if err := s.cryptoStreamManager.HandleCryptoFrame(frame, encLevel); err != nil { +func (c *Conn) handleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) error { + if err := c.cryptoStreamManager.HandleCryptoFrame(frame, encLevel); err != nil { return err } for { - data := s.cryptoStreamManager.GetCryptoData(encLevel) + data := c.cryptoStreamManager.GetCryptoData(encLevel) if data == nil { break } - if err := s.cryptoStreamHandler.HandleMessage(data, encLevel); err != nil { + if err := c.cryptoStreamHandler.HandleMessage(data, encLevel); err != nil { return err } } - return s.handleHandshakeEvents(rcvTime) + return c.handleHandshakeEvents(rcvTime) } -func (s *connection) handleHandshakeEvents(now time.Time) error { +func (c *Conn) handleHandshakeEvents(now monotime.Time) error { for { - ev := s.cryptoStreamHandler.NextEvent() + ev := c.cryptoStreamHandler.NextEvent() var err error switch ev.Kind { case handshake.EventNoEvent: @@ -1616,22 +2032,22 @@ func (s *connection) handleHandshakeEvents(now time.Time) error { case handshake.EventHandshakeComplete: // Don't call handleHandshakeComplete yet. // It's advantageous to process ACK frames that might be serialized after the CRYPTO frame first. - s.handshakeComplete = true + c.handshakeComplete = true case handshake.EventReceivedTransportParameters: - err = s.handleTransportParameters(ev.TransportParameters) + err = c.handleTransportParameters(ev.TransportParameters) case handshake.EventRestoredTransportParameters: - s.restoreTransportParameters(ev.TransportParameters) - close(s.earlyConnReadyChan) + c.restoreTransportParameters(ev.TransportParameters) + close(c.earlyConnReadyChan) case handshake.EventReceivedReadKeys: // queue all previously undecryptable packets - s.undecryptablePacketsToProcess = append(s.undecryptablePacketsToProcess, s.undecryptablePackets...) - s.undecryptablePackets = nil + c.undecryptablePacketsToProcess = append(c.undecryptablePacketsToProcess, c.undecryptablePackets...) + c.undecryptablePackets = nil case handshake.EventDiscard0RTTKeys: - err = s.dropEncryptionLevel(protocol.Encryption0RTT, now) + err = c.dropEncryptionLevel(protocol.Encryption0RTT, now) case handshake.EventWriteInitialData: - _, err = s.initialStream.Write(ev.Data) + _, err = c.initialStream.Write(ev.Data) case handshake.EventWriteHandshakeData: - _, err = s.handshakeStream.Write(ev.Data) + _, err = c.handshakeStream.Write(ev.Data) } if err != nil { return err @@ -1639,89 +2055,25 @@ func (s *connection) handleHandshakeEvents(now time.Time) error { } } -func (s *connection) handleStreamFrame(frame *wire.StreamFrame, rcvTime time.Time) error { - str, err := s.streamsMap.GetOrOpenReceiveStream(frame.StreamID) - if err != nil { - return err - } - if str == nil { // stream was already closed and garbage collected - return nil - } - return str.handleStreamFrame(frame, rcvTime) -} - -func (s *connection) handleMaxDataFrame(frame *wire.MaxDataFrame) { - s.connFlowController.UpdateSendWindow(frame.MaximumData) -} - -func (s *connection) handleMaxStreamDataFrame(frame *wire.MaxStreamDataFrame) error { - str, err := s.streamsMap.GetOrOpenSendStream(frame.StreamID) - if err != nil { - return err - } - if str == nil { - // stream is closed and already garbage collected - return nil - } - str.updateSendWindow(frame.MaximumStreamData) - return nil -} - -func (s *connection) handleStreamDataBlockedFrame(frame *wire.StreamDataBlockedFrame) error { - // We don't need to do anything in response to a STREAM_DATA_BLOCKED frame, - // but we need to make sure that the stream ID is valid. - _, err := s.streamsMap.GetOrOpenReceiveStream(frame.StreamID) - return err -} - -func (s *connection) handleMaxStreamsFrame(frame *wire.MaxStreamsFrame) { - s.streamsMap.HandleMaxStreamsFrame(frame) -} - -func (s *connection) handleResetStreamFrame(frame *wire.ResetStreamFrame, rcvTime time.Time) error { - str, err := s.streamsMap.GetOrOpenReceiveStream(frame.StreamID) - if err != nil { - return err - } - if str == nil { - // stream is closed and already garbage collected - return nil - } - return str.handleResetStreamFrame(frame, rcvTime) -} - -func (s *connection) handleStopSendingFrame(frame *wire.StopSendingFrame) error { - str, err := s.streamsMap.GetOrOpenSendStream(frame.StreamID) - if err != nil { - return err - } - if str == nil { - // stream is closed and already garbage collected - return nil - } - str.handleStopSendingFrame(frame) - return nil -} - -func (s *connection) handlePathChallengeFrame(f *wire.PathChallengeFrame) { - if s.perspective == protocol.PerspectiveClient { - s.queueControlFrame(&wire.PathResponseFrame{Data: f.Data}) +func (c *Conn) handlePathChallengeFrame(f *wire.PathChallengeFrame) { + if c.perspective == protocol.PerspectiveClient { + c.queueControlFrame(&wire.PathResponseFrame{Data: f.Data}) } } -func (s *connection) handlePathResponseFrame(f *wire.PathResponseFrame) error { - switch s.perspective { +func (c *Conn) handlePathResponseFrame(f *wire.PathResponseFrame) error { + switch c.perspective { case protocol.PerspectiveClient: - return s.handlePathResponseFrameClient(f) + return c.handlePathResponseFrameClient(f) case protocol.PerspectiveServer: - return s.handlePathResponseFrameServer(f) + return c.handlePathResponseFrameServer(f) default: panic("unreachable") } } -func (s *connection) handlePathResponseFrameClient(f *wire.PathResponseFrame) error { - pm := s.pathManagerOutgoing.Load() +func (c *Conn) handlePathResponseFrameClient(f *wire.PathResponseFrame) error { + pm := c.pathManagerOutgoing.Load() if pm == nil { return &qerr.TransportError{ ErrorCode: qerr.ProtocolViolation, @@ -1732,54 +2084,46 @@ func (s *connection) handlePathResponseFrameClient(f *wire.PathResponseFrame) er return nil } -func (s *connection) handlePathResponseFrameServer(f *wire.PathResponseFrame) error { - if s.pathManager == nil { +func (c *Conn) handlePathResponseFrameServer(f *wire.PathResponseFrame) error { + if c.pathManager == nil { // since we didn't send PATH_CHALLENGEs yet, we don't expect PATH_RESPONSEs return &qerr.TransportError{ ErrorCode: qerr.ProtocolViolation, ErrorMessage: "unexpected PATH_RESPONSE frame", } } - s.pathManager.HandlePathResponseFrame(f) + c.pathManager.HandlePathResponseFrame(f) return nil } -func (s *connection) handleNewTokenFrame(frame *wire.NewTokenFrame) error { - if s.perspective == protocol.PerspectiveServer { +func (c *Conn) handleNewTokenFrame(frame *wire.NewTokenFrame) error { + if c.perspective == protocol.PerspectiveServer { return &qerr.TransportError{ ErrorCode: qerr.ProtocolViolation, ErrorMessage: "received NEW_TOKEN frame from the client", } } - if s.config.TokenStore != nil { - s.config.TokenStore.Put(s.tokenStoreKey, &ClientToken{data: frame.Token}) + if c.config.TokenStore != nil { + c.config.TokenStore.Put(c.tokenStoreKey, &ClientToken{data: frame.Token, rtt: c.rttStats.SmoothedRTT()}) } return nil } -func (s *connection) handleNewConnectionIDFrame(f *wire.NewConnectionIDFrame) error { - return s.connIDManager.Add(f) -} - -func (s *connection) handleRetireConnectionIDFrame(f *wire.RetireConnectionIDFrame, destConnID protocol.ConnectionID) error { - return s.connIDGenerator.Retire(f.SequenceNumber, destConnID) -} - -func (s *connection) handleHandshakeDoneFrame(rcvTime time.Time) error { - if s.perspective == protocol.PerspectiveServer { +func (c *Conn) handleHandshakeDoneFrame(rcvTime monotime.Time) error { + if c.perspective == protocol.PerspectiveServer { return &qerr.TransportError{ ErrorCode: qerr.ProtocolViolation, ErrorMessage: "received a HANDSHAKE_DONE frame", } } - if !s.handshakeConfirmed { - return s.handleHandshakeConfirmed(rcvTime) + if !c.handshakeConfirmed { + return c.handleHandshakeConfirmed(rcvTime) } return nil } -func (s *connection) handleAckFrame(frame *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) error { - acked1RTTPacket, err := s.sentPacketHandler.ReceivedAck(frame, encLevel, s.lastPacketReceivedTime) +func (c *Conn) handleAckFrame(frame *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) error { + acked1RTTPacket, err := c.sentPacketHandler.ReceivedAck(frame, encLevel, c.lastPacketReceivedTime) if err != nil { return err } @@ -1789,81 +2133,83 @@ func (s *connection) handleAckFrame(frame *wire.AckFrame, encLevel protocol.Encr // On the client side: If the packet acknowledged a 1-RTT packet, this confirms the handshake. // This is only possible if the ACK was sent in a 1-RTT packet. // This is an optimization over simply waiting for a HANDSHAKE_DONE frame, see section 4.1.2 of RFC 9001. - if s.perspective == protocol.PerspectiveClient && !s.handshakeConfirmed { - if err := s.handleHandshakeConfirmed(rcvTime); err != nil { + if c.perspective == protocol.PerspectiveClient && !c.handshakeConfirmed { + if err := c.handleHandshakeConfirmed(rcvTime); err != nil { return err } } // If one of the acknowledged packets was a Path MTU probe packet, this might have increased the Path MTU estimate. - if s.mtuDiscoverer != nil { - if mtu := s.mtuDiscoverer.CurrentSize(); mtu > protocol.ByteCount(s.currentMTUEstimate.Load()) { - s.currentMTUEstimate.Store(uint32(mtu)) - s.sentPacketHandler.SetMaxDatagramSize(mtu) + if c.mtuDiscoverer != nil { + if mtu := c.mtuDiscoverer.CurrentSize(); mtu > protocol.ByteCount(c.currentMTUEstimate.Load()) { + c.currentMTUEstimate.Store(uint32(mtu)) + c.sentPacketHandler.SetMaxDatagramSize(mtu) } } - return s.cryptoStreamHandler.SetLargest1RTTAcked(frame.LargestAcked()) + return c.cryptoStreamHandler.SetLargest1RTTAcked(frame.LargestAcked()) } -func (s *connection) handleDatagramFrame(f *wire.DatagramFrame) error { - if f.Length(s.version) > wire.MaxDatagramSize { +func (c *Conn) handleDatagramFrame(f *wire.DatagramFrame) error { + if f.Length(c.version) > wire.MaxDatagramSize { return &qerr.TransportError{ ErrorCode: qerr.ProtocolViolation, ErrorMessage: "DATAGRAM frame too large", } } - s.datagramQueue.HandleDatagramFrame(f) + c.datagramQueue.HandleDatagramFrame(f) return nil } -func (s *connection) setCloseError(e *closeError) { - s.closeErr.CompareAndSwap(nil, e) +func (c *Conn) setCloseError(e *closeError) { + c.closeErr.CompareAndSwap(nil, e) select { - case s.closeChan <- struct{}{}: + case c.closeChan <- struct{}{}: default: } } // closeLocal closes the connection and send a CONNECTION_CLOSE containing the error -func (s *connection) closeLocal(e error) { - s.setCloseError(&closeError{err: e, immediate: false}) +func (c *Conn) closeLocal(e error) { + c.setCloseError(&closeError{err: e, immediate: false}) } // destroy closes the connection without sending the error on the wire -func (s *connection) destroy(e error) { - s.destroyImpl(e) - <-s.ctx.Done() +func (c *Conn) destroy(e error) { + c.destroyImpl(e) + <-c.ctx.Done() } -func (s *connection) destroyImpl(e error) { - s.setCloseError(&closeError{err: e, immediate: true}) +func (c *Conn) destroyImpl(e error) { + c.setCloseError(&closeError{err: e, immediate: true}) } -func (s *connection) CloseWithError(code ApplicationErrorCode, desc string) error { - s.closeLocal(&qerr.ApplicationError{ +// CloseWithError closes the connection with an error. +// The error string will be sent to the peer. +func (c *Conn) CloseWithError(code ApplicationErrorCode, desc string) error { + c.closeLocal(&qerr.ApplicationError{ ErrorCode: code, ErrorMessage: desc, }) - <-s.ctx.Done() + <-c.ctx.Done() return nil } -func (s *connection) closeWithTransportError(code TransportErrorCode) { - s.closeLocal(&qerr.TransportError{ErrorCode: code}) - <-s.ctx.Done() +func (c *Conn) closeWithTransportError(code TransportErrorCode) { + c.closeLocal(&qerr.TransportError{ErrorCode: code}) + <-c.ctx.Done() } -func (s *connection) handleCloseError(closeErr *closeError) { +func (c *Conn) handleCloseError(closeErr *closeError) { if closeErr.immediate { if nerr, ok := closeErr.err.(net.Error); ok && nerr.Timeout() { - s.logger.Errorf("Destroying connection: %s", closeErr.err) + c.logger.Errorf("Destroying connection: %s", closeErr.err) } else { - s.logger.Errorf("Destroying connection with error: %s", closeErr.err) + c.logger.Errorf("Destroying connection with error: %s", closeErr.err) } } else { if closeErr.err == nil { - s.logger.Infof("Closing connection.") + c.logger.Infof("Closing connection.") } else { - s.logger.Errorf("Closing connection with error: %s", closeErr.err) + c.logger.Errorf("Closing connection with error: %s", closeErr.err) } } @@ -1882,153 +2228,193 @@ func (s *connection) handleCloseError(closeErr *closeError) { transportErr *TransportError ) var isRemoteClose bool + var trigger qlog.ConnectionCloseTrigger + var reason string + var transportErrorCode *qlog.TransportErrorCode + var applicationErrorCode *qlog.ApplicationErrorCode switch { case errors.Is(e, qerr.ErrIdleTimeout), - errors.Is(e, qerr.ErrHandshakeTimeout), - errors.As(e, &statelessResetErr), - errors.As(e, &versionNegotiationErr), - errors.As(e, &recreateErr): + errors.Is(e, qerr.ErrHandshakeTimeout): + trigger = qlog.ConnectionCloseTriggerIdleTimeout + case errors.As(e, &statelessResetErr): + trigger = qlog.ConnectionCloseTriggerStatelessReset + case errors.As(e, &versionNegotiationErr): + trigger = qlog.ConnectionCloseTriggerVersionMismatch + case errors.As(e, &recreateErr): case errors.As(e, &applicationErr): isRemoteClose = applicationErr.Remote + reason = applicationErr.ErrorMessage + applicationErrorCode = &applicationErr.ErrorCode case errors.As(e, &transportErr): isRemoteClose = transportErr.Remote + reason = transportErr.ErrorMessage + transportErrorCode = &transportErr.ErrorCode case closeErr.immediate: e = closeErr.err default: - e = &qerr.TransportError{ + te := &qerr.TransportError{ ErrorCode: qerr.InternalError, ErrorMessage: e.Error(), } + e = te + reason = te.ErrorMessage + code := te.ErrorCode + transportErrorCode = &code } - s.streamsMap.CloseWithError(e) - if s.datagramQueue != nil { - s.datagramQueue.CloseWithError(e) + c.streamsMap.CloseWithError(e) + if c.datagramQueue != nil { + c.datagramQueue.CloseWithError(e) } // In rare instances, the connection ID manager might switch to a new connection ID // when sending the CONNECTION_CLOSE frame. // The connection ID manager removes the active stateless reset token from the packet // handler map when it is closed, so we need to make sure that this happens last. - defer s.connIDManager.Close() + defer c.connIDManager.Close() - if s.tracer != nil && s.tracer.ClosedConnection != nil && !errors.As(e, &recreateErr) { - s.tracer.ClosedConnection(e) + if c.qlogger != nil && !errors.As(e, &recreateErr) { + initiator := qlog.InitiatorLocal + if isRemoteClose { + initiator = qlog.InitiatorRemote + } + c.qlogger.RecordEvent(qlog.ConnectionClosed{ + Initiator: initiator, + ConnectionError: transportErrorCode, + ApplicationError: applicationErrorCode, + Trigger: trigger, + Reason: reason, + }) } // If this is a remote close we're done here if isRemoteClose { - s.connIDGenerator.ReplaceWithClosed(nil) + c.connIDGenerator.ReplaceWithClosed(nil, 3*c.rttStats.PTO(false)) return } if closeErr.immediate { - s.connIDGenerator.RemoveAll() + c.connIDGenerator.RemoveAll() return } // Don't send out any CONNECTION_CLOSE if this is an error that occurred // before we even sent out the first packet. - if s.perspective == protocol.PerspectiveClient && !s.sentFirstPacket { - s.connIDGenerator.RemoveAll() + if c.perspective == protocol.PerspectiveClient && !c.sentFirstPacket { + c.connIDGenerator.RemoveAll() return } - connClosePacket, err := s.sendConnectionClose(e) + connClosePacket, err := c.sendConnectionClose(e) if err != nil { - s.logger.Debugf("Error sending CONNECTION_CLOSE: %s", err) + c.logger.Debugf("Error sending CONNECTION_CLOSE: %s", err) } - s.connIDGenerator.ReplaceWithClosed(connClosePacket) + c.connIDGenerator.ReplaceWithClosed(connClosePacket, 3*c.rttStats.PTO(false)) } -func (s *connection) dropEncryptionLevel(encLevel protocol.EncryptionLevel, now time.Time) error { - if s.tracer != nil && s.tracer.DroppedEncryptionLevel != nil { - s.tracer.DroppedEncryptionLevel(encLevel) - } - s.sentPacketHandler.DropPackets(encLevel, now) - s.receivedPacketHandler.DropPackets(encLevel) +func (c *Conn) dropEncryptionLevel(encLevel protocol.EncryptionLevel, now monotime.Time) error { + c.sentPacketHandler.DropPackets(encLevel, now) + c.receivedPacketHandler.DropPackets(encLevel) //nolint:exhaustive // only Initial and 0-RTT need special treatment switch encLevel { case protocol.EncryptionInitial: - s.droppedInitialKeys = true - s.cryptoStreamHandler.DiscardInitialKeys() + c.droppedInitialKeys = true + c.cryptoStreamHandler.DiscardInitialKeys() case protocol.Encryption0RTT: - s.streamsMap.ResetFor0RTT() - s.framer.Handle0RTTRejection() - return s.connFlowController.Reset() + c.streamsMap.ResetFor0RTT() + c.framer.Handle0RTTRejection() + return c.connFlowController.Reset() } - return s.cryptoStreamManager.Drop(encLevel) + return c.cryptoStreamManager.Drop(encLevel) } // is called for the client, when restoring transport parameters saved for 0-RTT -func (s *connection) restoreTransportParameters(params *wire.TransportParameters) { - if s.logger.Debug() { - s.logger.Debugf("Restoring Transport Parameters: %s", params) +func (c *Conn) restoreTransportParameters(params *wire.TransportParameters) { + if c.logger.Debug() { + c.logger.Debugf("Restoring Transport Parameters: %s", params) + } + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.ParametersSet{ + Restore: true, + Initiator: qlog.InitiatorRemote, + SentBy: c.perspective, + OriginalDestinationConnectionID: params.OriginalDestinationConnectionID, + InitialSourceConnectionID: params.InitialSourceConnectionID, + RetrySourceConnectionID: params.RetrySourceConnectionID, + StatelessResetToken: params.StatelessResetToken, + DisableActiveMigration: params.DisableActiveMigration, + MaxIdleTimeout: params.MaxIdleTimeout, + MaxUDPPayloadSize: params.MaxUDPPayloadSize, + AckDelayExponent: params.AckDelayExponent, + MaxAckDelay: params.MaxAckDelay, + ActiveConnectionIDLimit: params.ActiveConnectionIDLimit, + InitialMaxData: params.InitialMaxData, + InitialMaxStreamDataBidiLocal: params.InitialMaxStreamDataBidiLocal, + InitialMaxStreamDataBidiRemote: params.InitialMaxStreamDataBidiRemote, + InitialMaxStreamDataUni: params.InitialMaxStreamDataUni, + InitialMaxStreamsBidi: int64(params.MaxBidiStreamNum), + InitialMaxStreamsUni: int64(params.MaxUniStreamNum), + MaxDatagramFrameSize: params.MaxDatagramFrameSize, + EnableResetStreamAt: params.EnableResetStreamAt, + }) } - s.peerParams = params - s.connIDGenerator.SetMaxActiveConnIDs(params.ActiveConnectionIDLimit) - s.connFlowController.UpdateSendWindow(params.InitialMaxData) - s.streamsMap.UpdateLimits(params) - s.connStateMutex.Lock() - s.connState.SupportsDatagrams = s.supportsDatagrams() - s.connStateMutex.Unlock() + c.peerParams = params + c.connIDGenerator.SetMaxActiveConnIDs(params.ActiveConnectionIDLimit) + c.connFlowController.UpdateSendWindow(params.InitialMaxData) + c.streamsMap.HandleTransportParameters(params) } -func (s *connection) handleTransportParameters(params *wire.TransportParameters) error { - if s.tracer != nil && s.tracer.ReceivedTransportParameters != nil { - s.tracer.ReceivedTransportParameters(params) +func (c *Conn) handleTransportParameters(params *wire.TransportParameters) error { + if c.qlogger != nil { + c.qlogTransportParameters(params, c.perspective.Opposite(), false) } - if err := s.checkTransportParameters(params); err != nil { + if err := c.checkTransportParameters(params); err != nil { return &qerr.TransportError{ ErrorCode: qerr.TransportParameterError, ErrorMessage: err.Error(), } } - if s.perspective == protocol.PerspectiveClient && s.peerParams != nil && s.ConnectionState().Used0RTT && !params.ValidForUpdate(s.peerParams) { + if c.perspective == protocol.PerspectiveClient && c.peerParams != nil && c.ConnectionState().Used0RTT && !params.ValidForUpdate(c.peerParams) { return &qerr.TransportError{ ErrorCode: qerr.ProtocolViolation, ErrorMessage: "server sent reduced limits after accepting 0-RTT data", } } - s.peerParams = params + c.peerParams = params // On the client side we have to wait for handshake completion. // During a 0-RTT connection, we are only allowed to use the new transport parameters for 1-RTT packets. - if s.perspective == protocol.PerspectiveServer { - s.applyTransportParameters() + if c.perspective == protocol.PerspectiveServer { + c.applyTransportParameters() // On the server side, the early connection is ready as soon as we processed // the client's transport parameters. - close(s.earlyConnReadyChan) + close(c.earlyConnReadyChan) } - - s.connStateMutex.Lock() - s.connState.SupportsDatagrams = s.supportsDatagrams() - s.connStateMutex.Unlock() return nil } -func (s *connection) checkTransportParameters(params *wire.TransportParameters) error { - if s.logger.Debug() { - s.logger.Debugf("Processed Transport Parameters: %s", params) +func (c *Conn) checkTransportParameters(params *wire.TransportParameters) error { + if c.logger.Debug() { + c.logger.Debugf("Processed Transport Parameters: %s", params) } // check the initial_source_connection_id - if params.InitialSourceConnectionID != s.handshakeDestConnID { - return fmt.Errorf("expected initial_source_connection_id to equal %s, is %s", s.handshakeDestConnID, params.InitialSourceConnectionID) + if params.InitialSourceConnectionID != c.handshakeDestConnID { + return fmt.Errorf("expected initial_source_connection_id to equal %s, is %s", c.handshakeDestConnID, params.InitialSourceConnectionID) } - if s.perspective == protocol.PerspectiveServer { + if c.perspective == protocol.PerspectiveServer { return nil } // check the original_destination_connection_id - if params.OriginalDestinationConnectionID != s.origDestConnID { - return fmt.Errorf("expected original_destination_connection_id to equal %s, is %s", s.origDestConnID, params.OriginalDestinationConnectionID) + if params.OriginalDestinationConnectionID != c.origDestConnID { + return fmt.Errorf("expected original_destination_connection_id to equal %s, is %s", c.origDestConnID, params.OriginalDestinationConnectionID) } - if s.retrySrcConnID != nil { // a Retry was performed + if c.retrySrcConnID != nil { // a Retry was performed if params.RetrySourceConnectionID == nil { return errors.New("missing retry_source_connection_id") } - if *params.RetrySourceConnectionID != *s.retrySrcConnID { - return fmt.Errorf("expected retry_source_connection_id to equal %s, is %s", s.retrySrcConnID, *params.RetrySourceConnectionID) + if *params.RetrySourceConnectionID != *c.retrySrcConnID { + return fmt.Errorf("expected retry_source_connection_id to equal %s, is %s", c.retrySrcConnID, *params.RetrySourceConnectionID) } } else if params.RetrySourceConnectionID != nil { return errors.New("received retry_source_connection_id, although no Retry was performed") @@ -2036,94 +2422,95 @@ func (s *connection) checkTransportParameters(params *wire.TransportParameters) return nil } -func (s *connection) applyTransportParameters() { - params := s.peerParams +func (c *Conn) applyTransportParameters() { + params := c.peerParams // Our local idle timeout will always be > 0. - s.idleTimeout = s.config.MaxIdleTimeout + c.idleTimeout = c.config.MaxIdleTimeout // If the peer advertised an idle timeout, take the minimum of the values. if params.MaxIdleTimeout > 0 { - s.idleTimeout = min(s.idleTimeout, params.MaxIdleTimeout) + c.idleTimeout = min(c.idleTimeout, params.MaxIdleTimeout) } - s.keepAliveInterval = min(s.config.KeepAlivePeriod, s.idleTimeout/2) - s.streamsMap.UpdateLimits(params) - s.frameParser.SetAckDelayExponent(params.AckDelayExponent) - s.connFlowController.UpdateSendWindow(params.InitialMaxData) - s.rttStats.SetMaxAckDelay(params.MaxAckDelay) - s.connIDGenerator.SetMaxActiveConnIDs(params.ActiveConnectionIDLimit) + c.keepAliveInterval = min(c.config.KeepAlivePeriod, c.idleTimeout/2) + c.streamsMap.HandleTransportParameters(params) + c.frameParser.SetAckDelayExponent(params.AckDelayExponent) + c.connFlowController.UpdateSendWindow(params.InitialMaxData) + c.rttStats.SetMaxAckDelay(params.MaxAckDelay) + c.connIDGenerator.SetMaxActiveConnIDs(params.ActiveConnectionIDLimit) if params.StatelessResetToken != nil { - s.connIDManager.SetStatelessResetToken(*params.StatelessResetToken) + c.connIDManager.SetStatelessResetToken(*params.StatelessResetToken) } // We don't support connection migration yet, so we don't have any use for the preferred_address. if params.PreferredAddress != nil { // Retire the connection ID. - s.connIDManager.AddFromPreferredAddress(params.PreferredAddress.ConnectionID, params.PreferredAddress.StatelessResetToken) + c.connIDManager.AddFromPreferredAddress(params.PreferredAddress.ConnectionID, params.PreferredAddress.StatelessResetToken) } maxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize) if params.MaxUDPPayloadSize > 0 && params.MaxUDPPayloadSize < maxPacketSize { maxPacketSize = params.MaxUDPPayloadSize } - s.mtuDiscoverer = newMTUDiscoverer( - s.rttStats, - protocol.ByteCount(s.config.InitialPacketSize), + c.mtuDiscoverer = newMTUDiscoverer( + c.rttStats, + protocol.ByteCount(c.config.InitialPacketSize), maxPacketSize, - s.tracer, + c.qlogger, ) } -func (s *connection) triggerSending(now time.Time) error { - s.pacingDeadline = time.Time{} +func (c *Conn) triggerSending(now monotime.Time) error { + c.pacingDeadline = 0 - sendMode := s.sentPacketHandler.SendMode(now) - //nolint:exhaustive // No need to handle pacing limited here. + sendMode := c.sentPacketHandler.SendMode(now) switch sendMode { case ackhandler.SendAny: - return s.sendPackets(now) + return c.sendPackets(now) case ackhandler.SendNone: + c.blocked = blockModeHardBlocked return nil case ackhandler.SendPacingLimited: - deadline := s.sentPacketHandler.TimeUntilSend() + deadline := c.sentPacketHandler.TimeUntilSend() if deadline.IsZero() { deadline = deadlineSendImmediately } - s.pacingDeadline = deadline + c.pacingDeadline = deadline // Allow sending of an ACK if we're pacing limit. // This makes sure that a peer that is mostly receiving data (and thus has an inaccurate cwnd estimate) // sends enough ACKs to allow its peer to utilize the bandwidth. - fallthrough + return c.maybeSendAckOnlyPacket(now) case ackhandler.SendAck: // We can at most send a single ACK only packet. // There will only be a new ACK after receiving new packets. // SendAck is only returned when we're congestion limited, so we don't need to set the pacing timer. - return s.maybeSendAckOnlyPacket(now) + c.blocked = blockModeCongestionLimited + return c.maybeSendAckOnlyPacket(now) case ackhandler.SendPTOInitial, ackhandler.SendPTOHandshake, ackhandler.SendPTOAppData: - if err := s.sendProbePacket(sendMode, now); err != nil { + if err := c.sendProbePacket(sendMode, now); err != nil { return err } - if s.sendQueue.WouldBlock() { - s.scheduleSending() + if c.sendQueue.WouldBlock() { + c.scheduleSending() return nil } - return s.triggerSending(now) + return c.triggerSending(now) default: return fmt.Errorf("BUG: invalid send mode %d", sendMode) } } -func (s *connection) sendPackets(now time.Time) error { - if s.perspective == protocol.PerspectiveClient && s.handshakeConfirmed { - if pm := s.pathManagerOutgoing.Load(); pm != nil { +func (c *Conn) sendPackets(now monotime.Time) error { + if c.perspective == protocol.PerspectiveClient && c.handshakeConfirmed { + if pm := c.pathManagerOutgoing.Load(); pm != nil { connID, frame, tr, ok := pm.NextPathToProbe() if ok { - probe, buf, err := s.packer.PackPathProbePacket(connID, []ackhandler.Frame{frame}, s.version) + probe, buf, err := c.packer.PackPathProbePacket(connID, []ackhandler.Frame{frame}, c.version) if err != nil { return err } - s.logger.Debugf("sending path probe packet from %s", s.LocalAddr()) - s.logShortHeaderPacket(probe.DestConnID, probe.Ack, probe.Frames, probe.StreamFrames, probe.PacketNumber, probe.PacketNumberLen, probe.KeyPhase, protocol.ECNNon, buf.Len(), false) - s.registerPackedShortHeaderPacket(probe, protocol.ECNNon, now) - tr.WriteTo(buf.Data, s.conn.RemoteAddr()) + c.logger.Debugf("sending path probe packet from %s", c.LocalAddr()) + c.logShortHeaderPacket(probe, protocol.ECNNon, buf.Len()) + c.registerPackedShortHeaderPacket(probe, protocol.ECNNon, now) + tr.WriteTo(buf.Data, c.conn.RemoteAddr()) // There's (likely) more data to send. Loop around again. - s.scheduleSending() + c.scheduleSending() return nil } } @@ -2133,58 +2520,58 @@ func (s *connection) sendPackets(now time.Time) error { // Can't use GSO, since we need to send a single packet that's larger than our current maximum size. // Performance-wise, this doesn't matter, since we only send a very small (<10) number of // MTU probe packets per connection. - if s.handshakeConfirmed && s.mtuDiscoverer != nil && s.mtuDiscoverer.ShouldSendProbe(now) { - ping, size := s.mtuDiscoverer.GetPing(now) - p, buf, err := s.packer.PackMTUProbePacket(ping, size, s.version) + if c.handshakeConfirmed && c.mtuDiscoverer != nil && c.mtuDiscoverer.ShouldSendProbe(now) { + ping, size := c.mtuDiscoverer.GetPing(now) + p, buf, err := c.packer.PackMTUProbePacket(ping, size, c.version) if err != nil { return err } - ecn := s.sentPacketHandler.ECNMode(true) - s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, buf.Len(), false) - s.registerPackedShortHeaderPacket(p, ecn, now) - s.sendQueue.Send(buf, 0, ecn) + ecn := c.sentPacketHandler.ECNMode(true) + c.logShortHeaderPacket(p, ecn, buf.Len()) + c.registerPackedShortHeaderPacket(p, ecn, now) + c.sendQueue.Send(buf, 0, ecn) // There's (likely) more data to send. Loop around again. - s.scheduleSending() + c.scheduleSending() return nil } - if offset := s.connFlowController.GetWindowUpdate(now); offset > 0 { - s.framer.QueueControlFrame(&wire.MaxDataFrame{MaximumData: offset}) + if offset := c.connFlowController.GetWindowUpdate(now); offset > 0 { + c.framer.QueueControlFrame(&wire.MaxDataFrame{MaximumData: offset}) } - if cf := s.cryptoStreamManager.GetPostHandshakeData(protocol.MaxPostHandshakeCryptoFrameSize); cf != nil { - s.queueControlFrame(cf) + if cf := c.cryptoStreamManager.GetPostHandshakeData(protocol.MaxPostHandshakeCryptoFrameSize); cf != nil { + c.queueControlFrame(cf) } - if !s.handshakeConfirmed { - packet, err := s.packer.PackCoalescedPacket(false, s.maxPacketSize(), now, s.version) + if !c.handshakeConfirmed { + packet, err := c.packer.PackCoalescedPacket(false, c.maxPacketSize(), now, c.version) if err != nil || packet == nil { return err } - s.sentFirstPacket = true - if err := s.sendPackedCoalescedPacket(packet, s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now); err != nil { + c.sentFirstPacket = true + if err := c.sendPackedCoalescedPacket(packet, c.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now); err != nil { return err } //nolint:exhaustive // only need to handle pacing-related events here - switch s.sentPacketHandler.SendMode(now) { + switch c.sentPacketHandler.SendMode(now) { case ackhandler.SendPacingLimited: - s.resetPacingDeadline() + c.resetPacingDeadline() case ackhandler.SendAny: - s.pacingDeadline = deadlineSendImmediately + c.pacingDeadline = deadlineSendImmediately } return nil } - if s.conn.capabilities().GSO { - return s.sendPacketsWithGSO(now) + if c.conn.capabilities().GSO { + return c.sendPacketsWithGSO(now) } - return s.sendPacketsWithoutGSO(now) + return c.sendPacketsWithoutGSO(now) } -func (s *connection) sendPacketsWithoutGSO(now time.Time) error { +func (c *Conn) sendPacketsWithoutGSO(now monotime.Time) error { for { buf := getPacketBuffer() - ecn := s.sentPacketHandler.ECNMode(true) - if _, err := s.appendOneShortHeaderPacket(buf, s.maxPacketSize(), ecn, now); err != nil { + ecn := c.sentPacketHandler.ECNMode(true) + if _, err := c.appendOneShortHeaderPacket(buf, c.maxPacketSize(), ecn, now); err != nil { if err == errNothingToPack { buf.Release() return nil @@ -2192,38 +2579,38 @@ func (s *connection) sendPacketsWithoutGSO(now time.Time) error { return err } - s.sendQueue.Send(buf, 0, ecn) + c.sendQueue.Send(buf, 0, ecn) - if s.sendQueue.WouldBlock() { + if c.sendQueue.WouldBlock() { return nil } - sendMode := s.sentPacketHandler.SendMode(now) + sendMode := c.sentPacketHandler.SendMode(now) if sendMode == ackhandler.SendPacingLimited { - s.resetPacingDeadline() + c.resetPacingDeadline() return nil } if sendMode != ackhandler.SendAny { return nil } // Prioritize receiving of packets over sending out more packets. - s.receivedPacketMx.Lock() - hasPackets := !s.receivedPackets.Empty() - s.receivedPacketMx.Unlock() + c.receivedPacketMx.Lock() + hasPackets := !c.receivedPackets.Empty() + c.receivedPacketMx.Unlock() if hasPackets { - s.pacingDeadline = deadlineSendImmediately + c.pacingDeadline = deadlineSendImmediately return nil } } } -func (s *connection) sendPacketsWithGSO(now time.Time) error { +func (c *Conn) sendPacketsWithGSO(now monotime.Time) error { buf := getLargePacketBuffer() - maxSize := s.maxPacketSize() + maxSize := c.maxPacketSize() - ecn := s.sentPacketHandler.ECNMode(true) + ecn := c.sentPacketHandler.ECNMode(true) for { var dontSendMore bool - size, err := s.appendOneShortHeaderPacket(buf, maxSize, ecn, now) + size, err := c.appendOneShortHeaderPacket(buf, maxSize, ecn, now) if err != nil { if err != errNothingToPack { return err @@ -2236,9 +2623,9 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error { } if !dontSendMore { - sendMode := s.sentPacketHandler.SendMode(now) + sendMode := c.sentPacketHandler.SendMode(now) if sendMode == ackhandler.SendPacingLimited { - s.resetPacingDeadline() + c.resetPacingDeadline() } if sendMode != ackhandler.SendAny { dontSendMore = true @@ -2246,7 +2633,7 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error { } // Don't send more packets in this batch if they require a different ECN marking than the previous ones. - nextECN := s.sentPacketHandler.ECNMode(true) + nextECN := c.sentPacketHandler.ECNMode(true) // Append another packet if // 1. The congestion controller and pacer allow sending more @@ -2257,21 +2644,21 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error { continue } - s.sendQueue.Send(buf, uint16(maxSize), ecn) + c.sendQueue.Send(buf, uint16(maxSize), ecn) if dontSendMore { return nil } - if s.sendQueue.WouldBlock() { + if c.sendQueue.WouldBlock() { return nil } // Prioritize receiving of packets over sending out more packets. - s.receivedPacketMx.Lock() - hasPackets := !s.receivedPackets.Empty() - s.receivedPacketMx.Unlock() + c.receivedPacketMx.Lock() + hasPackets := !c.receivedPackets.Empty() + c.receivedPacketMx.Unlock() if hasPackets { - s.pacingDeadline = deadlineSendImmediately + c.pacingDeadline = deadlineSendImmediately return nil } @@ -2280,42 +2667,42 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error { } } -func (s *connection) resetPacingDeadline() { - deadline := s.sentPacketHandler.TimeUntilSend() +func (c *Conn) resetPacingDeadline() { + deadline := c.sentPacketHandler.TimeUntilSend() if deadline.IsZero() { deadline = deadlineSendImmediately } - s.pacingDeadline = deadline + c.pacingDeadline = deadline } -func (s *connection) maybeSendAckOnlyPacket(now time.Time) error { - if !s.handshakeConfirmed { - ecn := s.sentPacketHandler.ECNMode(false) - packet, err := s.packer.PackCoalescedPacket(true, s.maxPacketSize(), now, s.version) +func (c *Conn) maybeSendAckOnlyPacket(now monotime.Time) error { + if !c.handshakeConfirmed { + ecn := c.sentPacketHandler.ECNMode(false) + packet, err := c.packer.PackCoalescedPacket(true, c.maxPacketSize(), now, c.version) if err != nil { return err } if packet == nil { return nil } - return s.sendPackedCoalescedPacket(packet, ecn, now) + return c.sendPackedCoalescedPacket(packet, ecn, now) } - ecn := s.sentPacketHandler.ECNMode(true) - p, buf, err := s.packer.PackAckOnlyPacket(s.maxPacketSize(), now, s.version) + ecn := c.sentPacketHandler.ECNMode(true) + p, buf, err := c.packer.PackAckOnlyPacket(c.maxPacketSize(), now, c.version) if err != nil { if err == errNothingToPack { return nil } return err } - s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, buf.Len(), false) - s.registerPackedShortHeaderPacket(p, ecn, now) - s.sendQueue.Send(buf, 0, ecn) + c.logShortHeaderPacket(p, ecn, buf.Len()) + c.registerPackedShortHeaderPacket(p, ecn, now) + c.sendQueue.Send(buf, 0, ecn) return nil } -func (s *connection) sendProbePacket(sendMode ackhandler.SendMode, now time.Time) error { +func (c *Conn) sendProbePacket(sendMode ackhandler.SendMode, now monotime.Time) error { var encLevel protocol.EncryptionLevel //nolint:exhaustive // We only need to handle the PTO send modes here. switch sendMode { @@ -2332,18 +2719,18 @@ func (s *connection) sendProbePacket(sendMode ackhandler.SendMode, now time.Time // or until there are no more packets to queue. var packet *coalescedPacket for packet == nil { - if wasQueued := s.sentPacketHandler.QueueProbePacket(encLevel); !wasQueued { + if wasQueued := c.sentPacketHandler.QueueProbePacket(encLevel); !wasQueued { break } var err error - packet, err = s.packer.PackPTOProbePacket(encLevel, s.maxPacketSize(), false, now, s.version) + packet, err = c.packer.PackPTOProbePacket(encLevel, c.maxPacketSize(), false, now, c.version) if err != nil { return err } } if packet == nil { var err error - packet, err = s.packer.PackPTOProbePacket(encLevel, s.maxPacketSize(), true, now, s.version) + packet, err = c.packer.PackPTOProbePacket(encLevel, c.maxPacketSize(), true, now, c.version) if err != nil { return err } @@ -2351,26 +2738,26 @@ func (s *connection) sendProbePacket(sendMode ackhandler.SendMode, now time.Time if packet == nil || (len(packet.longHdrPackets) == 0 && packet.shortHdrPacket == nil) { return fmt.Errorf("connection BUG: couldn't pack %s probe packet: %v", encLevel, packet) } - return s.sendPackedCoalescedPacket(packet, s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now) + return c.sendPackedCoalescedPacket(packet, c.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now) } // appendOneShortHeaderPacket appends a new packet to the given packetBuffer. // If there was nothing to pack, the returned size is 0. -func (s *connection) appendOneShortHeaderPacket(buf *packetBuffer, maxSize protocol.ByteCount, ecn protocol.ECN, now time.Time) (protocol.ByteCount, error) { +func (c *Conn) appendOneShortHeaderPacket(buf *packetBuffer, maxSize protocol.ByteCount, ecn protocol.ECN, now monotime.Time) (protocol.ByteCount, error) { startLen := buf.Len() - p, err := s.packer.AppendPacket(buf, maxSize, now, s.version) + p, err := c.packer.AppendPacket(buf, maxSize, now, c.version) if err != nil { return 0, err } size := buf.Len() - startLen - s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, size, false) - s.registerPackedShortHeaderPacket(p, ecn, now) + c.logShortHeaderPacket(p, ecn, size) + c.registerPackedShortHeaderPacket(p, ecn, now) return size, nil } -func (s *connection) registerPackedShortHeaderPacket(p shortHeaderPacket, ecn protocol.ECN, now time.Time) { +func (c *Conn) registerPackedShortHeaderPacket(p shortHeaderPacket, ecn protocol.ECN, now monotime.Time) { if p.IsPathProbePacket { - s.sentPacketHandler.SentPacket( + c.sentPacketHandler.SentPacket( now, p.PacketNumber, protocol.InvalidPacketNumber, @@ -2384,15 +2771,15 @@ func (s *connection) registerPackedShortHeaderPacket(p shortHeaderPacket, ecn pr ) return } - if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && (len(p.StreamFrames) > 0 || ackhandler.HasAckElicitingFrames(p.Frames)) { - s.firstAckElicitingPacketAfterIdleSentTime = now + if c.firstAckElicitingPacketAfterIdleSentTime.IsZero() && (len(p.StreamFrames) > 0 || ackhandler.HasAckElicitingFrames(p.Frames)) { + c.firstAckElicitingPacketAfterIdleSentTime = now } largestAcked := protocol.InvalidPacketNumber if p.Ack != nil { largestAcked = p.Ack.LargestAcked() } - s.sentPacketHandler.SentPacket( + c.sentPacketHandler.SentPacket( now, p.PacketNumber, largestAcked, @@ -2404,20 +2791,20 @@ func (s *connection) registerPackedShortHeaderPacket(p shortHeaderPacket, ecn pr p.IsPathMTUProbePacket, false, ) - s.connIDManager.SentPacket() + c.connIDManager.SentPacket() } -func (s *connection) sendPackedCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN, now time.Time) error { - s.logCoalescedPacket(packet, ecn) +func (c *Conn) sendPackedCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN, now monotime.Time) error { + c.logCoalescedPacket(packet, ecn) for _, p := range packet.longHdrPackets { - if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() { - s.firstAckElicitingPacketAfterIdleSentTime = now + if c.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() { + c.firstAckElicitingPacketAfterIdleSentTime = now } largestAcked := protocol.InvalidPacketNumber if p.ack != nil { largestAcked = p.ack.LargestAcked() } - s.sentPacketHandler.SentPacket( + c.sentPacketHandler.SentPacket( now, p.header.PacketNumber, largestAcked, @@ -2429,24 +2816,24 @@ func (s *connection) sendPackedCoalescedPacket(packet *coalescedPacket, ecn prot false, false, ) - if s.perspective == protocol.PerspectiveClient && p.EncryptionLevel() == protocol.EncryptionHandshake && - !s.droppedInitialKeys { + if c.perspective == protocol.PerspectiveClient && p.EncryptionLevel() == protocol.EncryptionHandshake && + !c.droppedInitialKeys { // On the client side, Initial keys are dropped as soon as the first Handshake packet is sent. // See Section 4.9.1 of RFC 9001. - if err := s.dropEncryptionLevel(protocol.EncryptionInitial, now); err != nil { + if err := c.dropEncryptionLevel(protocol.EncryptionInitial, now); err != nil { return err } } } if p := packet.shortHdrPacket; p != nil { - if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() { - s.firstAckElicitingPacketAfterIdleSentTime = now + if c.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() { + c.firstAckElicitingPacketAfterIdleSentTime = now } largestAcked := protocol.InvalidPacketNumber if p.Ack != nil { largestAcked = p.Ack.LargestAcked() } - s.sentPacketHandler.SentPacket( + c.sentPacketHandler.SentPacket( now, p.PacketNumber, largestAcked, @@ -2459,41 +2846,41 @@ func (s *connection) sendPackedCoalescedPacket(packet *coalescedPacket, ecn prot false, ) } - s.connIDManager.SentPacket() - s.sendQueue.Send(packet.buffer, 0, ecn) + c.connIDManager.SentPacket() + c.sendQueue.Send(packet.buffer, 0, ecn) return nil } -func (s *connection) sendConnectionClose(e error) ([]byte, error) { +func (c *Conn) sendConnectionClose(e error) ([]byte, error) { var packet *coalescedPacket var err error var transportErr *qerr.TransportError var applicationErr *qerr.ApplicationError if errors.As(e, &transportErr) { - packet, err = s.packer.PackConnectionClose(transportErr, s.maxPacketSize(), s.version) + packet, err = c.packer.PackConnectionClose(transportErr, c.maxPacketSize(), c.version) } else if errors.As(e, &applicationErr) { - packet, err = s.packer.PackApplicationClose(applicationErr, s.maxPacketSize(), s.version) + packet, err = c.packer.PackApplicationClose(applicationErr, c.maxPacketSize(), c.version) } else { - packet, err = s.packer.PackConnectionClose(&qerr.TransportError{ + packet, err = c.packer.PackConnectionClose(&qerr.TransportError{ ErrorCode: qerr.InternalError, ErrorMessage: fmt.Sprintf("connection BUG: unspecified error type (msg: %s)", e.Error()), - }, s.maxPacketSize(), s.version) + }, c.maxPacketSize(), c.version) } if err != nil { return nil, err } - ecn := s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()) - s.logCoalescedPacket(packet, ecn) - return packet.buffer.Data, s.conn.Write(packet.buffer.Data, 0, ecn) + ecn := c.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()) + c.logCoalescedPacket(packet, ecn) + return packet.buffer.Data, c.conn.Write(packet.buffer.Data, 0, ecn) } -func (s *connection) maxPacketSize() protocol.ByteCount { - if s.mtuDiscoverer == nil { +func (c *Conn) maxPacketSize() protocol.ByteCount { + if c.mtuDiscoverer == nil { // Use the configured packet size on the client side. // If the server sends a max_udp_payload_size that's smaller than this size, we can ignore this: // Apparently the server still processed the (fully padded) Initial packet anyway. - if s.perspective == protocol.PerspectiveClient { - return protocol.ByteCount(s.config.InitialPacketSize) + if c.perspective == protocol.PerspectiveClient { + return protocol.ByteCount(c.config.InitialPacketSize) } // On the server side, there's no downside to using 1200 bytes until we received the client's transport // parameters: @@ -2502,109 +2889,152 @@ func (s *connection) maxPacketSize() protocol.ByteCount { // * If it did, we will have processed the transport parameters and initialized the MTU discoverer. return protocol.MinInitialPacketSize } - return s.mtuDiscoverer.CurrentSize() + return c.mtuDiscoverer.CurrentSize() } -// AcceptStream returns the next stream openend by the peer -func (s *connection) AcceptStream(ctx context.Context) (Stream, error) { - return s.streamsMap.AcceptStream(ctx) +// AcceptStream returns the next stream opened by the peer, blocking until one is available. +func (c *Conn) AcceptStream(ctx context.Context) (*Stream, error) { + return c.streamsMap.AcceptStream(ctx) } -func (s *connection) AcceptUniStream(ctx context.Context) (ReceiveStream, error) { - return s.streamsMap.AcceptUniStream(ctx) +// AcceptUniStream returns the next unidirectional stream opened by the peer, blocking until one is available. +func (c *Conn) AcceptUniStream(ctx context.Context) (*ReceiveStream, error) { + return c.streamsMap.AcceptUniStream(ctx) } -// OpenStream opens a stream -func (s *connection) OpenStream() (Stream, error) { - return s.streamsMap.OpenStream() +// OpenStream opens a new bidirectional QUIC stream. +// There is no signaling to the peer about new streams: +// The peer can only accept the stream after data has been sent on the stream, +// or the stream has been reset or closed. +// When reaching the peer's stream limit, it is not possible to open a new stream until the +// peer raises the stream limit. In that case, a [StreamLimitReachedError] is returned. +func (c *Conn) OpenStream() (*Stream, error) { + return c.streamsMap.OpenStream() } -func (s *connection) OpenStreamSync(ctx context.Context) (Stream, error) { - return s.streamsMap.OpenStreamSync(ctx) +// OpenStreamSync opens a new bidirectional QUIC stream. +// It blocks until a new stream can be opened. +// There is no signaling to the peer about new streams: +// The peer can only accept the stream after data has been sent on the stream, +// or the stream has been reset or closed. +func (c *Conn) OpenStreamSync(ctx context.Context) (*Stream, error) { + return c.streamsMap.OpenStreamSync(ctx) } -func (s *connection) OpenUniStream() (SendStream, error) { - return s.streamsMap.OpenUniStream() +// OpenUniStream opens a new outgoing unidirectional QUIC stream. +// There is no signaling to the peer about new streams: +// The peer can only accept the stream after data has been sent on the stream, +// or the stream has been reset or closed. +// When reaching the peer's stream limit, it is not possible to open a new stream until the +// peer raises the stream limit. In that case, a [StreamLimitReachedError] is returned. +func (c *Conn) OpenUniStream() (*SendStream, error) { + return c.streamsMap.OpenUniStream() } -func (s *connection) OpenUniStreamSync(ctx context.Context) (SendStream, error) { - return s.streamsMap.OpenUniStreamSync(ctx) +// OpenUniStreamSync opens a new outgoing unidirectional QUIC stream. +// It blocks until a new stream can be opened. +// There is no signaling to the peer about new streams: +// The peer can only accept the stream after data has been sent on the stream, +// or the stream has been reset or closed. +func (c *Conn) OpenUniStreamSync(ctx context.Context) (*SendStream, error) { + return c.streamsMap.OpenUniStreamSync(ctx) } -func (s *connection) newFlowController(id protocol.StreamID) flowcontrol.StreamFlowController { - initialSendWindow := s.peerParams.InitialMaxStreamDataUni +func (c *Conn) newFlowController(id protocol.StreamID) flowcontrol.StreamFlowController { + initialSendWindow := c.peerParams.InitialMaxStreamDataUni if id.Type() == protocol.StreamTypeBidi { - if id.InitiatedBy() == s.perspective { - initialSendWindow = s.peerParams.InitialMaxStreamDataBidiRemote + if id.InitiatedBy() == c.perspective { + initialSendWindow = c.peerParams.InitialMaxStreamDataBidiRemote } else { - initialSendWindow = s.peerParams.InitialMaxStreamDataBidiLocal + initialSendWindow = c.peerParams.InitialMaxStreamDataBidiLocal } } return flowcontrol.NewStreamFlowController( id, - s.connFlowController, - protocol.ByteCount(s.config.InitialStreamReceiveWindow), - protocol.ByteCount(s.config.MaxStreamReceiveWindow), + c.connFlowController, + protocol.ByteCount(c.config.InitialStreamReceiveWindow), + protocol.ByteCount(c.config.MaxStreamReceiveWindow), initialSendWindow, - s.rttStats, - s.logger, + c.rttStats, + c.logger, ) } // scheduleSending signals that we have data for sending -func (s *connection) scheduleSending() { +func (c *Conn) scheduleSending() { select { - case s.sendingScheduled <- struct{}{}: + case c.sendingScheduled <- struct{}{}: default: } } // tryQueueingUndecryptablePacket queues a packet for which we're missing the decryption keys. -// The logging.PacketType is only used for logging purposes. -func (s *connection) tryQueueingUndecryptablePacket(p receivedPacket, pt logging.PacketType) { - if s.handshakeComplete { +// The qlogevents.PacketType is only used for logging purposes. +func (c *Conn) tryQueueingUndecryptablePacket(p receivedPacket, pt qlog.PacketType, datagramID qlog.DatagramID) { + if c.handshakeComplete { panic("shouldn't queue undecryptable packets after handshake completion") } - if len(s.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropDOSPrevention) + if len(c.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets { + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: pt, + PacketNumber: protocol.InvalidPacketNumber, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + DatagramID: datagramID, + Trigger: qlog.PacketDropDOSPrevention, + }) } - s.logger.Infof("Dropping undecryptable packet (%d bytes). Undecryptable packet queue full.", p.Size()) + c.logger.Infof("Dropping undecryptable packet (%d bytes). Undecryptable packet queue full.", p.Size()) return } - s.logger.Infof("Queueing packet (%d bytes) for later decryption", p.Size()) - if s.tracer != nil && s.tracer.BufferedPacket != nil { - s.tracer.BufferedPacket(pt, p.Size()) + c.logger.Infof("Queueing packet (%d bytes) for later decryption", p.Size()) + if c.qlogger != nil { + c.qlogger.RecordEvent(qlog.PacketBuffered{ + Header: qlog.PacketHeader{ + PacketType: pt, + PacketNumber: protocol.InvalidPacketNumber, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + DatagramID: datagramID, + }) } - s.undecryptablePackets = append(s.undecryptablePackets, p) + c.undecryptablePackets = append(c.undecryptablePackets, receivedPacketWithDatagramID{receivedPacket: p, datagramID: datagramID}) } -func (s *connection) queueControlFrame(f wire.Frame) { - s.framer.QueueControlFrame(f) - s.scheduleSending() +func (c *Conn) queueControlFrame(f wire.Frame) { + c.framer.QueueControlFrame(f) + c.scheduleSending() } -func (s *connection) onHasConnectionData() { s.scheduleSending() } +func (c *Conn) onHasConnectionData() { c.scheduleSending() } -func (s *connection) onHasStreamData(id protocol.StreamID, str sendStreamI) { - s.framer.AddActiveStream(id, str) - s.scheduleSending() +func (c *Conn) onHasStreamData(id protocol.StreamID, str *SendStream) { + c.framer.AddActiveStream(id, str) + c.scheduleSending() } -func (s *connection) onHasStreamControlFrame(id protocol.StreamID, str streamControlFrameGetter) { - s.framer.AddStreamWithControlFrames(id, str) - s.scheduleSending() +func (c *Conn) onHasStreamControlFrame(id protocol.StreamID, str streamControlFrameGetter) { + c.framer.AddStreamWithControlFrames(id, str) + c.scheduleSending() } -func (s *connection) onStreamCompleted(id protocol.StreamID) { - if err := s.streamsMap.DeleteStream(id); err != nil { - s.closeLocal(err) +func (c *Conn) onStreamCompleted(id protocol.StreamID) { + if err := c.streamsMap.DeleteStream(id); err != nil { + c.closeLocal(err) } - s.framer.RemoveActiveStream(id) + c.framer.RemoveActiveStream(id) } -func (s *connection) SendDatagram(p []byte) error { - if !s.supportsDatagrams() { +// SendDatagram sends a message using a QUIC datagram, as specified in RFC 9221, +// if the peer enabled datagram support. +// There is no delivery guarantee for DATAGRAM frames, they are not retransmitted if lost. +// The payload of the datagram needs to fit into a single QUIC packet. +// In addition, a datagram may be dropped before being sent out if the available packet size suddenly decreases. +// If the payload is too large to be sent at the current time, a DatagramTooLargeError is returned. +func (c *Conn) SendDatagram(p []byte) error { + if !c.supportsDatagrams() { return errors.New("datagram support disabled") } @@ -2612,61 +3042,74 @@ func (s *connection) SendDatagram(p []byte) error { // The payload size estimate is conservative. // Under many circumstances we could send a few more bytes. maxDataLen := min( - f.MaxDataLen(s.peerParams.MaxDatagramFrameSize, s.version), - protocol.ByteCount(s.currentMTUEstimate.Load()), + f.MaxDataLen(c.peerParams.MaxDatagramFrameSize, c.version), + protocol.ByteCount(c.currentMTUEstimate.Load()), ) if protocol.ByteCount(len(p)) > maxDataLen { return &DatagramTooLargeError{MaxDatagramPayloadSize: int64(maxDataLen)} } f.Data = make([]byte, len(p)) copy(f.Data, p) - return s.datagramQueue.Add(f) + return c.datagramQueue.Add(f) } -func (s *connection) ReceiveDatagram(ctx context.Context) ([]byte, error) { - if !s.config.EnableDatagrams { +// ReceiveDatagram gets a message received in a QUIC datagram, as specified in RFC 9221. +func (c *Conn) ReceiveDatagram(ctx context.Context) ([]byte, error) { + if !c.config.EnableDatagrams { return nil, errors.New("datagram support disabled") } - return s.datagramQueue.Receive(ctx) + return c.datagramQueue.Receive(ctx) } -func (s *connection) LocalAddr() net.Addr { return s.conn.LocalAddr() } -func (s *connection) RemoteAddr() net.Addr { return s.conn.RemoteAddr() } +// LocalAddr returns the local address of the QUIC connection. +func (c *Conn) LocalAddr() net.Addr { return c.conn.LocalAddr() } -func (s *connection) getPathManager() *pathManagerOutgoing { - s.pathManagerOutgoing.CompareAndSwap(nil, - func() *pathManagerOutgoing { // this function is only called if a swap is performed - return newPathManagerOutgoing( - s.connIDManager.GetConnIDForPath, - s.connIDManager.RetireConnIDForPath, - s.scheduleSending, - ) - }(), +// RemoteAddr returns the remote address of the QUIC connection. +func (c *Conn) RemoteAddr() net.Addr { return c.conn.RemoteAddr() } + +// getPathManager lazily initializes the Conn's pathManagerOutgoing. +// May create multiple pathManagerOutgoing objects if called concurrently. +func (c *Conn) getPathManager() *pathManagerOutgoing { + old := c.pathManagerOutgoing.Load() + if old != nil { + // Path manager is already initialized + return old + } + + // Initialize the path manager + new := newPathManagerOutgoing( + c.connIDManager.GetConnIDForPath, + c.connIDManager.RetireConnIDForPath, + c.scheduleSending, ) - return s.pathManagerOutgoing.Load() + if c.pathManagerOutgoing.CompareAndSwap(old, new) { + return new + } + + // Swap failed. A concurrent writer wrote first, use their value. + return c.pathManagerOutgoing.Load() } -func (s *connection) AddPath(t *Transport) (*Path, error) { - if s.perspective == protocol.PerspectiveServer { +func (c *Conn) AddPath(t *Transport) (*Path, error) { + if c.perspective == protocol.PerspectiveServer { return nil, errors.New("server cannot initiate connection migration") } - if s.peerParams.DisableActiveMigration { + if c.peerParams.DisableActiveMigration { return nil, errors.New("server disabled connection migration") } if err := t.init(false); err != nil { return nil, err } - return s.getPathManager().NewPath( + return c.getPathManager().NewPath( t, 200*time.Millisecond, // initial RTT estimate func() { - runner := t.connRunner() - s.connIDGenerator.AddConnRunner( - t.id(), + runner := (*packetHandlerMap)(t) + c.connIDGenerator.AddConnRunner( + runner, connRunnerCallbacks{ - AddConnectionID: func(connID protocol.ConnectionID) { runner.Add(connID, s) }, + AddConnectionID: func(connID protocol.ConnectionID) { runner.Add(connID, c) }, RemoveConnectionID: runner.Remove, - RetireConnectionID: runner.Retire, ReplaceWithClosed: runner.ReplaceWithClosed, }, ) @@ -2674,17 +3117,38 @@ func (s *connection) AddPath(t *Transport) (*Path, error) { ), nil } -func (s *connection) NextConnection(ctx context.Context) (Connection, error) { +// HandshakeComplete blocks until the handshake completes (or fails). +// For the client, data sent before completion of the handshake is encrypted with 0-RTT keys. +// For the server, data sent before completion of the handshake is encrypted with 1-RTT keys, +// however the client's identity is only verified once the handshake completes. +func (c *Conn) HandshakeComplete() <-chan struct{} { + return c.handshakeCompleteChan +} + +// QlogTrace returns the qlog trace of the QUIC connection. +// It is nil if qlog is not enabled. +func (c *Conn) QlogTrace() qlogwriter.Trace { + return c.qlogTrace +} + +// NextConnection transitions a connection to be usable after a 0-RTT rejection. +// It waits for the handshake to complete and then enables the connection for normal use. +// This should be called when the server rejects 0-RTT and the application receives +// [Err0RTTRejected] errors. +// +// Note that 0-RTT rejection invalidates all data sent in 0-RTT packets. It is the +// application's responsibility to handle this (for example by resending the data). +func (c *Conn) NextConnection(ctx context.Context) (*Conn, error) { // The handshake might fail after the server rejected 0-RTT. // This could happen if the Finished message is malformed or never received. select { case <-ctx.Done(): return nil, context.Cause(ctx) - case <-s.Context().Done(): - case <-s.HandshakeComplete(): - s.streamsMap.UseResetMaps() + case <-c.Context().Done(): + case <-c.HandshakeComplete(): + c.streamsMap.UseResetMaps() } - return s, nil + return c, nil } // estimateMaxPayloadSize estimates the maximum payload size for short header packets. diff --git a/vendor/github.com/quic-go/quic-go/connection_logging.go b/vendor/github.com/quic-go/quic-go/connection_logging.go index a314a6cd..c828c8be 100644 --- a/vendor/github.com/quic-go/quic-go/connection_logging.go +++ b/vendor/github.com/quic-go/quic-go/connection_logging.go @@ -1,46 +1,53 @@ package quic import ( + "net" + "net/netip" "slices" - "github.com/quic-go/quic-go/internal/ackhandler" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/wire" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" ) // ConvertFrame converts a wire.Frame into a logging.Frame. // This makes it possible for external packages to access the frames. // Furthermore, it removes the data slices from CRYPTO and STREAM frames. -func toLoggingFrame(frame wire.Frame) logging.Frame { +func toQlogFrame(frame wire.Frame) qlog.Frame { switch f := frame.(type) { case *wire.AckFrame: // We use a pool for ACK frames. // Implementations of the tracer interface may hold on to frames, so we need to make a copy here. - return toLoggingAckFrame(f) + return qlog.Frame{Frame: toQlogAckFrame(f)} case *wire.CryptoFrame: - return &logging.CryptoFrame{ - Offset: f.Offset, - Length: protocol.ByteCount(len(f.Data)), + return qlog.Frame{ + Frame: &qlog.CryptoFrame{ + Offset: int64(f.Offset), + Length: int64(len(f.Data)), + }, } case *wire.StreamFrame: - return &logging.StreamFrame{ - StreamID: f.StreamID, - Offset: f.Offset, - Length: f.DataLen(), - Fin: f.Fin, + return qlog.Frame{ + Frame: &qlog.StreamFrame{ + StreamID: f.StreamID, + Offset: int64(f.Offset), + Length: int64(f.DataLen()), + Fin: f.Fin, + }, } case *wire.DatagramFrame: - return &logging.DatagramFrame{ - Length: logging.ByteCount(len(f.Data)), + return qlog.Frame{ + Frame: &qlog.DatagramFrame{ + Length: int64(len(f.Data)), + }, } default: - return logging.Frame(frame) + return qlog.Frame{Frame: frame} } } -func toLoggingAckFrame(f *wire.AckFrame) *logging.AckFrame { - ack := &logging.AckFrame{ +func toQlogAckFrame(f *wire.AckFrame) *qlog.AckFrame { + ack := &qlog.AckFrame{ AckRanges: slices.Clone(f.AckRanges), DelayTime: f.DelayTime, ECNCE: f.ECNCE, @@ -50,119 +57,259 @@ func toLoggingAckFrame(f *wire.AckFrame) *logging.AckFrame { return ack } -func (s *connection) logLongHeaderPacket(p *longHeaderPacket, ecn protocol.ECN) { +func (c *Conn) logLongHeaderPacket(p *longHeaderPacket, ecn protocol.ECN, datagramID qlog.DatagramID) { // quic-go logging - if s.logger.Debug() { - p.header.Log(s.logger) + if c.logger.Debug() { + p.header.Log(c.logger) if p.ack != nil { - wire.LogFrame(s.logger, p.ack, true) + wire.LogFrame(c.logger, p.ack, true) } for _, frame := range p.frames { - wire.LogFrame(s.logger, frame.Frame, true) + wire.LogFrame(c.logger, frame.Frame, true) } for _, frame := range p.streamFrames { - wire.LogFrame(s.logger, frame.Frame, true) + wire.LogFrame(c.logger, frame.Frame, true) } } // tracing - if s.tracer != nil && s.tracer.SentLongHeaderPacket != nil { - frames := make([]logging.Frame, 0, len(p.frames)) + if c.qlogger != nil { + numFrames := len(p.frames) + len(p.streamFrames) + if p.ack != nil { + numFrames++ + } + frames := make([]qlog.Frame, 0, numFrames) + if p.ack != nil { + frames = append(frames, toQlogFrame(p.ack)) + } for _, f := range p.frames { - frames = append(frames, toLoggingFrame(f.Frame)) + frames = append(frames, toQlogFrame(f.Frame)) } for _, f := range p.streamFrames { - frames = append(frames, toLoggingFrame(f.Frame)) + frames = append(frames, toQlogFrame(f.Frame)) } - var ack *logging.AckFrame - if p.ack != nil { - ack = toLoggingAckFrame(p.ack) - } - s.tracer.SentLongHeaderPacket(p.header, p.length, ecn, ack, frames) + c.qlogger.RecordEvent(qlog.PacketSent{ + Header: qlog.PacketHeader{ + PacketType: toQlogPacketType(p.header.Type), + KeyPhaseBit: p.header.KeyPhase, + PacketNumber: p.header.PacketNumber, + Version: p.header.Version, + SrcConnectionID: p.header.SrcConnectionID, + DestConnectionID: p.header.DestConnectionID, + }, + Raw: qlog.RawInfo{ + Length: int(p.length), + PayloadLength: int(p.header.Length), + }, + DatagramID: datagramID, + Frames: frames, + ECN: toQlogECN(ecn), + }) } } -func (s *connection) logShortHeaderPacket( - destConnID protocol.ConnectionID, - ackFrame *wire.AckFrame, - frames []ackhandler.Frame, - streamFrames []ackhandler.StreamFrame, - pn protocol.PacketNumber, - pnLen protocol.PacketNumberLen, - kp protocol.KeyPhaseBit, - ecn protocol.ECN, - size protocol.ByteCount, - isCoalesced bool, -) { - if s.logger.Debug() && !isCoalesced { - s.logger.Debugf("-> Sending packet %d (%d bytes) for connection %s, 1-RTT (ECN: %s)", pn, size, s.logID, ecn) +func (c *Conn) logShortHeaderPacket(p shortHeaderPacket, ecn protocol.ECN, size protocol.ByteCount) { + c.logShortHeaderPacketWithDatagramID(p, ecn, size, false, 0) +} + +func (c *Conn) logShortHeaderPacketWithDatagramID(p shortHeaderPacket, ecn protocol.ECN, size protocol.ByteCount, isCoalesced bool, datagramID qlog.DatagramID) { + if c.logger.Debug() && !isCoalesced { + c.logger.Debugf("-> Sending packet %d (%d bytes) for connection %s, 1-RTT (ECN: %s)", p.PacketNumber, size, c.logID, ecn) } // quic-go logging - if s.logger.Debug() { - wire.LogShortHeader(s.logger, destConnID, pn, pnLen, kp) - if ackFrame != nil { - wire.LogFrame(s.logger, ackFrame, true) + if c.logger.Debug() { + wire.LogShortHeader(c.logger, p.DestConnID, p.PacketNumber, p.PacketNumberLen, p.KeyPhase) + if p.Ack != nil { + wire.LogFrame(c.logger, p.Ack, true) } - for _, f := range frames { - wire.LogFrame(s.logger, f.Frame, true) + for _, f := range p.Frames { + wire.LogFrame(c.logger, f.Frame, true) } - for _, f := range streamFrames { - wire.LogFrame(s.logger, f.Frame, true) + for _, f := range p.StreamFrames { + wire.LogFrame(c.logger, f.Frame, true) } } // tracing - if s.tracer != nil && s.tracer.SentShortHeaderPacket != nil { - fs := make([]logging.Frame, 0, len(frames)+len(streamFrames)) - for _, f := range frames { - fs = append(fs, toLoggingFrame(f.Frame)) + if c.qlogger != nil { + numFrames := len(p.Frames) + len(p.StreamFrames) + if p.Ack != nil { + numFrames++ } - for _, f := range streamFrames { - fs = append(fs, toLoggingFrame(f.Frame)) + fs := make([]qlog.Frame, 0, numFrames) + if p.Ack != nil { + fs = append(fs, toQlogFrame(p.Ack)) } - var ack *logging.AckFrame - if ackFrame != nil { - ack = toLoggingAckFrame(ackFrame) + for _, f := range p.Frames { + fs = append(fs, toQlogFrame(f.Frame)) } - s.tracer.SentShortHeaderPacket( - &logging.ShortHeader{DestConnectionID: destConnID, PacketNumber: pn, PacketNumberLen: pnLen, KeyPhase: kp}, - size, - ecn, - ack, - fs, - ) + for _, f := range p.StreamFrames { + fs = append(fs, toQlogFrame(f.Frame)) + } + c.qlogger.RecordEvent(qlog.PacketSent{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketType1RTT, + KeyPhaseBit: p.KeyPhase, + PacketNumber: p.PacketNumber, + Version: c.version, + DestConnectionID: p.DestConnID, + }, + Raw: qlog.RawInfo{ + Length: int(size), + PayloadLength: int(size - wire.ShortHeaderLen(p.DestConnID, p.PacketNumberLen)), + }, + DatagramID: datagramID, + Frames: fs, + ECN: toQlogECN(ecn), + }) } } -func (s *connection) logCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN) { - if s.logger.Debug() { +func (c *Conn) logCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN) { + var datagramID qlog.DatagramID + if c.qlogger != nil { + datagramID = qlog.CalculateDatagramID(packet.buffer.Data) + } + if c.logger.Debug() { // There's a short period between dropping both Initial and Handshake keys and completion of the handshake, // during which we might call PackCoalescedPacket but just pack a short header packet. if len(packet.longHdrPackets) == 0 && packet.shortHdrPacket != nil { - s.logShortHeaderPacket( - packet.shortHdrPacket.DestConnID, - packet.shortHdrPacket.Ack, - packet.shortHdrPacket.Frames, - packet.shortHdrPacket.StreamFrames, - packet.shortHdrPacket.PacketNumber, - packet.shortHdrPacket.PacketNumberLen, - packet.shortHdrPacket.KeyPhase, + c.logShortHeaderPacketWithDatagramID( + *packet.shortHdrPacket, ecn, packet.shortHdrPacket.Length, false, + datagramID, ) return } if len(packet.longHdrPackets) > 1 { - s.logger.Debugf("-> Sending coalesced packet (%d parts, %d bytes) for connection %s", len(packet.longHdrPackets), packet.buffer.Len(), s.logID) + c.logger.Debugf("-> Sending coalesced packet (%d parts, %d bytes) for connection %s", len(packet.longHdrPackets), packet.buffer.Len(), c.logID) } else { - s.logger.Debugf("-> Sending packet %d (%d bytes) for connection %s, %s", packet.longHdrPackets[0].header.PacketNumber, packet.buffer.Len(), s.logID, packet.longHdrPackets[0].EncryptionLevel()) + c.logger.Debugf("-> Sending packet %d (%d bytes) for connection %s, %s", packet.longHdrPackets[0].header.PacketNumber, packet.buffer.Len(), c.logID, packet.longHdrPackets[0].EncryptionLevel()) } } for _, p := range packet.longHdrPackets { - s.logLongHeaderPacket(p, ecn) + c.logLongHeaderPacket(p, ecn, datagramID) } if p := packet.shortHdrPacket; p != nil { - s.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, p.Length, true) + c.logShortHeaderPacketWithDatagramID(*p, ecn, p.Length, true, datagramID) } } + +func (c *Conn) qlogTransportParameters(tp *wire.TransportParameters, sentBy protocol.Perspective, restore bool) { + ev := qlog.ParametersSet{ + Restore: restore, + OriginalDestinationConnectionID: tp.OriginalDestinationConnectionID, + InitialSourceConnectionID: tp.InitialSourceConnectionID, + RetrySourceConnectionID: tp.RetrySourceConnectionID, + StatelessResetToken: tp.StatelessResetToken, + DisableActiveMigration: tp.DisableActiveMigration, + MaxIdleTimeout: tp.MaxIdleTimeout, + MaxUDPPayloadSize: tp.MaxUDPPayloadSize, + AckDelayExponent: tp.AckDelayExponent, + MaxAckDelay: tp.MaxAckDelay, + ActiveConnectionIDLimit: tp.ActiveConnectionIDLimit, + InitialMaxData: tp.InitialMaxData, + InitialMaxStreamDataBidiLocal: tp.InitialMaxStreamDataBidiLocal, + InitialMaxStreamDataBidiRemote: tp.InitialMaxStreamDataBidiRemote, + InitialMaxStreamDataUni: tp.InitialMaxStreamDataUni, + InitialMaxStreamsBidi: int64(tp.MaxBidiStreamNum), + InitialMaxStreamsUni: int64(tp.MaxUniStreamNum), + MaxDatagramFrameSize: tp.MaxDatagramFrameSize, + EnableResetStreamAt: tp.EnableResetStreamAt, + } + if sentBy == c.perspective { + ev.Initiator = qlog.InitiatorLocal + } else { + ev.Initiator = qlog.InitiatorRemote + } + if tp.PreferredAddress != nil { + ev.PreferredAddress = &qlog.PreferredAddress{ + IPv4: tp.PreferredAddress.IPv4, + IPv6: tp.PreferredAddress.IPv6, + ConnectionID: tp.PreferredAddress.ConnectionID, + StatelessResetToken: tp.PreferredAddress.StatelessResetToken, + } + } + c.qlogger.RecordEvent(ev) +} + +func toQlogECN(ecn protocol.ECN) qlog.ECN { + //nolint:exhaustive // only need to handle the 3 valid values + switch ecn { + case protocol.ECT0: + return qlog.ECT0 + case protocol.ECT1: + return qlog.ECT1 + case protocol.ECNCE: + return qlog.ECNCE + default: + return qlog.ECNUnsupported + } +} + +func toQlogPacketType(pt protocol.PacketType) qlog.PacketType { + var qpt qlog.PacketType + switch pt { + case protocol.PacketTypeInitial: + qpt = qlog.PacketTypeInitial + case protocol.PacketTypeHandshake: + qpt = qlog.PacketTypeHandshake + case protocol.PacketType0RTT: + qpt = qlog.PacketType0RTT + case protocol.PacketTypeRetry: + qpt = qlog.PacketTypeRetry + } + return qpt +} + +func toPathEndpointInfo(addr *net.UDPAddr) qlog.PathEndpointInfo { + if addr == nil { + return qlog.PathEndpointInfo{} + } + + var info qlog.PathEndpointInfo + if addr.IP == nil || addr.IP.To4() != nil { + addrPort := netip.AddrPortFrom(netip.AddrFrom4([4]byte(addr.IP.To4())), uint16(addr.Port)) + if addrPort.IsValid() { + info.IPv4 = addrPort + } + } else { + addrPort := netip.AddrPortFrom(netip.AddrFrom16([16]byte(addr.IP.To16())), uint16(addr.Port)) + if addrPort.IsValid() { + info.IPv6 = addrPort + } + } + return info +} + +// startedConnectionEvent builds a StartedConnection event using consistent logic +// for both endpoints. If the local address is unspecified (e.g., dual-stack +// listener), it selects the family based on the remote address and uses the +// unspecified address of that family with the local port. +func startedConnectionEvent(local, remote *net.UDPAddr) qlog.StartedConnection { + var localInfo, remoteInfo qlog.PathEndpointInfo + if remote != nil { + remoteInfo = toPathEndpointInfo(remote) + } + if local != nil { + if local.IP == nil || local.IP.IsUnspecified() { + // Choose local family based on the remote address family. + if remote != nil && remote.IP.To4() != nil { + ap := netip.AddrPortFrom(netip.AddrFrom4([4]byte{}), uint16(local.Port)) + if ap.IsValid() { + localInfo.IPv4 = ap + } + } else if remote != nil && remote.IP.To16() != nil && remote.IP.To4() == nil { + ap := netip.AddrPortFrom(netip.AddrFrom16([16]byte{}), uint16(local.Port)) + if ap.IsValid() { + localInfo.IPv6 = ap + } + } + } else { + localInfo = toPathEndpointInfo(local) + } + } + return qlog.StartedConnection{Local: localInfo, Remote: remoteInfo} +} diff --git a/vendor/github.com/quic-go/quic-go/connection_timer.go b/vendor/github.com/quic-go/quic-go/connection_timer.go deleted file mode 100644 index 171fdd01..00000000 --- a/vendor/github.com/quic-go/quic-go/connection_timer.go +++ /dev/null @@ -1,51 +0,0 @@ -package quic - -import ( - "time" - - "github.com/quic-go/quic-go/internal/utils" -) - -var deadlineSendImmediately = time.Time{}.Add(42 * time.Millisecond) // any value > time.Time{} and before time.Now() is fine - -type connectionTimer struct { - timer *utils.Timer - last time.Time -} - -func newTimer() *connectionTimer { - return &connectionTimer{timer: utils.NewTimer()} -} - -func (t *connectionTimer) SetRead() { - if deadline := t.timer.Deadline(); deadline != deadlineSendImmediately { - t.last = deadline - } - t.timer.SetRead() -} - -func (t *connectionTimer) Chan() <-chan time.Time { - return t.timer.Chan() -} - -// SetTimer resets the timer. -// It makes sure that the deadline is strictly increasing. -// This prevents busy-looping in cases where the timer fires, but we can't actually send out a packet. -// This doesn't apply to the pacing deadline, which can be set multiple times to deadlineSendImmediately. -func (t *connectionTimer) SetTimer(idleTimeoutOrKeepAlive, ackAlarm, lossTime, pacing time.Time) { - deadline := idleTimeoutOrKeepAlive - if !ackAlarm.IsZero() && ackAlarm.Before(deadline) && ackAlarm.After(t.last) { - deadline = ackAlarm - } - if !lossTime.IsZero() && lossTime.Before(deadline) && lossTime.After(t.last) { - deadline = lossTime - } - if !pacing.IsZero() && pacing.Before(deadline) { - deadline = pacing - } - t.timer.Reset(deadline) -} - -func (t *connectionTimer) Stop() { - t.timer.Stop() -} diff --git a/vendor/github.com/quic-go/quic-go/crypto_stream.go b/vendor/github.com/quic-go/quic-go/crypto_stream.go index 9a387baa..6d39aa09 100644 --- a/vendor/github.com/quic-go/quic-go/crypto_stream.go +++ b/vendor/github.com/quic-go/quic-go/crypto_stream.go @@ -1,14 +1,23 @@ package quic import ( + "errors" "fmt" + "io" + "os" + "slices" + "strconv" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/wire" ) -type cryptoStream struct { +const disableClientHelloScramblingEnv = "QUIC_GO_DISABLE_CLIENTHELLO_SCRAMBLING" + +// The baseCryptoStream is used by the cryptoStream and the initialCryptoStream. +// This allows us to implement different logic for PopCryptoFrame for the two streams. +type baseCryptoStream struct { queue frameSorter highestOffset protocol.ByteCount @@ -19,10 +28,10 @@ type cryptoStream struct { } func newCryptoStream() *cryptoStream { - return &cryptoStream{queue: *newFrameSorter()} + return &cryptoStream{baseCryptoStream{queue: *newFrameSorter()}} } -func (s *cryptoStream) HandleCryptoFrame(f *wire.CryptoFrame) error { +func (s *baseCryptoStream) HandleCryptoFrame(f *wire.CryptoFrame) error { highestOffset := f.Offset + protocol.ByteCount(len(f.Data)) if maxOffset := highestOffset; maxOffset > protocol.MaxCryptoStreamOffset { return &qerr.TransportError{ @@ -47,12 +56,12 @@ func (s *cryptoStream) HandleCryptoFrame(f *wire.CryptoFrame) error { } // GetCryptoData retrieves data that was received in CRYPTO frames -func (s *cryptoStream) GetCryptoData() []byte { +func (s *baseCryptoStream) GetCryptoData() []byte { _, data, _ := s.queue.Pop() return data } -func (s *cryptoStream) Finish() error { +func (s *baseCryptoStream) Finish() error { if s.queue.HasMoreData() { return &qerr.TransportError{ ErrorCode: qerr.ProtocolViolation, @@ -64,20 +73,177 @@ func (s *cryptoStream) Finish() error { } // Writes writes data that should be sent out in CRYPTO frames -func (s *cryptoStream) Write(p []byte) (int, error) { +func (s *baseCryptoStream) Write(p []byte) (int, error) { s.writeBuf = append(s.writeBuf, p...) return len(p), nil } -func (s *cryptoStream) HasData() bool { +func (s *baseCryptoStream) HasData() bool { return len(s.writeBuf) > 0 } -func (s *cryptoStream) PopCryptoFrame(maxLen protocol.ByteCount) *wire.CryptoFrame { +func (s *baseCryptoStream) PopCryptoFrame(maxLen protocol.ByteCount) *wire.CryptoFrame { f := &wire.CryptoFrame{Offset: s.writeOffset} n := min(f.MaxDataLen(maxLen), protocol.ByteCount(len(s.writeBuf))) + if n <= 0 { + return nil + } f.Data = s.writeBuf[:n] s.writeBuf = s.writeBuf[n:] s.writeOffset += n return f } + +type cryptoStream struct { + baseCryptoStream +} + +type clientHelloCut struct { + start protocol.ByteCount + end protocol.ByteCount +} + +type initialCryptoStream struct { + baseCryptoStream + + scramble bool + end protocol.ByteCount + cuts [2]clientHelloCut +} + +func newInitialCryptoStream(isClient bool) *initialCryptoStream { + var scramble bool + if isClient { + disabled, err := strconv.ParseBool(os.Getenv(disableClientHelloScramblingEnv)) + scramble = err != nil || !disabled + } + s := &initialCryptoStream{ + baseCryptoStream: baseCryptoStream{queue: *newFrameSorter()}, + scramble: scramble, + } + for i := range len(s.cuts) { + s.cuts[i].start = protocol.InvalidByteCount + s.cuts[i].end = protocol.InvalidByteCount + } + return s +} + +func (s *initialCryptoStream) HasData() bool { + // The ClientHello might be written in multiple parts. + // In order to correctly split the ClientHello, we need the entire ClientHello has been queued. + if s.scramble && s.writeOffset == 0 && s.cuts[0].start == protocol.InvalidByteCount { + return false + } + return s.baseCryptoStream.HasData() +} + +func (s *initialCryptoStream) Write(p []byte) (int, error) { + s.writeBuf = append(s.writeBuf, p...) + if !s.scramble { + return len(p), nil + } + if s.cuts[0].start == protocol.InvalidByteCount { + sniPos, sniLen, echPos, err := findSNIAndECH(s.writeBuf) + if errors.Is(err, io.ErrUnexpectedEOF) { + return len(p), nil + } + if err != nil { + return len(p), err + } + if sniPos == -1 && echPos == -1 { + // Neither SNI nor ECH found. + // There's nothing to scramble. + s.scramble = false + return len(p), nil + } + s.end = protocol.ByteCount(len(s.writeBuf)) + s.cuts[0].start = protocol.ByteCount(sniPos + sniLen/2) // right in the middle + s.cuts[0].end = protocol.ByteCount(sniPos + sniLen) + if echPos > 0 { + // ECH extension found, cut the ECH extension type value (a uint16) in half + start := protocol.ByteCount(echPos + 1) + s.cuts[1].start = start + // cut somewhere (16 bytes), most likely in the ECH extension value + s.cuts[1].end = min(start+16, s.end) + } + slices.SortFunc(s.cuts[:], func(a, b clientHelloCut) int { + if a.start == protocol.InvalidByteCount { + return 1 + } + if a.start > b.start { + return 1 + } + return -1 + }) + } + return len(p), nil +} + +func (s *initialCryptoStream) PopCryptoFrame(maxLen protocol.ByteCount) *wire.CryptoFrame { + if !s.scramble { + return s.baseCryptoStream.PopCryptoFrame(maxLen) + } + + // send out the skipped parts + if s.writeOffset == s.end { + var foundCuts bool + var f *wire.CryptoFrame + for i, c := range s.cuts { + if c.start == protocol.InvalidByteCount { + continue + } + foundCuts = true + if f != nil { + break + } + f = &wire.CryptoFrame{Offset: c.start} + n := min(f.MaxDataLen(maxLen), c.end-c.start) + if n <= 0 { + return nil + } + f.Data = s.writeBuf[c.start : c.start+n] + s.cuts[i].start += n + if s.cuts[i].start == c.end { + s.cuts[i].start = protocol.InvalidByteCount + s.cuts[i].end = protocol.InvalidByteCount + foundCuts = false + } + } + if !foundCuts { + // no more cuts found, we're done sending out everything up until s.end + s.writeBuf = s.writeBuf[s.end:] + s.end = protocol.InvalidByteCount + s.scramble = false + } + return f + } + + nextCut := clientHelloCut{start: protocol.InvalidByteCount, end: protocol.InvalidByteCount} + for _, c := range s.cuts { + if c.start == protocol.InvalidByteCount { + continue + } + if c.start > s.writeOffset { + nextCut = c + break + } + } + f := &wire.CryptoFrame{Offset: s.writeOffset} + maxOffset := nextCut.start + if maxOffset == protocol.InvalidByteCount { + maxOffset = s.end + } + n := min(f.MaxDataLen(maxLen), maxOffset-s.writeOffset) + if n <= 0 { + return nil + } + f.Data = s.writeBuf[s.writeOffset : s.writeOffset+n] + // Don't reslice the writeBuf yet. + // This is done once all parts have been sent out. + s.writeOffset += n + if s.writeOffset == nextCut.start { + s.writeOffset = nextCut.end + } + + return f +} diff --git a/vendor/github.com/quic-go/quic-go/crypto_stream_manager.go b/vendor/github.com/quic-go/quic-go/crypto_stream_manager.go index d70b9b00..1e7dbf74 100644 --- a/vendor/github.com/quic-go/quic-go/crypto_stream_manager.go +++ b/vendor/github.com/quic-go/quic-go/crypto_stream_manager.go @@ -8,13 +8,13 @@ import ( ) type cryptoStreamManager struct { - initialStream *cryptoStream + initialStream *initialCryptoStream handshakeStream *cryptoStream oneRTTStream *cryptoStream } func newCryptoStreamManager( - initialStream *cryptoStream, + initialStream *initialCryptoStream, handshakeStream *cryptoStream, oneRTTStream *cryptoStream, ) *cryptoStreamManager { @@ -26,35 +26,31 @@ func newCryptoStreamManager( } func (m *cryptoStreamManager) HandleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel) error { - var str *cryptoStream //nolint:exhaustive // CRYPTO frames cannot be sent in 0-RTT packets. switch encLevel { case protocol.EncryptionInitial: - str = m.initialStream + return m.initialStream.HandleCryptoFrame(frame) case protocol.EncryptionHandshake: - str = m.handshakeStream + return m.handshakeStream.HandleCryptoFrame(frame) case protocol.Encryption1RTT: - str = m.oneRTTStream + return m.oneRTTStream.HandleCryptoFrame(frame) default: return fmt.Errorf("received CRYPTO frame with unexpected encryption level: %s", encLevel) } - return str.HandleCryptoFrame(frame) } func (m *cryptoStreamManager) GetCryptoData(encLevel protocol.EncryptionLevel) []byte { - var str *cryptoStream //nolint:exhaustive // CRYPTO frames cannot be sent in 0-RTT packets. switch encLevel { case protocol.EncryptionInitial: - str = m.initialStream + return m.initialStream.GetCryptoData() case protocol.EncryptionHandshake: - str = m.handshakeStream + return m.handshakeStream.GetCryptoData() case protocol.Encryption1RTT: - str = m.oneRTTStream + return m.oneRTTStream.GetCryptoData() default: panic(fmt.Sprintf("received CRYPTO frame with unexpected encryption level: %s", encLevel)) } - return str.GetCryptoData() } func (m *cryptoStreamManager) GetPostHandshakeData(maxSize protocol.ByteCount) *wire.CryptoFrame { diff --git a/vendor/github.com/quic-go/quic-go/errors.go b/vendor/github.com/quic-go/quic-go/errors.go index 4a69a7f1..829730fe 100644 --- a/vendor/github.com/quic-go/quic-go/errors.go +++ b/vendor/github.com/quic-go/quic-go/errors.go @@ -7,42 +7,72 @@ import ( ) type ( - TransportError = qerr.TransportError - ApplicationError = qerr.ApplicationError + // TransportError indicates an error that occurred on the QUIC transport layer. + // Every transport error other than CONNECTION_REFUSED and APPLICATION_ERROR is + // likely a bug in the implementation. + TransportError = qerr.TransportError + // ApplicationError is an application-defined error. + ApplicationError = qerr.ApplicationError + // VersionNegotiationError indicates a failure to negotiate a QUIC version. VersionNegotiationError = qerr.VersionNegotiationError - StatelessResetError = qerr.StatelessResetError - IdleTimeoutError = qerr.IdleTimeoutError - HandshakeTimeoutError = qerr.HandshakeTimeoutError + // StatelessResetError indicates a stateless reset was received. + // This can happen when the peer reboots, or when packets are misrouted. + // See section 10.3 of RFC 9000 for details. + StatelessResetError = qerr.StatelessResetError + // IdleTimeoutError indicates that the connection timed out because it was inactive for too long. + IdleTimeoutError = qerr.IdleTimeoutError + // HandshakeTimeoutError indicates that the connection timed out before completing the handshake. + HandshakeTimeoutError = qerr.HandshakeTimeoutError ) type ( - TransportErrorCode = qerr.TransportErrorCode + // TransportErrorCode is a QUIC transport error code, see section 20 of RFC 9000. + TransportErrorCode = qerr.TransportErrorCode + // ApplicationErrorCode is an QUIC application error code. ApplicationErrorCode = qerr.ApplicationErrorCode - StreamErrorCode = qerr.StreamErrorCode + // StreamErrorCode is a QUIC stream error code. The meaning of the value is defined by the application. + StreamErrorCode = qerr.StreamErrorCode ) const ( - NoError = qerr.NoError - InternalError = qerr.InternalError - ConnectionRefused = qerr.ConnectionRefused - FlowControlError = qerr.FlowControlError - StreamLimitError = qerr.StreamLimitError - StreamStateError = qerr.StreamStateError - FinalSizeError = qerr.FinalSizeError - FrameEncodingError = qerr.FrameEncodingError - TransportParameterError = qerr.TransportParameterError - ConnectionIDLimitError = qerr.ConnectionIDLimitError - ProtocolViolation = qerr.ProtocolViolation - InvalidToken = qerr.InvalidToken + // NoError is the NO_ERROR transport error code. + NoError = qerr.NoError + // InternalError is the INTERNAL_ERROR transport error code. + InternalError = qerr.InternalError + // ConnectionRefused is the CONNECTION_REFUSED transport error code. + ConnectionRefused = qerr.ConnectionRefused + // FlowControlError is the FLOW_CONTROL_ERROR transport error code. + FlowControlError = qerr.FlowControlError + // StreamLimitError is the STREAM_LIMIT_ERROR transport error code. + StreamLimitError = qerr.StreamLimitError + // StreamStateError is the STREAM_STATE_ERROR transport error code. + StreamStateError = qerr.StreamStateError + // FinalSizeError is the FINAL_SIZE_ERROR transport error code. + FinalSizeError = qerr.FinalSizeError + // FrameEncodingError is the FRAME_ENCODING_ERROR transport error code. + FrameEncodingError = qerr.FrameEncodingError + // TransportParameterError is the TRANSPORT_PARAMETER_ERROR transport error code. + TransportParameterError = qerr.TransportParameterError + // ConnectionIDLimitError is the CONNECTION_ID_LIMIT_ERROR transport error code. + ConnectionIDLimitError = qerr.ConnectionIDLimitError + // ProtocolViolation is the PROTOCOL_VIOLATION transport error code. + ProtocolViolation = qerr.ProtocolViolation + // InvalidToken is the INVALID_TOKEN transport error code. + InvalidToken = qerr.InvalidToken + // ApplicationErrorErrorCode is the APPLICATION_ERROR transport error code. ApplicationErrorErrorCode = qerr.ApplicationErrorErrorCode - CryptoBufferExceeded = qerr.CryptoBufferExceeded - KeyUpdateError = qerr.KeyUpdateError - AEADLimitReached = qerr.AEADLimitReached - NoViablePathError = qerr.NoViablePathError + // CryptoBufferExceeded is the CRYPTO_BUFFER_EXCEEDED transport error code. + CryptoBufferExceeded = qerr.CryptoBufferExceeded + // KeyUpdateError is the KEY_UPDATE_ERROR transport error code. + KeyUpdateError = qerr.KeyUpdateError + // AEADLimitReached is the AEAD_LIMIT_REACHED transport error code. + AEADLimitReached = qerr.AEADLimitReached + // NoViablePathError is the NO_VIABLE_PATH_ERROR transport error code. + NoViablePathError = qerr.NoViablePathError ) -// A StreamError is used for Stream.CancelRead and Stream.CancelWrite. -// It is also returned from Stream.Read and Stream.Write if the peer canceled reading or writing. +// A StreamError is used to signal stream cancellations. +// It is returned from the Read and Write methods of the [ReceiveStream], [SendStream] and [Stream]. type StreamError struct { StreamID StreamID ErrorCode StreamErrorCode @@ -62,7 +92,7 @@ func (e *StreamError) Error() string { return fmt.Sprintf("stream %d canceled by %s with error code %d", e.StreamID, pers, e.ErrorCode) } -// DatagramTooLargeError is returned from Connection.SendDatagram if the payload is too large to be sent. +// DatagramTooLargeError is returned from Conn.SendDatagram if the payload is too large to be sent. type DatagramTooLargeError struct { MaxDatagramPayloadSize int64 } diff --git a/vendor/github.com/quic-go/quic-go/frame_sorter.go b/vendor/github.com/quic-go/quic-go/frame_sorter.go index bee0abad..20c6d9cc 100644 --- a/vendor/github.com/quic-go/quic-go/frame_sorter.go +++ b/vendor/github.com/quic-go/quic-go/frame_sorter.go @@ -235,3 +235,40 @@ func (s *frameSorter) Pop() (protocol.ByteCount, []byte, func()) { func (s *frameSorter) HasMoreData() bool { return len(s.queue) > 0 } + +var errTooLittleData = errors.New("too little data") + +// Peek copies len(p) consecutive bytes starting at offset into p, without removing them. +// It is only possible to peek from an offset where a frame starts. +// +// If there isn't enough consecutive data available, errTooLittleData is returned. +func (s *frameSorter) Peek(offset protocol.ByteCount, p []byte) error { + if len(p) == 0 { + return nil + } + + // first, check if we have enough consecutive data available + pos := offset + remaining := len(p) + for remaining > 0 { + entry, ok := s.queue[pos] + if !ok { + return errTooLittleData + } + entryLen := len(entry.Data) + if remaining <= entryLen { + break // enough data available + } + remaining -= entryLen + pos += protocol.ByteCount(entryLen) + } + + pos = offset + var copied int + for copied < len(p) { + entry := s.queue[pos] // the entry is guaranteed to exist from the check above + copied += copy(p[copied:], entry.Data) + pos += protocol.ByteCount(len(entry.Data)) + } + return nil +} diff --git a/vendor/github.com/quic-go/quic-go/framer.go b/vendor/github.com/quic-go/quic-go/framer.go index fee31631..ca23f0aa 100644 --- a/vendor/github.com/quic-go/quic-go/framer.go +++ b/vendor/github.com/quic-go/quic-go/framer.go @@ -3,10 +3,10 @@ package quic import ( "slices" "sync" - "time" "github.com/quic-go/quic-go/internal/ackhandler" "github.com/quic-go/quic-go/internal/flowcontrol" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils/ringbuffer" "github.com/quic-go/quic-go/internal/wire" @@ -22,14 +22,18 @@ const ( // (which is the RESET_STREAM frame). const maxStreamControlFrameSize = 25 +type streamFrameGetter interface { + popStreamFrame(protocol.ByteCount, protocol.Version) (ackhandler.StreamFrame, *wire.StreamDataBlockedFrame, bool) +} + type streamControlFrameGetter interface { - getControlFrame(time.Time) (_ ackhandler.Frame, ok, hasMore bool) + getControlFrame(monotime.Time) (_ ackhandler.Frame, ok, hasMore bool) } type framer struct { mutex sync.Mutex - activeStreams map[protocol.StreamID]sendStreamI + activeStreams map[protocol.StreamID]streamFrameGetter streamQueue ringbuffer.RingBuffer[protocol.StreamID] streamsWithControlFrames map[protocol.StreamID]streamControlFrameGetter @@ -42,7 +46,7 @@ type framer struct { func newFramer(connFlowController flowcontrol.ConnectionFlowController) *framer { return &framer{ - activeStreams: make(map[protocol.StreamID]sendStreamI), + activeStreams: make(map[protocol.StreamID]streamFrameGetter), streamsWithControlFrames: make(map[protocol.StreamID]streamControlFrameGetter), connFlowController: connFlowController, } @@ -86,7 +90,7 @@ func (f *framer) Append( frames []ackhandler.Frame, streamFrames []ackhandler.StreamFrame, maxLen protocol.ByteCount, - now time.Time, + now monotime.Time, v protocol.Version, ) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) { f.controlFrameMutex.Lock() @@ -153,7 +157,7 @@ func (f *framer) Append( func (f *framer) appendControlFrames( frames []ackhandler.Frame, maxLen protocol.ByteCount, - now time.Time, + now monotime.Time, v protocol.Version, ) ([]ackhandler.Frame, protocol.ByteCount) { var length protocol.ByteCount @@ -214,7 +218,7 @@ func (f *framer) QueuedTooManyControlFrames() bool { return f.queuedTooManyControlFrames } -func (f *framer) AddActiveStream(id protocol.StreamID, str sendStreamI) { +func (f *framer) AddActiveStream(id protocol.StreamID, str streamFrameGetter) { f.mutex.Lock() if _, ok := f.activeStreams[id]; !ok { f.streamQueue.PushBack(id) diff --git a/vendor/github.com/quic-go/quic-go/interface.go b/vendor/github.com/quic-go/quic-go/interface.go index e144acc6..119e3205 100644 --- a/vendor/github.com/quic-go/quic-go/interface.go +++ b/vendor/github.com/quic-go/quic-go/interface.go @@ -4,13 +4,13 @@ import ( "context" "crypto/tls" "errors" - "io" "net" + "slices" "time" "github.com/quic-go/quic-go/internal/handshake" "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlogwriter" ) // The StreamID is the ID of a QUIC stream. @@ -26,10 +26,17 @@ const ( Version2 = protocol.Version2 ) +// SupportedVersions returns the support versions, sorted in descending order of preference. +func SupportedVersions() []Version { + // clone the slice to prevent the caller from modifying the slice + return slices.Clone(protocol.SupportedVersions) +} + // A ClientToken is a token received by the client. // It can be used to skip address validation on future connection attempts. type ClientToken struct { data []byte + rtt time.Duration } type TokenStore interface { @@ -51,171 +58,10 @@ type TokenStore interface { // when the server rejects a 0-RTT connection attempt. var Err0RTTRejected = errors.New("0-RTT rejected") -// ConnectionTracingKey can be used to associate a [logging.ConnectionTracer] with a [Connection]. -// It is set on the Connection.Context() context, -// as well as on the context passed to logging.Tracer.NewConnectionTracer. -// -// Deprecated: Applications can set their own tracing key using Transport.ConnContext. -var ConnectionTracingKey = connTracingCtxKey{} - -// ConnectionTracingID is the type of the context value saved under the ConnectionTracingKey. -// -// Deprecated: Applications can set their own tracing key using Transport.ConnContext. -type ConnectionTracingID uint64 - -type connTracingCtxKey struct{} - // QUICVersionContextKey can be used to find out the QUIC version of a TLS handshake from the // context returned by tls.Config.ClientInfo.Context. var QUICVersionContextKey = handshake.QUICVersionContextKey -// Stream is the interface implemented by QUIC streams. -// In addition to the errors listed on the [Connection], -// calls to stream functions can return a [StreamError] if the stream is canceled. -type Stream interface { - ReceiveStream - SendStream - // SetDeadline sets the read and write deadlines associated - // with the connection. It is equivalent to calling both - // SetReadDeadline and SetWriteDeadline. - SetDeadline(t time.Time) error -} - -// A ReceiveStream is a unidirectional Receive Stream. -type ReceiveStream interface { - // StreamID returns the stream ID. - StreamID() StreamID - // Read reads data from the stream. - // Read can be made to time out using SetDeadline and SetReadDeadline. - // If the stream was canceled, the error is a StreamError. - io.Reader - // CancelRead aborts receiving on this stream. - // It will ask the peer to stop transmitting stream data. - // Read will unblock immediately, and future Read calls will fail. - // When called multiple times or after reading the io.EOF it is a no-op. - CancelRead(StreamErrorCode) - // SetReadDeadline sets the deadline for future Read calls and - // any currently-blocked Read call. - // A zero value for t means Read will not time out. - SetReadDeadline(t time.Time) error -} - -// A SendStream is a unidirectional Send Stream. -type SendStream interface { - // StreamID returns the stream ID. - StreamID() StreamID - // Write writes data to the stream. - // Write can be made to time out using SetDeadline and SetWriteDeadline. - // If the stream was canceled, the error is a StreamError. - io.Writer - // Close closes the write-direction of the stream. - // Future calls to Write are not permitted after calling Close. - // It must not be called concurrently with Write. - // It must not be called after calling CancelWrite. - io.Closer - // CancelWrite aborts sending on this stream. - // Data already written, but not yet delivered to the peer is not guaranteed to be delivered reliably. - // Write will unblock immediately, and future calls to Write will fail. - // When called multiple times it is a no-op. - // When called after Close, it aborts delivery. Note that there is no guarantee if - // the peer will receive the FIN or the reset first. - CancelWrite(StreamErrorCode) - // The Context is canceled as soon as the write-side of the stream is closed. - // This happens when Close() or CancelWrite() is called, or when the peer - // cancels the read-side of their stream. - // The cancellation cause is set to the error that caused the stream to - // close, or `context.Canceled` in case the stream is closed without error. - Context() context.Context - // SetWriteDeadline sets the deadline for future Write calls - // and any currently-blocked Write call. - // Even if write times out, it may return n > 0, indicating that - // some data was successfully written. - // A zero value for t means Write will not time out. - SetWriteDeadline(t time.Time) error -} - -// A Connection is a QUIC connection between two peers. -// Calls to the connection (and to streams) can return the following types of errors: -// - [ApplicationError]: for errors triggered by the application running on top of QUIC -// - [TransportError]: for errors triggered by the QUIC transport (in many cases a misbehaving peer) -// - [IdleTimeoutError]: when the peer goes away unexpectedly (this is a [net.Error] timeout error) -// - [HandshakeTimeoutError]: when the cryptographic handshake takes too long (this is a [net.Error] timeout error) -// - [StatelessResetError]: when we receive a stateless reset -// - [VersionNegotiationError]: returned by the client, when there's no version overlap between the peers -type Connection interface { - // AcceptStream returns the next stream opened by the peer, blocking until one is available. - AcceptStream(context.Context) (Stream, error) - // AcceptUniStream returns the next unidirectional stream opened by the peer, blocking until one is available. - AcceptUniStream(context.Context) (ReceiveStream, error) - // OpenStream opens a new bidirectional QUIC stream. - // There is no signaling to the peer about new streams: - // The peer can only accept the stream after data has been sent on the stream, - // or the stream has been reset or closed. - // When reaching the peer's stream limit, it is not possible to open a new stream until the - // peer raises the stream limit. In that case, a StreamLimitReachedError is returned. - OpenStream() (Stream, error) - // OpenStreamSync opens a new bidirectional QUIC stream. - // It blocks until a new stream can be opened. - // There is no signaling to the peer about new streams: - // The peer can only accept the stream after data has been sent on the stream, - // or the stream has been reset or closed. - OpenStreamSync(context.Context) (Stream, error) - // OpenUniStream opens a new outgoing unidirectional QUIC stream. - // There is no signaling to the peer about new streams: - // The peer can only accept the stream after data has been sent on the stream, - // or the stream has been reset or closed. - // When reaching the peer's stream limit, it is not possible to open a new stream until the - // peer raises the stream limit. In that case, a StreamLimitReachedError is returned. - OpenUniStream() (SendStream, error) - // OpenUniStreamSync opens a new outgoing unidirectional QUIC stream. - // It blocks until a new stream can be opened. - // There is no signaling to the peer about new streams: - // The peer can only accept the stream after data has been sent on the stream, - // or the stream has been reset or closed. - OpenUniStreamSync(context.Context) (SendStream, error) - // LocalAddr returns the local address. - LocalAddr() net.Addr - // RemoteAddr returns the address of the peer. - RemoteAddr() net.Addr - // CloseWithError closes the connection with an error. - // The error string will be sent to the peer. - CloseWithError(ApplicationErrorCode, string) error - // Context returns a context that is cancelled when the connection is closed. - // The cancellation cause is set to the error that caused the connection to - // close, or `context.Canceled` in case the listener is closed first. - Context() context.Context - // ConnectionState returns basic details about the QUIC connection. - // Warning: This API should not be considered stable and might change soon. - ConnectionState() ConnectionState - - // SendDatagram sends a message using a QUIC datagram, as specified in RFC 9221. - // There is no delivery guarantee for DATAGRAM frames, they are not retransmitted if lost. - // The payload of the datagram needs to fit into a single QUIC packet. - // In addition, a datagram may be dropped before being sent out if the available packet size suddenly decreases. - // If the payload is too large to be sent at the current time, a DatagramTooLargeError is returned. - SendDatagram(payload []byte) error - // ReceiveDatagram gets a message received in a datagram, as specified in RFC 9221. - ReceiveDatagram(context.Context) ([]byte, error) - - AddPath(*Transport) (*Path, error) -} - -// An EarlyConnection is a connection that is handshaking. -// Data sent during the handshake is encrypted using the forward secure keys. -// When using client certificates, the client's identity is only verified -// after completion of the handshake. -type EarlyConnection interface { - Connection - - // HandshakeComplete blocks until the handshake completes (or fails). - // For the client, data sent before completion of the handshake is encrypted with 0-RTT keys. - // For the server, data sent before completion of the handshake is encrypted with 1-RTT keys, - // however the client's identity is only verified once the handshake completes. - HandshakeComplete() <-chan struct{} - - NextConnection(context.Context) (Connection, error) -} - // StatelessResetKey is a key used to derive stateless reset tokens. type StatelessResetKey [32]byte @@ -296,7 +142,7 @@ type Config struct { // limit the memory usage. // To avoid deadlocks, it is not valid to call other functions on the connection or on streams // in this callback. - AllowConnectionWindowIncrease func(conn Connection, delta uint64) bool + AllowConnectionWindowIncrease func(conn *Conn, delta uint64) bool // MaxIncomingStreams is the maximum number of concurrent bidirectional streams that a peer is allowed to open. // If not set, it will default to 100. // If set to a negative value, it doesn't allow any bidirectional streams. @@ -326,13 +172,12 @@ type Config struct { Allow0RTT bool // Enable QUIC datagram support (RFC 9221). EnableDatagrams bool - Tracer func(context.Context, logging.Perspective, ConnectionID) *logging.ConnectionTracer -} + // Enable QUIC Stream Resets with Partial Delivery. + // See https://datatracker.ietf.org/doc/html/draft-ietf-quic-reliable-stream-reset-07. + EnableStreamResetPartialDelivery bool -// ClientHelloInfo contains information about an incoming connection attempt. -// -// Deprecated: Use ClientInfo instead. -type ClientHelloInfo = ClientInfo + Tracer func(ctx context.Context, isClient bool, connID ConnectionID) qlogwriter.Trace +} // ClientInfo contains information about an incoming connection attempt. type ClientInfo struct { @@ -349,11 +194,18 @@ type ClientInfo struct { type ConnectionState struct { // TLS contains information about the TLS connection state, incl. the tls.ConnectionState. TLS tls.ConnectionState - // SupportsDatagrams indicates whether the peer advertised support for QUIC datagrams (RFC 9221). - // When true, datagrams can be sent using the Connection's SendDatagram method. - // This is a unilateral declaration by the peer - receiving datagrams is only possible if - // datagram support was enabled locally via Config.EnableDatagrams. - SupportsDatagrams bool + // SupportsDatagrams indicates support for QUIC datagrams (RFC 9221). + SupportsDatagrams struct { + // Remote is true if the peer advertised datagram support. + // Local is true if datagram support was enabled via Config.EnableDatagrams. + Remote, Local bool + } + // SupportsStreamResetPartialDelivery indicates support for QUIC Stream Resets with Partial Delivery. + SupportsStreamResetPartialDelivery struct { + // Remote is true if the peer advertised support. + // Local is true if support was enabled via Config.EnableStreamResetPartialDelivery. + Remote, Local bool + } // Used0RTT says if 0-RTT resumption was used. Used0RTT bool // Version is the QUIC version of the QUIC connection. diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/ack_eliciting.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/ack_eliciting.go index 34506b12..8d843612 100644 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/ack_eliciting.go +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/ack_eliciting.go @@ -2,6 +2,19 @@ package ackhandler import "github.com/quic-go/quic-go/internal/wire" +// IsFrameTypeAckEliciting returns true if the frame is ack-eliciting. +func IsFrameTypeAckEliciting(t wire.FrameType) bool { + //nolint:exhaustive // The default case catches the rest. + switch t { + case wire.FrameTypeAck, wire.FrameTypeAckECN: + return false + case wire.FrameTypeConnectionClose, wire.FrameTypeApplicationClose: + return false + default: + return true + } +} + // IsFrameAckEliciting returns true if the frame is ack-eliciting. func IsFrameAckEliciting(f wire.Frame) bool { _, isAck := f.(*wire.AckFrame) diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/ackhandler.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/ackhandler.go deleted file mode 100644 index 6f890b4d..00000000 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/ackhandler.go +++ /dev/null @@ -1,24 +0,0 @@ -package ackhandler - -import ( - "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/utils" - "github.com/quic-go/quic-go/logging" -) - -// NewAckHandler creates a new SentPacketHandler and a new ReceivedPacketHandler. -// clientAddressValidated indicates whether the address was validated beforehand by an address validation token. -// clientAddressValidated has no effect for a client. -func NewAckHandler( - initialPacketNumber protocol.PacketNumber, - initialMaxDatagramSize protocol.ByteCount, - rttStats *utils.RTTStats, - clientAddressValidated bool, - enableECN bool, - pers protocol.Perspective, - tracer *logging.ConnectionTracer, - logger utils.Logger, -) (SentPacketHandler, ReceivedPacketHandler) { - sph := newSentPacketHandler(initialPacketNumber, initialMaxDatagramSize, rttStats, clientAddressValidated, enableECN, pers, tracer, logger) - return sph, newReceivedPacketHandler(sph, logger) -} diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/ecn.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/ecn.go index 68415ac6..123d3a34 100644 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/ecn.go +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/ecn.go @@ -5,7 +5,8 @@ import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" + "github.com/quic-go/quic-go/qlogwriter" ) type ecnState uint8 @@ -18,13 +19,29 @@ const ( ecnStateFailed ) +const ( + // ecnFailedNoECNCounts is emitted when an ACK acknowledges ECN-marked packets, + // but doesn't contain any ECN counts + ecnFailedNoECNCounts = "ACK doesn't contain ECN marks" + // ecnFailedDecreasedECNCounts is emitted when an ACK frame decreases ECN counts + ecnFailedDecreasedECNCounts = "ACK decreases ECN counts" + // ecnFailedLostAllTestingPackets is emitted when all ECN testing packets are declared lost + ecnFailedLostAllTestingPackets = "all ECN testing packets declared lost" + // ecnFailedMoreECNCountsThanSent is emitted when an ACK contains more ECN counts than ECN-marked packets were sent + ecnFailedMoreECNCountsThanSent = "ACK contains more ECN counts than ECN-marked packets sent" + // ecnFailedTooFewECNCounts is emitted when an ACK contains fewer ECN counts than it acknowledges packets + ecnFailedTooFewECNCounts = "ACK contains fewer new ECN counts than acknowledged ECN-marked packets" + // ecnFailedManglingDetected is emitted when the path marks all ECN-marked packets as CE + ecnFailedManglingDetected = "ECN mangling detected" +) + // must fit into an uint8, otherwise numSentTesting and numLostTesting must have a larger type const numECNTestingPackets = 10 type ecnHandler interface { SentPacket(protocol.PacketNumber, protocol.ECN) Mode() protocol.ECN - HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64) (congested bool) + HandleNewlyAcked(packets []packetWithPacketNumber, ect0, ect1, ecnce int64) (congested bool) LostPacket(protocol.PacketNumber) } @@ -45,20 +62,20 @@ type ecnTracker struct { numSentECT0, numSentECT1 int64 numAckedECT0, numAckedECT1, numAckedECNCE int64 - tracer *logging.ConnectionTracer - logger utils.Logger + qlogger qlogwriter.Recorder + logger utils.Logger } var _ ecnHandler = &ecnTracker{} -func newECNTracker(logger utils.Logger, tracer *logging.ConnectionTracer) *ecnTracker { +func newECNTracker(logger utils.Logger, qlogger qlogwriter.Recorder) *ecnTracker { return &ecnTracker{ firstTestingPacket: protocol.InvalidPacketNumber, lastTestingPacket: protocol.InvalidPacketNumber, firstCapablePacket: protocol.InvalidPacketNumber, state: ecnStateInitial, logger: logger, - tracer: tracer, + qlogger: qlogger, } } @@ -92,8 +109,10 @@ func (e *ecnTracker) SentPacket(pn protocol.PacketNumber, ecn protocol.ECN) { e.firstTestingPacket = pn } if e.numSentECT0+e.numSentECT1 >= numECNTestingPackets { - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateUnknown, logging.ECNTriggerNoTrigger) + if e.qlogger != nil { + e.qlogger.RecordEvent(qlog.ECNStateUpdated{ + State: qlog.ECNStateUnknown, + }) } e.state = ecnStateUnknown e.lastTestingPacket = pn @@ -103,8 +122,10 @@ func (e *ecnTracker) SentPacket(pn protocol.PacketNumber, ecn protocol.ECN) { func (e *ecnTracker) Mode() protocol.ECN { switch e.state { case ecnStateInitial: - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateTesting, logging.ECNTriggerNoTrigger) + if e.qlogger != nil { + e.qlogger.RecordEvent(qlog.ECNStateUpdated{ + State: qlog.ECNStateTesting, + }) } e.state = ecnStateTesting return e.Mode() @@ -131,8 +152,11 @@ func (e *ecnTracker) LostPacket(pn protocol.PacketNumber) { } if e.numLostTesting >= e.numSentTesting { e.logger.Debugf("Disabling ECN. All testing packets were lost.") - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedLostAllTestingPackets) + if e.qlogger != nil { + e.qlogger.RecordEvent(qlog.ECNStateUpdated{ + State: qlog.ECNStateFailed, + Trigger: ecnFailedLostAllTestingPackets, + }) } e.state = ecnStateFailed return @@ -144,7 +168,7 @@ func (e *ecnTracker) LostPacket(pn protocol.PacketNumber) { // HandleNewlyAcked handles the ECN counts on an ACK frame. // It must only be called for ACK frames that increase the largest acknowledged packet number, // see section 13.4.2.1 of RFC 9000. -func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64) (congested bool) { +func (e *ecnTracker) HandleNewlyAcked(packets []packetWithPacketNumber, ect0, ect1, ecnce int64) (congested bool) { if e.state == ecnStateFailed { return false } @@ -153,8 +177,11 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // the total number of packets sent with each corresponding ECT codepoint. if ect0 > e.numSentECT0 || ect1 > e.numSentECT1 { e.logger.Debugf("Disabling ECN. Received more ECT(0) / ECT(1) acknowledgements than packets sent.") - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedMoreECNCountsThanSent) + if e.qlogger != nil { + e.qlogger.RecordEvent(qlog.ECNStateUpdated{ + State: qlog.ECNStateFailed, + Trigger: ecnFailedMoreECNCountsThanSent, + }) } e.state = ecnStateFailed return false @@ -179,8 +206,11 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // * peers that don't report any ECN counts if (ackedECT0 > 0 || ackedECT1 > 0) && ect0 == 0 && ect1 == 0 && ecnce == 0 { e.logger.Debugf("Disabling ECN. ECN-marked packet acknowledged, but no ECN counts on ACK frame.") - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedNoECNCounts) + if e.qlogger != nil { + e.qlogger.RecordEvent(qlog.ECNStateUpdated{ + State: qlog.ECNStateFailed, + Trigger: ecnFailedNoECNCounts, + }) } e.state = ecnStateFailed return false @@ -196,8 +226,11 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // Any decrease means that the peer's counting logic is broken. if newECT0 < 0 || newECT1 < 0 || newECNCE < 0 { e.logger.Debugf("Disabling ECN. ECN counts decreased unexpectedly.") - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedDecreasedECNCounts) + if e.qlogger != nil { + e.qlogger.RecordEvent(qlog.ECNStateUpdated{ + State: qlog.ECNStateFailed, + Trigger: ecnFailedDecreasedECNCounts, + }) } e.state = ecnStateFailed return false @@ -208,8 +241,11 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // This could be the result of (partial) bleaching. if newECT0+newECNCE < ackedECT0 { e.logger.Debugf("Disabling ECN. Received less ECT(0) + ECN-CE than packets sent with ECT(0).") - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedTooFewECNCounts) + if e.qlogger != nil { + e.qlogger.RecordEvent(qlog.ECNStateUpdated{ + State: qlog.ECNStateFailed, + Trigger: ecnFailedTooFewECNCounts, + }) } e.state = ecnStateFailed return false @@ -218,8 +254,11 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // the number of newly acknowledged packets sent with an ECT(1) marking. if newECT1+newECNCE < ackedECT1 { e.logger.Debugf("Disabling ECN. Received less ECT(1) + ECN-CE than packets sent with ECT(1).") - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedTooFewECNCounts) + if e.qlogger != nil { + e.qlogger.RecordEvent(qlog.ECNStateUpdated{ + State: qlog.ECNStateFailed, + Trigger: ecnFailedTooFewECNCounts, + }) } e.state = ecnStateFailed return false @@ -249,8 +288,10 @@ func (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64 // This check won't succeed if the path is mangling ECN-marks (i.e. rewrites all ECN-marked packets to CE). if ackedTestingPacket && (newECT0 > 0 || newECT1 > 0) { e.logger.Debugf("ECN capability confirmed.") - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateCapable, logging.ECNTriggerNoTrigger) + if e.qlogger != nil { + e.qlogger.RecordEvent(qlog.ECNStateUpdated{ + State: qlog.ECNStateCapable, + }) } e.state = ecnStateCapable } @@ -267,8 +308,11 @@ func (e *ecnTracker) failIfMangled() { if e.numSentECT0+e.numSentECT1 > numAckedECNCE { return } - if e.tracer != nil && e.tracer.ECNStateUpdated != nil { - e.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected) + if e.qlogger != nil { + e.qlogger.RecordEvent(qlog.ECNStateUpdated{ + State: qlog.ECNStateFailed, + Trigger: ecnFailedManglingDetected, + }) } e.state = ecnStateFailed } diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/interfaces.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/interfaces.go index 5fcce44d..620a5e11 100644 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/interfaces.go +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/interfaces.go @@ -1,8 +1,7 @@ package ackhandler import ( - "time" - + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/wire" ) @@ -10,19 +9,20 @@ import ( // SentPacketHandler handles ACKs received for outgoing packets type SentPacketHandler interface { // SentPacket may modify the packet - SentPacket(t time.Time, pn, largestAcked protocol.PacketNumber, streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, ecn protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket, isPathProbePacket bool) + SentPacket(t monotime.Time, pn, largestAcked protocol.PacketNumber, streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, ecn protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket, isPathProbePacket bool) // ReceivedAck processes an ACK frame. // It does not store a copy of the frame. - ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool /* 1-RTT packet acked */, error) - ReceivedBytes(_ protocol.ByteCount, rcvTime time.Time) - DropPackets(_ protocol.EncryptionLevel, rcvTime time.Time) - ResetForRetry(rcvTime time.Time) + ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) (bool /* 1-RTT packet acked */, error) + ReceivedPacket(protocol.EncryptionLevel, monotime.Time) + ReceivedBytes(_ protocol.ByteCount, rcvTime monotime.Time) + DropPackets(_ protocol.EncryptionLevel, rcvTime monotime.Time) + ResetForRetry(rcvTime monotime.Time) // The SendMode determines if and what kind of packets can be sent. - SendMode(now time.Time) SendMode + SendMode(now monotime.Time) SendMode // TimeUntilSend is the time when the next packet should be sent. // It is used for pacing packets. - TimeUntilSend() time.Time + TimeUntilSend() monotime.Time SetMaxDatagramSize(count protocol.ByteCount) // only to be called once the handshake is complete @@ -32,23 +32,8 @@ type SentPacketHandler interface { PeekPacketNumber(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) PopPacketNumber(protocol.EncryptionLevel) protocol.PacketNumber - GetLossDetectionTimeout() time.Time - OnLossDetectionTimeout(now time.Time) error + GetLossDetectionTimeout() monotime.Time + OnLossDetectionTimeout(now monotime.Time) error - MigratedPath(now time.Time, initialMaxPacketSize protocol.ByteCount) -} - -type sentPacketTracker interface { - GetLowestPacketNotConfirmedAcked() protocol.PacketNumber - ReceivedPacket(_ protocol.EncryptionLevel, rcvTime time.Time) -} - -// ReceivedPacketHandler handles ACKs needed to send for incoming packets -type ReceivedPacketHandler interface { - IsPotentiallyDuplicate(protocol.PacketNumber, protocol.EncryptionLevel) bool - ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, encLevel protocol.EncryptionLevel, rcvTime time.Time, ackEliciting bool) error - DropPackets(protocol.EncryptionLevel) - - GetAlarmTimeout() time.Time - GetAckFrame(_ protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame + MigratedPath(now monotime.Time, initialMaxPacketSize protocol.ByteCount) } diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/lost_packet_tracker.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/lost_packet_tracker.go new file mode 100644 index 00000000..40665734 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/lost_packet_tracker.go @@ -0,0 +1,73 @@ +package ackhandler + +import ( + "iter" + "slices" + + "github.com/quic-go/quic-go/internal/monotime" + "github.com/quic-go/quic-go/internal/protocol" +) + +type lostPacket struct { + PacketNumber protocol.PacketNumber + SendTime monotime.Time +} + +type lostPacketTracker struct { + maxLength int + lostPackets []lostPacket +} + +func newLostPacketTracker(maxLength int) *lostPacketTracker { + return &lostPacketTracker{ + maxLength: maxLength, + // Preallocate a small slice only. + // Hopefully we won't lose many packets. + lostPackets: make([]lostPacket, 0, 4), + } +} + +func (t *lostPacketTracker) Add(p protocol.PacketNumber, sendTime monotime.Time) { + if len(t.lostPackets) == t.maxLength { + t.lostPackets = t.lostPackets[1:] + } + t.lostPackets = append(t.lostPackets, lostPacket{ + PacketNumber: p, + SendTime: sendTime, + }) +} + +// Delete deletes a packet from the lost packet tracker. +// This function is not optimized for performance if many packets are lost, +// but it is only used when a spurious loss is detected, which is rare. +func (t *lostPacketTracker) Delete(pn protocol.PacketNumber) { + t.lostPackets = slices.DeleteFunc(t.lostPackets, func(p lostPacket) bool { + return p.PacketNumber == pn + }) +} + +func (t *lostPacketTracker) All() iter.Seq2[protocol.PacketNumber, monotime.Time] { + return func(yield func(protocol.PacketNumber, monotime.Time) bool) { + for _, p := range t.lostPackets { + if !yield(p.PacketNumber, p.SendTime) { + return + } + } + } +} + +func (t *lostPacketTracker) DeleteBefore(ti monotime.Time) { + if len(t.lostPackets) == 0 { + return + } + if !t.lostPackets[0].SendTime.Before(ti) { + return + } + var idx int + for ; idx < len(t.lostPackets); idx++ { + if !t.lostPackets[idx].SendTime.Before(ti) { + break + } + } + t.lostPackets = slices.Delete(t.lostPackets, 0, idx) +} diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/mockgen.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/mockgen.go index 0031e6b1..3add80d1 100644 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/mockgen.go +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/mockgen.go @@ -2,8 +2,5 @@ package ackhandler -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package ackhandler -destination mock_sent_packet_tracker_test.go github.com/quic-go/quic-go/internal/ackhandler SentPacketTracker" -type SentPacketTracker = sentPacketTracker - -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package ackhandler -destination mock_ecn_handler_test.go github.com/quic-go/quic-go/internal/ackhandler ECNHandler" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package ackhandler -destination mock_ecn_handler_test.go github.com/quic-go/quic-go/internal/ackhandler ECNHandler" type ECNHandler = ecnHandler diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/packet.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/packet.go index c634939a..7d986300 100644 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/packet.go +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/packet.go @@ -2,15 +2,19 @@ package ackhandler import ( "sync" - "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" ) +type packetWithPacketNumber struct { + PacketNumber protocol.PacketNumber + *packet +} + // A Packet is a packet type packet struct { - SendTime time.Time - PacketNumber protocol.PacketNumber + SendTime monotime.Time StreamFrames []StreamFrame Frames []Frame LargestAcked protocol.PacketNumber // InvalidPacketNumber if the packet doesn't contain an ACK @@ -20,30 +24,30 @@ type packet struct { IsPathMTUProbePacket bool // We don't report the loss of Path MTU probe packets to the congestion controller. includedInBytesInFlight bool - declaredLost bool - skippedPacket bool isPathProbePacket bool } -func (p *packet) outstanding() bool { - return !p.declaredLost && !p.skippedPacket && !p.IsPathMTUProbePacket && !p.isPathProbePacket +func (p *packet) Outstanding() bool { + return !p.IsPathMTUProbePacket && !p.isPathProbePacket && p.IsAckEliciting() +} + +func (p *packet) IsAckEliciting() bool { + return len(p.StreamFrames) > 0 || len(p.Frames) > 0 } var packetPool = sync.Pool{New: func() any { return &packet{} }} func getPacket() *packet { p := packetPool.Get().(*packet) - p.PacketNumber = 0 p.StreamFrames = nil p.Frames = nil p.LargestAcked = 0 p.Length = 0 p.EncryptionLevel = protocol.EncryptionLevel(0) - p.SendTime = time.Time{} + p.SendTime = 0 p.IsPathMTUProbePacket = false p.includedInBytesInFlight = false - p.declaredLost = false - p.skippedPacket = false + p.isPathProbePacket = false return p } diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_handler.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_handler.go index eda0826c..d0d24bf3 100644 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_handler.go +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_handler.go @@ -2,16 +2,14 @@ package ackhandler import ( "fmt" - "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" ) -type receivedPacketHandler struct { - sentPackets sentPacketTracker - +type ReceivedPacketHandler struct { initialPackets *receivedPacketTracker handshakePackets *receivedPacketTracker appDataPackets appDataReceivedPacketTracker @@ -19,11 +17,8 @@ type receivedPacketHandler struct { lowest1RTTPacket protocol.PacketNumber } -var _ ReceivedPacketHandler = &receivedPacketHandler{} - -func newReceivedPacketHandler(sentPackets sentPacketTracker, logger utils.Logger) ReceivedPacketHandler { - return &receivedPacketHandler{ - sentPackets: sentPackets, +func NewReceivedPacketHandler(logger utils.Logger) *ReceivedPacketHandler { + return &ReceivedPacketHandler{ initialPackets: newReceivedPacketTracker(), handshakePackets: newReceivedPacketTracker(), appDataPackets: *newAppDataReceivedPacketTracker(logger), @@ -31,24 +26,23 @@ func newReceivedPacketHandler(sentPackets sentPacketTracker, logger utils.Logger } } -func (h *receivedPacketHandler) ReceivedPacket( +func (h *ReceivedPacketHandler) ReceivedPacket( pn protocol.PacketNumber, ecn protocol.ECN, encLevel protocol.EncryptionLevel, - rcvTime time.Time, + rcvTime monotime.Time, ackEliciting bool, ) error { - h.sentPackets.ReceivedPacket(encLevel, rcvTime) switch encLevel { case protocol.EncryptionInitial: - return h.initialPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting) + return h.initialPackets.ReceivedPacket(pn, ecn, ackEliciting) case protocol.EncryptionHandshake: // The Handshake packet number space might already have been dropped as a result // of processing the CRYPTO frame that was contained in this packet. if h.handshakePackets == nil { return nil } - return h.handshakePackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting) + return h.handshakePackets.ReceivedPacket(pn, ecn, ackEliciting) case protocol.Encryption0RTT: if h.lowest1RTTPacket != protocol.InvalidPacketNumber && pn > h.lowest1RTTPacket { return fmt.Errorf("received packet number %d on a 0-RTT packet after receiving %d on a 1-RTT packet", pn, h.lowest1RTTPacket) @@ -58,17 +52,17 @@ func (h *receivedPacketHandler) ReceivedPacket( if h.lowest1RTTPacket == protocol.InvalidPacketNumber || pn < h.lowest1RTTPacket { h.lowest1RTTPacket = pn } - if err := h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting); err != nil { - return err - } - h.appDataPackets.IgnoreBelow(h.sentPackets.GetLowestPacketNotConfirmedAcked()) - return nil + return h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting) default: panic(fmt.Sprintf("received packet with unknown encryption level: %s", encLevel)) } } -func (h *receivedPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) { +func (h *ReceivedPacketHandler) IgnorePacketsBelow(pn protocol.PacketNumber) { + h.appDataPackets.IgnoreBelow(pn) +} + +func (h *ReceivedPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) { //nolint:exhaustive // 1-RTT packet number space is never dropped. switch encLevel { case protocol.EncryptionInitial: @@ -83,11 +77,11 @@ func (h *receivedPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) { } } -func (h *receivedPacketHandler) GetAlarmTimeout() time.Time { +func (h *ReceivedPacketHandler) GetAlarmTimeout() monotime.Time { return h.appDataPackets.GetAlarmTimeout() } -func (h *receivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame { +func (h *ReceivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel, now monotime.Time, onlyIfQueued bool) *wire.AckFrame { //nolint:exhaustive // 0-RTT packets can't contain ACK frames. switch encLevel { case protocol.EncryptionInitial: @@ -108,7 +102,7 @@ func (h *receivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel, n } } -func (h *receivedPacketHandler) IsPotentiallyDuplicate(pn protocol.PacketNumber, encLevel protocol.EncryptionLevel) bool { +func (h *ReceivedPacketHandler) IsPotentiallyDuplicate(pn protocol.PacketNumber, encLevel protocol.EncryptionLevel) bool { switch encLevel { case protocol.EncryptionInitial: if h.initialPackets != nil { diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_history.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_history.go index f9feae1d..d065b6e6 100644 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_history.go +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_history.go @@ -1,10 +1,10 @@ package ackhandler import ( + "iter" "slices" "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/wire" ) // interval is an interval from one PacketNumber to the other @@ -23,7 +23,9 @@ type receivedPacketHistory struct { } func newReceivedPacketHistory() *receivedPacketHistory { - return &receivedPacketHistory{} + return &receivedPacketHistory{ + deletedBelow: protocol.InvalidPacketNumber, + } } // ReceivedPacket registers a packet with PacketNumber p and updates the ranges @@ -107,21 +109,37 @@ func (h *receivedPacketHistory) DeleteBelow(p protocol.PacketNumber) { } } -// AppendAckRanges appends to a slice of all AckRanges that can be used in an AckFrame -func (h *receivedPacketHistory) AppendAckRanges(ackRanges []wire.AckRange) []wire.AckRange { - for i := len(h.ranges) - 1; i >= 0; i-- { - ackRanges = append(ackRanges, wire.AckRange{Smallest: h.ranges[i].Start, Largest: h.ranges[i].End}) +// Backward returns an iterator over the ranges in reverse order +func (h *receivedPacketHistory) Backward() iter.Seq[interval] { + return func(yield func(interval) bool) { + for i := len(h.ranges) - 1; i >= 0; i-- { + if !yield(h.ranges[i]) { + return + } + } } - return ackRanges } -func (h *receivedPacketHistory) GetHighestAckRange() wire.AckRange { - ackRange := wire.AckRange{} - if len(h.ranges) > 0 { - ackRange.Smallest = h.ranges[len(h.ranges)-1].Start - ackRange.Largest = h.ranges[len(h.ranges)-1].End +func (h *receivedPacketHistory) HighestMissingUpTo(p protocol.PacketNumber) protocol.PacketNumber { + if len(h.ranges) == 0 || (h.deletedBelow != protocol.InvalidPacketNumber && p < h.deletedBelow) { + return protocol.InvalidPacketNumber } - return ackRange + p = min(h.ranges[len(h.ranges)-1].End, p) + for i := len(h.ranges) - 1; i >= 0; i-- { + r := h.ranges[i] + if p >= r.Start && p <= r.End { // p is contained in this range + highest := r.Start - 1 // highest packet in the gap before this range + if h.deletedBelow != protocol.InvalidPacketNumber && highest < h.deletedBelow { + return protocol.InvalidPacketNumber + } + return highest + } + if i >= 1 && p > h.ranges[i-1].End && p <= r.Start { + // p is in the gap between the previous range and this range + return p + } + } + return p } func (h *receivedPacketHistory) IsPotentiallyDuplicate(p protocol.PacketNumber) bool { diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_tracker.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_tracker.go index d1d26f4a..64092ccc 100644 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_tracker.go +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_tracker.go @@ -4,11 +4,14 @@ import ( "fmt" "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" ) +const reorderingThreshold = 1 + // The receivedPacketTracker tracks packets for the Initial and Handshake packet number space. // Every received packet is acknowledged immediately. type receivedPacketTracker struct { @@ -24,9 +27,9 @@ func newReceivedPacketTracker() *receivedPacketTracker { return &receivedPacketTracker{packetHistory: *newReceivedPacketHistory()} } -func (h *receivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, rcvTime time.Time, ackEliciting bool) error { +func (h *receivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, ackEliciting bool) error { if isNew := h.packetHistory.ReceivedPacket(pn); !isNew { - return fmt.Errorf("recevedPacketTracker BUG: ReceivedPacket called for old / duplicate packet %d", pn) + return fmt.Errorf("receivedPacketTracker BUG: ReceivedPacket called for old / duplicate packet %d", pn) } //nolint:exhaustive // Only need to count ECT(0), ECT(1) and ECN-CE. @@ -59,7 +62,9 @@ func (h *receivedPacketTracker) GetAckFrame() *wire.AckFrame { ack.ECT0 = h.ect0 ack.ECT1 = h.ect1 ack.ECNCE = h.ecnce - ack.AckRanges = h.packetHistory.AppendAckRanges(ack.AckRanges) + for r := range h.packetHistory.Backward() { + ack.AckRanges = append(ack.AckRanges, wire.AckRange{Smallest: r.Start, Largest: r.End}) + } h.lastAck = ack h.hasNewAck = false @@ -78,7 +83,7 @@ const packetsBeforeAck = 2 type appDataReceivedPacketTracker struct { receivedPacketTracker - largestObservedRcvdTime time.Time + largestObservedRcvdTime monotime.Time largestObserved protocol.PacketNumber ignoreBelow protocol.PacketNumber @@ -87,7 +92,7 @@ type appDataReceivedPacketTracker struct { ackQueued bool // true if we need send a new ACK ackElicitingPacketsReceivedSinceLastAck int - ackAlarm time.Time + ackAlarm monotime.Time logger utils.Logger } @@ -101,8 +106,8 @@ func newAppDataReceivedPacketTracker(logger utils.Logger) *appDataReceivedPacket return h } -func (h *appDataReceivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, rcvTime time.Time, ackEliciting bool) error { - if err := h.receivedPacketTracker.ReceivedPacket(pn, ecn, rcvTime, ackEliciting); err != nil { +func (h *appDataReceivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, rcvTime monotime.Time, ackEliciting bool) error { + if err := h.receivedPacketTracker.ReceivedPacket(pn, ecn, ackEliciting); err != nil { return err } if pn >= h.largestObserved { @@ -116,7 +121,7 @@ func (h *appDataReceivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, isMissing := h.isMissing(pn) if !h.ackQueued && h.shouldQueueACK(pn, ecn, isMissing) { h.ackQueued = true - h.ackAlarm = time.Time{} // cancel the ack alarm + h.ackAlarm = 0 // cancel the ack alarm } if !h.ackQueued { // No ACK queued, but we'll need to acknowledge the packet after max_ack_delay. @@ -153,17 +158,21 @@ func (h *appDataReceivedPacketTracker) hasNewMissingPackets() bool { if h.lastAck == nil { return false } - highestRange := h.packetHistory.GetHighestAckRange() - return highestRange.Smallest > h.lastAck.LargestAcked()+1 && highestRange.Len() == 1 + if h.largestObserved < reorderingThreshold { + return false + } + highestMissing := h.packetHistory.HighestMissingUpTo(h.largestObserved - reorderingThreshold) + if highestMissing == protocol.InvalidPacketNumber { + return false + } + if highestMissing < h.lastAck.LargestAcked() { + // the packet was already reported missing in the last ACK + return false + } + return highestMissing > h.lastAck.LargestAcked()-reorderingThreshold } func (h *appDataReceivedPacketTracker) shouldQueueACK(pn protocol.PacketNumber, ecn protocol.ECN, wasMissing bool) bool { - // always acknowledge the first packet - if h.lastAck == nil { - h.logger.Debugf("\tQueueing ACK because the first packet should be acknowledged.") - return true - } - // Send an ACK if this packet was reported missing in an ACK sent before. // Ack decimation with reordering relies on the timer to send an ACK, but if // missing packets we reported in the previous ACK, send an ACK immediately. @@ -196,7 +205,7 @@ func (h *appDataReceivedPacketTracker) shouldQueueACK(pn protocol.PacketNumber, return false } -func (h *appDataReceivedPacketTracker) GetAckFrame(now time.Time, onlyIfQueued bool) *wire.AckFrame { +func (h *appDataReceivedPacketTracker) GetAckFrame(now monotime.Time, onlyIfQueued bool) *wire.AckFrame { if onlyIfQueued && !h.ackQueued { if h.ackAlarm.IsZero() || h.ackAlarm.After(now) { return nil @@ -211,9 +220,9 @@ func (h *appDataReceivedPacketTracker) GetAckFrame(now time.Time, onlyIfQueued b } ack.DelayTime = max(0, now.Sub(h.largestObservedRcvdTime)) h.ackQueued = false - h.ackAlarm = time.Time{} + h.ackAlarm = 0 h.ackElicitingPacketsReceivedSinceLastAck = 0 return ack } -func (h *appDataReceivedPacketTracker) GetAlarmTimeout() time.Time { return h.ackAlarm } +func (h *appDataReceivedPacketTracker) GetAlarmTimeout() monotime.Time { return h.ackAlarm } diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_handler.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_handler.go index a53be7d7..9b539ead 100644 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_handler.go +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_handler.go @@ -6,11 +6,13 @@ import ( "time" "github.com/quic-go/quic-go/internal/congestion" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" + "github.com/quic-go/quic-go/qlogwriter" ) const ( @@ -34,8 +36,8 @@ type packetNumberSpace struct { history sentPacketHistory pns packetNumberGenerator - lossTime time.Time - lastAckElicitingPacketTime time.Time + lossTime monotime.Time + lastAckElicitingPacketTime monotime.Time largestAcked protocol.PacketNumber largestSent protocol.PacketNumber @@ -57,8 +59,8 @@ func newPacketNumberSpace(initialPN protocol.PacketNumber, isAppData bool) *pack } type alarmTimer struct { - Time time.Time - TimerType logging.TimerType + Time monotime.Time + TimerType qlog.TimerType EncryptionLevel protocol.EncryptionLevel } @@ -66,6 +68,9 @@ type sentPacketHandler struct { initialPackets *packetNumberSpace handshakePackets *packetNumberSpace appDataPackets *packetNumberSpace + lostPackets lostPacketTracker // only for application-data packet number space + // send time of the largest acknowledged packet, across all packet number spaces + largestAckedTime monotime.Time // Do we know that the peer completed address validation yet? // Always true for the server. @@ -78,18 +83,15 @@ type sentPacketHandler struct { handshakeConfirmed bool - // lowestNotConfirmedAcked is the lowest packet number that we sent an ACK for, but haven't received confirmation, that this ACK actually arrived - // example: we send an ACK for packets 90-100 with packet number 20 - // once we receive an ACK from the peer for packet 20, the lowestNotConfirmedAcked is 101 - // Only applies to the application-data packet number space. - lowestNotConfirmedAcked protocol.PacketNumber + ignorePacketsBelow func(protocol.PacketNumber) - ackedPackets []*packet // to avoid allocations in detectAndRemoveAckedPackets + ackedPackets []packetWithPacketNumber // to avoid allocations in detectAndRemoveAckedPackets bytesInFlight protocol.ByteCount congestion congestion.SendAlgorithmWithDebugInfos rttStats *utils.RTTStats + connStats *utils.ConnectionStats // The number of times a PTO has been sent without receiving an ack. ptoCount uint32 @@ -106,33 +108,34 @@ type sentPacketHandler struct { perspective protocol.Perspective - tracer *logging.ConnectionTracer - logger utils.Logger + qlogger qlogwriter.Recorder + lastMetrics qlog.MetricsUpdated + logger utils.Logger } -var ( - _ SentPacketHandler = &sentPacketHandler{} - _ sentPacketTracker = &sentPacketHandler{} -) +var _ SentPacketHandler = &sentPacketHandler{} // clientAddressValidated indicates whether the address was validated beforehand by an address validation token. // If the address was validated, the amplification limit doesn't apply. It has no effect for a client. -func newSentPacketHandler( +func NewSentPacketHandler( initialPN protocol.PacketNumber, initialMaxDatagramSize protocol.ByteCount, rttStats *utils.RTTStats, + connStats *utils.ConnectionStats, clientAddressValidated bool, enableECN bool, + ignorePacketsBelow func(protocol.PacketNumber), pers protocol.Perspective, - tracer *logging.ConnectionTracer, + qlogger qlogwriter.Recorder, logger utils.Logger, -) *sentPacketHandler { +) SentPacketHandler { congestion := congestion.NewCubicSender( congestion.DefaultClock{}, rttStats, + connStats, initialMaxDatagramSize, true, // use Reno - tracer, + qlogger, ) h := &sentPacketHandler{ @@ -141,15 +144,18 @@ func newSentPacketHandler( initialPackets: newPacketNumberSpace(initialPN, false), handshakePackets: newPacketNumberSpace(0, false), appDataPackets: newPacketNumberSpace(0, true), + lostPackets: *newLostPacketTracker(64), rttStats: rttStats, + connStats: connStats, congestion: congestion, + ignorePacketsBelow: ignorePacketsBelow, perspective: pers, - tracer: tracer, + qlogger: qlogger, logger: logger, } if enableECN { h.enableECN = true - h.ecnTracker = newECNTracker(logger, tracer) + h.ecnTracker = newECNTracker(logger, qlogger) } return h } @@ -164,7 +170,7 @@ func (h *sentPacketHandler) removeFromBytesInFlight(p *packet) { } } -func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel, now time.Time) { +func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel, now monotime.Time) { // The server won't await address validation after the handshake is confirmed. // This applies even if we didn't receive an ACK for a Handshake packet. if h.perspective == protocol.PerspectiveClient && encLevel == protocol.EncryptionHandshake { @@ -177,7 +183,7 @@ func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel, now t if pnSpace == nil { return } - for p := range pnSpace.history.Packets() { + for _, p := range pnSpace.history.Packets() { h.removeFromBytesInFlight(p) } } @@ -196,18 +202,18 @@ func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel, now t // and not when the client drops 0-RTT keys when the handshake completes. // When 0-RTT is rejected, all application data sent so far becomes invalid. // Delete the packets from the history and remove them from bytes_in_flight. - for p := range h.appDataPackets.history.Packets() { - if p.EncryptionLevel != protocol.Encryption0RTT && !p.skippedPacket { + for pn, p := range h.appDataPackets.history.Packets() { + if p.EncryptionLevel != protocol.Encryption0RTT { break } h.removeFromBytesInFlight(p) - h.appDataPackets.history.Remove(p.PacketNumber) + h.appDataPackets.history.Remove(pn) } default: panic(fmt.Sprintf("Cannot drop keys for encryption level %s", encLevel)) } - if h.tracer != nil && h.tracer.UpdatedPTOCount != nil && h.ptoCount != 0 { - h.tracer.UpdatedPTOCount(0) + if h.qlogger != nil && h.ptoCount != 0 { + h.qlogger.RecordEvent(qlog.PTOCountUpdated{PTOCount: 0}) } h.ptoCount = 0 h.numProbesToSend = 0 @@ -215,7 +221,8 @@ func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel, now t h.setLossDetectionTimer(now) } -func (h *sentPacketHandler) ReceivedBytes(n protocol.ByteCount, t time.Time) { +func (h *sentPacketHandler) ReceivedBytes(n protocol.ByteCount, t monotime.Time) { + h.connStats.BytesReceived.Add(uint64(n)) wasAmplificationLimit := h.isAmplificationLimited() h.bytesReceived += n if wasAmplificationLimit && !h.isAmplificationLimited() { @@ -223,7 +230,8 @@ func (h *sentPacketHandler) ReceivedBytes(n protocol.ByteCount, t time.Time) { } } -func (h *sentPacketHandler) ReceivedPacket(l protocol.EncryptionLevel, t time.Time) { +func (h *sentPacketHandler) ReceivedPacket(l protocol.EncryptionLevel, t monotime.Time) { + h.connStats.PacketsReceived.Add(1) if h.perspective == protocol.PerspectiveServer && l == protocol.EncryptionHandshake && !h.peerAddressValidated { h.peerAddressValidated = true h.setLossDetectionTimer(t) @@ -231,18 +239,18 @@ func (h *sentPacketHandler) ReceivedPacket(l protocol.EncryptionLevel, t time.Ti } func (h *sentPacketHandler) packetsInFlight() int { - packetsInFlight := h.appDataPackets.history.Len() + packetsInFlight := h.appDataPackets.history.NumOutstanding() if h.handshakePackets != nil { - packetsInFlight += h.handshakePackets.history.Len() + packetsInFlight += h.handshakePackets.history.NumOutstanding() } if h.initialPackets != nil { - packetsInFlight += h.initialPackets.history.Len() + packetsInFlight += h.initialPackets.history.NumOutstanding() } return packetsInFlight } func (h *sentPacketHandler) SentPacket( - t time.Time, + t monotime.Time, pn, largestAcked protocol.PacketNumber, streamFrames []StreamFrame, frames []Frame, @@ -253,6 +261,8 @@ func (h *sentPacketHandler) SentPacket( isPathProbePacket bool, ) { h.bytesSent += size + h.connStats.BytesSent.Add(uint64(size)) + h.connStats.PacketsSent.Add(1) pnSpace := h.getPacketNumberSpace(encLevel) if h.logger.Debug() && (pnSpace.history.HasOutstandingPackets() || pnSpace.history.HasOutstandingPathProbes()) { @@ -262,23 +272,27 @@ func (h *sentPacketHandler) SentPacket( } pnSpace.largestSent = pn - isAckEliciting := len(streamFrames) > 0 || len(frames) > 0 + + p := getPacket() + p.SendTime = t + p.EncryptionLevel = encLevel + p.Length = size + p.Frames = frames + p.LargestAcked = largestAcked + p.StreamFrames = streamFrames + p.IsPathMTUProbePacket = isPathMTUProbePacket + p.isPathProbePacket = isPathProbePacket + isAckEliciting := p.IsAckEliciting() if isPathProbePacket { - p := getPacket() - p.SendTime = t - p.PacketNumber = pn - p.EncryptionLevel = encLevel - p.Length = size - p.Frames = frames - p.isPathProbePacket = true - pnSpace.history.SentPathProbePacket(p) + pnSpace.history.SentPathProbePacket(pn, p) h.setLossDetectionTimer(t) return } if isAckEliciting { pnSpace.lastAckElicitingPacketTime = t h.bytesInFlight += size + p.includedInBytesInFlight = true if h.numProbesToSend > 0 { h.numProbesToSend-- } @@ -289,32 +303,65 @@ func (h *sentPacketHandler) SentPacket( h.ecnTracker.SentPacket(pn, ecn) } + pnSpace.history.SentPacket(pn, p) if !isAckEliciting { - pnSpace.history.SentNonAckElicitingPacket(pn) if !h.peerCompletedAddressValidation { h.setLossDetectionTimer(t) } return } - - p := getPacket() - p.SendTime = t - p.PacketNumber = pn - p.EncryptionLevel = encLevel - p.Length = size - p.LargestAcked = largestAcked - p.StreamFrames = streamFrames - p.Frames = frames - p.IsPathMTUProbePacket = isPathMTUProbePacket - p.includedInBytesInFlight = true - - pnSpace.history.SentAckElicitingPacket(p) - if h.tracer != nil && h.tracer.UpdatedMetrics != nil { - h.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight()) + if h.qlogger != nil { + h.qlogMetricsUpdated() } h.setLossDetectionTimer(t) } +func (h *sentPacketHandler) qlogMetricsUpdated() { + var metricsUpdatedEvent qlog.MetricsUpdated + var updated bool + if h.rttStats.HasMeasurement() { + if h.lastMetrics.MinRTT != h.rttStats.MinRTT() { + metricsUpdatedEvent.MinRTT = h.rttStats.MinRTT() + h.lastMetrics.MinRTT = metricsUpdatedEvent.MinRTT + updated = true + } + if h.lastMetrics.SmoothedRTT != h.rttStats.SmoothedRTT() { + metricsUpdatedEvent.SmoothedRTT = h.rttStats.SmoothedRTT() + h.lastMetrics.SmoothedRTT = metricsUpdatedEvent.SmoothedRTT + updated = true + } + if h.lastMetrics.LatestRTT != h.rttStats.LatestRTT() { + metricsUpdatedEvent.LatestRTT = h.rttStats.LatestRTT() + h.lastMetrics.LatestRTT = metricsUpdatedEvent.LatestRTT + updated = true + } + if h.lastMetrics.RTTVariance != h.rttStats.MeanDeviation() { + metricsUpdatedEvent.RTTVariance = h.rttStats.MeanDeviation() + h.lastMetrics.RTTVariance = metricsUpdatedEvent.RTTVariance + updated = true + } + } + if cwnd := h.congestion.GetCongestionWindow(); h.lastMetrics.CongestionWindow != int(cwnd) { + metricsUpdatedEvent.CongestionWindow = int(cwnd) + h.lastMetrics.CongestionWindow = metricsUpdatedEvent.CongestionWindow + updated = true + } + if h.lastMetrics.BytesInFlight != int(h.bytesInFlight) { + metricsUpdatedEvent.BytesInFlight = int(h.bytesInFlight) + h.lastMetrics.BytesInFlight = metricsUpdatedEvent.BytesInFlight + updated = true + } + packetsInFlight := h.packetsInFlight() + if h.lastMetrics.PacketsInFlight != packetsInFlight { + metricsUpdatedEvent.PacketsInFlight = packetsInFlight + h.lastMetrics.PacketsInFlight = metricsUpdatedEvent.PacketsInFlight + updated = true + } + if updated { + h.qlogger.RecordEvent(metricsUpdatedEvent) + } +} + func (h *sentPacketHandler) getPacketNumberSpace(encLevel protocol.EncryptionLevel) *packetNumberSpace { switch encLevel { case protocol.EncryptionInitial: @@ -328,7 +375,7 @@ func (h *sentPacketHandler) getPacketNumberSpace(encLevel protocol.EncryptionLev } } -func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool /* contained 1-RTT packet */, error) { +func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime monotime.Time) (bool /* contained 1-RTT packet */, error) { pnSpace := h.getPacketNumberSpace(encLevel) largestAcked := ack.LargestAcked() @@ -349,21 +396,26 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En } priorInFlight := h.bytesInFlight - ackedPackets, err := h.detectAndRemoveAckedPackets(ack, encLevel) + ackedPackets, hasAckEliciting, err := h.detectAndRemoveAckedPackets(ack, encLevel) if err != nil || len(ackedPackets) == 0 { return false, err } - // update the RTT, if the largest acked is newly acknowledged + // update the RTT, if: + // * the largest acked is newly acknowledged, AND + // * at least one new ack-eliciting packet was acknowledged if len(ackedPackets) > 0 { - if p := ackedPackets[len(ackedPackets)-1]; p.PacketNumber == ack.LargestAcked() && !p.isPathProbePacket { + if p := ackedPackets[len(ackedPackets)-1]; p.PacketNumber == ack.LargestAcked() && !p.isPathProbePacket && hasAckEliciting { // don't use the ack delay for Initial and Handshake packets var ackDelay time.Duration if encLevel == protocol.Encryption1RTT { ackDelay = min(ack.DelayTime, h.rttStats.MaxAckDelay()) } - h.rttStats.UpdateRTT(rcvTime.Sub(p.SendTime), ackDelay) - if h.logger.Debug() { - h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation()) + if h.largestAckedTime.IsZero() || !p.SendTime.Before(h.largestAckedTime) { + h.rttStats.UpdateRTT(rcvTime.Sub(p.SendTime), ackDelay) + if h.logger.Debug() { + h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation()) + } + h.largestAckedTime = p.SendTime } h.congestion.MaybeExitSlowStart() } @@ -385,88 +437,152 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En } var acked1RTTPacket bool for _, p := range ackedPackets { - if p.includedInBytesInFlight && !p.declaredLost { + if p.includedInBytesInFlight { h.congestion.OnPacketAcked(p.PacketNumber, p.Length, priorInFlight, rcvTime) } if p.EncryptionLevel == protocol.Encryption1RTT { acked1RTTPacket = true } - h.removeFromBytesInFlight(p) + h.removeFromBytesInFlight(p.packet) if !p.isPathProbePacket { - putPacket(p) + putPacket(p.packet) } } + + // detect spurious losses for application data packets, if the ACK was not reordered + if encLevel == protocol.Encryption1RTT && largestAcked == pnSpace.largestAcked { + h.detectSpuriousLosses( + ack, + rcvTime.Add(-min(ack.DelayTime, h.rttStats.MaxAckDelay())), + ) + // clean up lost packet history + h.lostPackets.DeleteBefore(rcvTime.Add(-3 * h.rttStats.PTO(false))) + } + // After this point, we must not use ackedPackets any longer! // We've already returned the buffers. - ackedPackets = nil //nolint:ineffassign // This is just to be on the safe side. + ackedPackets = nil //nolint:ineffassign // This is just to be on the safe side. + clear(h.ackedPackets) // make sure the memory is released + h.ackedPackets = h.ackedPackets[:0] // Reset the pto_count unless the client is unsure if the server has validated the client's address. if h.peerCompletedAddressValidation { - if h.tracer != nil && h.tracer.UpdatedPTOCount != nil && h.ptoCount != 0 { - h.tracer.UpdatedPTOCount(0) + if h.qlogger != nil && h.ptoCount != 0 { + h.qlogger.RecordEvent(qlog.PTOCountUpdated{PTOCount: 0}) } h.ptoCount = 0 } h.numProbesToSend = 0 - if h.tracer != nil && h.tracer.UpdatedMetrics != nil { - h.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight()) + if h.qlogger != nil { + h.qlogMetricsUpdated() } h.setLossDetectionTimer(rcvTime) return acked1RTTPacket, nil } -func (h *sentPacketHandler) GetLowestPacketNotConfirmedAcked() protocol.PacketNumber { - return h.lowestNotConfirmedAcked +func (h *sentPacketHandler) detectSpuriousLosses(ack *wire.AckFrame, ackTime monotime.Time) { + var maxPacketReordering protocol.PacketNumber + var maxTimeReordering time.Duration + ackRangeIdx := len(ack.AckRanges) - 1 + var spuriousLosses []protocol.PacketNumber + for pn, sendTime := range h.lostPackets.All() { + ackRange := ack.AckRanges[ackRangeIdx] + for pn > ackRange.Largest { + // this should never happen, since detectSpuriousLosses is only called for ACKs that increase the largest acked + if ackRangeIdx == 0 { + break + } + ackRangeIdx-- + ackRange = ack.AckRanges[ackRangeIdx] + } + if pn < ackRange.Smallest { + continue + } + if pn <= ackRange.Largest { + packetReordering := h.appDataPackets.history.Difference(ack.LargestAcked(), pn) + timeReordering := ackTime.Sub(sendTime) + maxPacketReordering = max(maxPacketReordering, packetReordering) + maxTimeReordering = max(maxTimeReordering, timeReordering) + + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.SpuriousLoss{ + EncryptionLevel: protocol.Encryption1RTT, + PacketNumber: pn, + PacketReordering: uint64(packetReordering), + TimeReordering: timeReordering, + }) + } + spuriousLosses = append(spuriousLosses, pn) + } + } + for _, pn := range spuriousLosses { + h.lostPackets.Delete(pn) + } } // Packets are returned in ascending packet number order. -func (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encLevel protocol.EncryptionLevel) ([]*packet, error) { +func (h *sentPacketHandler) detectAndRemoveAckedPackets( + ack *wire.AckFrame, + encLevel protocol.EncryptionLevel, +) (_ []packetWithPacketNumber, hasAckEliciting bool, _ error) { + if len(h.ackedPackets) > 0 { + return nil, false, errors.New("ackhandler BUG: ackedPackets slice not empty") + } + pnSpace := h.getPacketNumberSpace(encLevel) - h.ackedPackets = h.ackedPackets[:0] - ackRangeIndex := 0 + + if encLevel == protocol.Encryption1RTT { + for p := range pnSpace.history.SkippedPackets() { + if ack.AcksPacket(p) { + return nil, false, &qerr.TransportError{ + ErrorCode: qerr.ProtocolViolation, + ErrorMessage: fmt.Sprintf("received an ACK for skipped packet number: %d (%s)", p, encLevel), + } + } + } + } + + var ackRangeIndex int lowestAcked := ack.LowestAcked() largestAcked := ack.LargestAcked() - for p := range pnSpace.history.Packets() { + for pn, p := range pnSpace.history.Packets() { // ignore packets below the lowest acked - if p.PacketNumber < lowestAcked { + if pn < lowestAcked { continue } - if p.PacketNumber > largestAcked { + if pn > largestAcked { break } if ack.HasMissingRanges() { ackRange := ack.AckRanges[len(ack.AckRanges)-1-ackRangeIndex] - for p.PacketNumber > ackRange.Largest && ackRangeIndex < len(ack.AckRanges)-1 { + for pn > ackRange.Largest && ackRangeIndex < len(ack.AckRanges)-1 { ackRangeIndex++ ackRange = ack.AckRanges[len(ack.AckRanges)-1-ackRangeIndex] } - if p.PacketNumber < ackRange.Smallest { // packet not contained in ACK range + if pn < ackRange.Smallest { // packet not contained in ACK range continue } - if p.PacketNumber > ackRange.Largest { - return nil, fmt.Errorf("BUG: ackhandler would have acked wrong packet %d, while evaluating range %d -> %d", p.PacketNumber, ackRange.Smallest, ackRange.Largest) - } - } - if p.skippedPacket { - return nil, &qerr.TransportError{ - ErrorCode: qerr.ProtocolViolation, - ErrorMessage: fmt.Sprintf("received an ACK for skipped packet number: %d (%s)", p.PacketNumber, encLevel), + if pn > ackRange.Largest { + return nil, false, fmt.Errorf("BUG: ackhandler would have acked wrong packet %d, while evaluating range %d -> %d", pn, ackRange.Smallest, ackRange.Largest) } } if p.isPathProbePacket { - probePacket := pnSpace.history.RemovePathProbe(p.PacketNumber) + probePacket := pnSpace.history.RemovePathProbe(pn) // the probe packet might already have been declared lost if probePacket != nil { - h.ackedPackets = append(h.ackedPackets, probePacket) + h.ackedPackets = append(h.ackedPackets, packetWithPacketNumber{PacketNumber: pn, packet: probePacket}) } continue } - h.ackedPackets = append(h.ackedPackets, p) + if p.IsAckEliciting() { + hasAckEliciting = true + } + h.ackedPackets = append(h.ackedPackets, packetWithPacketNumber{PacketNumber: pn, packet: p}) } if h.logger.Debug() && len(h.ackedPackets) > 0 { pns := make([]protocol.PacketNumber, len(h.ackedPackets)) @@ -477,8 +593,8 @@ func (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encL } for _, p := range h.ackedPackets { - if p.LargestAcked != protocol.InvalidPacketNumber && encLevel == protocol.Encryption1RTT { - h.lowestNotConfirmedAcked = max(h.lowestNotConfirmedAcked, p.LargestAcked+1) + if p.LargestAcked != protocol.InvalidPacketNumber && encLevel == protocol.Encryption1RTT && h.ignorePacketsBelow != nil { + h.ignorePacketsBelow(p.LargestAcked + 1) } for _, f := range p.Frames { @@ -492,18 +608,16 @@ func (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encL } } if err := pnSpace.history.Remove(p.PacketNumber); err != nil { - return nil, err - } - if h.tracer != nil && h.tracer.AcknowledgedPacket != nil { - h.tracer.AcknowledgedPacket(encLevel, p.PacketNumber) + return nil, false, err } } - return h.ackedPackets, nil + // TODO: add support for the transport:packets_acked qlog event + return h.ackedPackets, hasAckEliciting, nil } -func (h *sentPacketHandler) getLossTimeAndSpace() (time.Time, protocol.EncryptionLevel) { +func (h *sentPacketHandler) getLossTimeAndSpace() (monotime.Time, protocol.EncryptionLevel) { var encLevel protocol.EncryptionLevel - var lossTime time.Time + var lossTime monotime.Time if h.initialPackets != nil { lossTime = h.initialPackets.lossTime @@ -529,7 +643,7 @@ func (h *sentPacketHandler) getScaledPTO(includeMaxAckDelay bool) time.Duration } // same logic as getLossTimeAndSpace, but for lastAckElicitingPacketTime instead of lossTime -func (h *sentPacketHandler) getPTOTimeAndSpace(now time.Time) (pto time.Time, encLevel protocol.EncryptionLevel) { +func (h *sentPacketHandler) getPTOTimeAndSpace(now monotime.Time) (pto monotime.Time, encLevel protocol.EncryptionLevel) { // We only send application data probe packets once the handshake is confirmed, // because before that, we don't have the keys to decrypt ACKs sent in 1-RTT packets. if !h.handshakeConfirmed && !h.hasOutstandingCryptoPackets() { @@ -579,7 +693,7 @@ func (h *sentPacketHandler) hasOutstandingCryptoPackets() bool { return false } -func (h *sentPacketHandler) setLossDetectionTimer(now time.Time) { +func (h *sentPacketHandler) setLossDetectionTimer(now monotime.Time) { oldAlarm := h.alarm // only needed in case tracing is enabled newAlarm := h.lossDetectionTime(now) h.alarm = newAlarm @@ -587,17 +701,24 @@ func (h *sentPacketHandler) setLossDetectionTimer(now time.Time) { hasAlarm := !newAlarm.Time.IsZero() if !hasAlarm && !oldAlarm.Time.IsZero() { h.logger.Debugf("Canceling loss detection timer.") - if h.tracer != nil && h.tracer.LossTimerCanceled != nil { - h.tracer.LossTimerCanceled() + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.LossTimerUpdated{ + Type: qlog.LossTimerUpdateTypeCancelled, + }) } } - if hasAlarm && h.tracer != nil && h.tracer.SetLossTimer != nil && newAlarm != oldAlarm { - h.tracer.SetLossTimer(newAlarm.TimerType, newAlarm.EncryptionLevel, newAlarm.Time) + if h.qlogger != nil && hasAlarm && newAlarm != oldAlarm { + h.qlogger.RecordEvent(qlog.LossTimerUpdated{ + Type: qlog.LossTimerUpdateTypeSet, + TimerType: newAlarm.TimerType, + EncLevel: newAlarm.EncryptionLevel, + Time: newAlarm.Time.ToTime(), + }) } } -func (h *sentPacketHandler) lossDetectionTime(now time.Time) alarmTimer { +func (h *sentPacketHandler) lossDetectionTime(now monotime.Time) alarmTimer { // cancel the alarm if no packets are outstanding if h.peerCompletedAddressValidation && !h.hasOutstandingCryptoPackets() && !h.appDataPackets.history.HasOutstandingPackets() && !h.appDataPackets.history.HasOutstandingPathProbes() { @@ -609,9 +730,9 @@ func (h *sentPacketHandler) lossDetectionTime(now time.Time) alarmTimer { return alarmTimer{} } - var pathProbeLossTime time.Time + var pathProbeLossTime monotime.Time if h.appDataPackets.history.HasOutstandingPathProbes() { - if p := h.appDataPackets.history.FirstOutstandingPathProbe(); p != nil { + if _, p := h.appDataPackets.history.FirstOutstandingPathProbe(); p != nil { pathProbeLossTime = p.SendTime.Add(pathProbePacketLossTimeout) } } @@ -621,7 +742,7 @@ func (h *sentPacketHandler) lossDetectionTime(now time.Time) alarmTimer { if !lossTime.IsZero() && (pathProbeLossTime.IsZero() || lossTime.Before(pathProbeLossTime)) { return alarmTimer{ Time: lossTime, - TimerType: logging.TimerTypeACK, + TimerType: qlog.TimerTypeACK, EncryptionLevel: encLevel, } } @@ -629,30 +750,30 @@ func (h *sentPacketHandler) lossDetectionTime(now time.Time) alarmTimer { if !ptoTime.IsZero() && (pathProbeLossTime.IsZero() || ptoTime.Before(pathProbeLossTime)) { return alarmTimer{ Time: ptoTime, - TimerType: logging.TimerTypePTO, + TimerType: qlog.TimerTypePTO, EncryptionLevel: encLevel, } } if !pathProbeLossTime.IsZero() { return alarmTimer{ Time: pathProbeLossTime, - TimerType: logging.TimerTypePathProbe, + TimerType: qlog.TimerTypePathProbe, EncryptionLevel: protocol.Encryption1RTT, } } return alarmTimer{} } -func (h *sentPacketHandler) detectLostPathProbes(now time.Time) { +func (h *sentPacketHandler) detectLostPathProbes(now monotime.Time) { if !h.appDataPackets.history.HasOutstandingPathProbes() { return } lossTime := now.Add(-pathProbePacketLossTimeout) // RemovePathProbe cannot be called while iterating. - var lostPathProbes []*packet - for p := range h.appDataPackets.history.PathProbes() { + var lostPathProbes []packetWithPacketNumber + for pn, p := range h.appDataPackets.history.PathProbes() { if !p.SendTime.After(lossTime) { - lostPathProbes = append(lostPathProbes, p) + lostPathProbes = append(lostPathProbes, packetWithPacketNumber{PacketNumber: pn, packet: p}) } } for _, p := range lostPathProbes { @@ -663,9 +784,9 @@ func (h *sentPacketHandler) detectLostPathProbes(now time.Time) { } } -func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.EncryptionLevel) { +func (h *sentPacketHandler) detectLostPackets(now monotime.Time, encLevel protocol.EncryptionLevel) { pnSpace := h.getPacketNumberSpace(encLevel) - pnSpace.lossTime = time.Time{} + pnSpace.lossTime = 0 maxRTT := float64(max(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT())) lossDelay := time.Duration(timeThreshold * maxRTT) @@ -677,59 +798,73 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E lostSendTime := now.Add(-lossDelay) priorInFlight := h.bytesInFlight - for p := range pnSpace.history.Packets() { - if p.PacketNumber > pnSpace.largestAcked { + for pn, p := range pnSpace.history.Packets() { + if pn > pnSpace.largestAcked { break } - isRegularPacket := !p.skippedPacket && !p.isPathProbePacket var packetLost bool if !p.SendTime.After(lostSendTime) { packetLost = true - if isRegularPacket { + if !p.isPathProbePacket && p.IsAckEliciting() { if h.logger.Debug() { - h.logger.Debugf("\tlost packet %d (time threshold)", p.PacketNumber) + h.logger.Debugf("\tlost packet %d (time threshold)", pn) } - if h.tracer != nil && h.tracer.LostPacket != nil { - h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossTimeThreshold) + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.PacketLost{ + Header: qlog.PacketHeader{ + PacketType: qlog.EncryptionLevelToPacketType(p.EncryptionLevel), + PacketNumber: pn, + }, + Trigger: qlog.PacketLossTimeThreshold, + }) } } - } else if pnSpace.largestAcked >= p.PacketNumber+packetThreshold { + } else if pnSpace.history.Difference(pnSpace.largestAcked, pn) >= packetThreshold { packetLost = true - if isRegularPacket { + if !p.isPathProbePacket && p.IsAckEliciting() { if h.logger.Debug() { - h.logger.Debugf("\tlost packet %d (reordering threshold)", p.PacketNumber) + h.logger.Debugf("\tlost packet %d (reordering threshold)", pn) } - if h.tracer != nil && h.tracer.LostPacket != nil { - h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossReorderingThreshold) + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.PacketLost{ + Header: qlog.PacketHeader{ + PacketType: qlog.EncryptionLevelToPacketType(p.EncryptionLevel), + PacketNumber: pn, + }, + Trigger: qlog.PacketLossReorderingThreshold, + }) } } } else if pnSpace.lossTime.IsZero() { // Note: This conditional is only entered once per call lossTime := p.SendTime.Add(lossDelay) if h.logger.Debug() { - h.logger.Debugf("\tsetting loss timer for packet %d (%s) to %s (in %s)", p.PacketNumber, encLevel, lossDelay, lossTime) + h.logger.Debugf("\tsetting loss timer for packet %d (%s) to %s (in %s)", pn, encLevel, lossDelay, lossTime) } pnSpace.lossTime = lossTime } if packetLost { - pnSpace.history.DeclareLost(p.PacketNumber) - if isRegularPacket { + if encLevel == protocol.Encryption0RTT || encLevel == protocol.Encryption1RTT { + h.lostPackets.Add(pn, p.SendTime) + } + pnSpace.history.DeclareLost(pn) + if !p.isPathProbePacket && p.IsAckEliciting() { // the bytes in flight need to be reduced no matter if the frames in this packet will be retransmitted h.removeFromBytesInFlight(p) h.queueFramesForRetransmission(p) if !p.IsPathMTUProbePacket { - h.congestion.OnCongestionEvent(p.PacketNumber, p.Length, priorInFlight) + h.congestion.OnCongestionEvent(pn, p.Length, priorInFlight) } if encLevel == protocol.Encryption1RTT && h.ecnTracker != nil { - h.ecnTracker.LostPacket(p.PacketNumber) + h.ecnTracker.LostPacket(pn) } } } } } -func (h *sentPacketHandler) OnLossDetectionTimeout(now time.Time) error { +func (h *sentPacketHandler) OnLossDetectionTimeout(now monotime.Time) error { defer h.setLossDetectionTimer(now) if h.handshakeConfirmed { @@ -741,8 +876,12 @@ func (h *sentPacketHandler) OnLossDetectionTimeout(now time.Time) error { if h.logger.Debug() { h.logger.Debugf("Loss detection alarm fired in loss timer mode. Loss time: %s", earliestLossTime) } - if h.tracer != nil && h.tracer.LossTimerExpired != nil { - h.tracer.LossTimerExpired(logging.TimerTypeACK, encLevel) + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.LossTimerUpdated{ + Type: qlog.LossTimerUpdateTypeExpired, + TimerType: qlog.TimerTypeACK, + EncLevel: encLevel, + }) } // Early retransmit or time loss detection h.detectLostPackets(now, encLevel) @@ -779,13 +918,13 @@ func (h *sentPacketHandler) OnLossDetectionTimeout(now time.Time) error { if h.logger.Debug() { h.logger.Debugf("Loss detection alarm for %s fired in PTO mode. PTO count: %d", encLevel, h.ptoCount) } - if h.tracer != nil { - if h.tracer.LossTimerExpired != nil { - h.tracer.LossTimerExpired(logging.TimerTypePTO, encLevel) - } - if h.tracer.UpdatedPTOCount != nil { - h.tracer.UpdatedPTOCount(h.ptoCount) - } + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.LossTimerUpdated{ + Type: qlog.LossTimerUpdateTypeExpired, + TimerType: qlog.TimerTypePTO, + EncLevel: encLevel, + }) + h.qlogger.RecordEvent(qlog.PTOCountUpdated{PTOCount: h.ptoCount}) } h.numProbesToSend += 2 //nolint:exhaustive // We never arm a PTO timer for 0-RTT packets. @@ -805,7 +944,7 @@ func (h *sentPacketHandler) OnLossDetectionTimeout(now time.Time) error { return nil } -func (h *sentPacketHandler) GetLossDetectionTimeout() time.Time { +func (h *sentPacketHandler) GetLossDetectionTimeout() monotime.Time { return h.alarm.Time } @@ -839,7 +978,7 @@ func (h *sentPacketHandler) PopPacketNumber(encLevel protocol.EncryptionLevel) p return pn } -func (h *sentPacketHandler) SendMode(now time.Time) SendMode { +func (h *sentPacketHandler) SendMode(now monotime.Time) SendMode { numTrackedPackets := h.appDataPackets.history.Len() if h.initialPackets != nil { numTrackedPackets += h.initialPackets.history.Len() @@ -884,7 +1023,7 @@ func (h *sentPacketHandler) SendMode(now time.Time) SendMode { return SendAny } -func (h *sentPacketHandler) TimeUntilSend() time.Time { +func (h *sentPacketHandler) TimeUntilSend() monotime.Time { return h.congestion.TimeUntilSend(h.bytesInFlight) } @@ -901,15 +1040,16 @@ func (h *sentPacketHandler) isAmplificationLimited() bool { func (h *sentPacketHandler) QueueProbePacket(encLevel protocol.EncryptionLevel) bool { pnSpace := h.getPacketNumberSpace(encLevel) - p := pnSpace.history.FirstOutstanding() + pn, p := pnSpace.history.FirstOutstanding() if p == nil { return false } - h.queueFramesForRetransmission(p) // TODO: don't declare the packet lost here. // Keep track of acknowledged frames instead. + // Call DeclareLost before queueFramesForRetransmission, which clears the packet's frames. + pnSpace.history.DeclareLost(pn) h.removeFromBytesInFlight(p) - pnSpace.history.DeclareLost(p.PacketNumber) + h.queueFramesForRetransmission(p) return true } @@ -931,21 +1071,21 @@ func (h *sentPacketHandler) queueFramesForRetransmission(p *packet) { p.Frames = nil } -func (h *sentPacketHandler) ResetForRetry(now time.Time) { +func (h *sentPacketHandler) ResetForRetry(now monotime.Time) { h.bytesInFlight = 0 - var firstPacketSendTime time.Time - for p := range h.initialPackets.history.Packets() { + var firstPacketSendTime monotime.Time + for _, p := range h.initialPackets.history.Packets() { if firstPacketSendTime.IsZero() { firstPacketSendTime = p.SendTime } - if !p.declaredLost && !p.skippedPacket { + if p.IsAckEliciting() { h.queueFramesForRetransmission(p) } } // All application data packets sent at this point are 0-RTT packets. // In the case of a Retry, we can assume that the server dropped all of them. - for p := range h.appDataPackets.history.Packets() { - if !p.declaredLost && !p.skippedPacket { + for _, p := range h.appDataPackets.history.Packets() { + if p.IsAckEliciting() { h.queueFramesForRetransmission(p) } } @@ -958,43 +1098,46 @@ func (h *sentPacketHandler) ResetForRetry(now time.Time) { if h.logger.Debug() { h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation()) } - if h.tracer != nil && h.tracer.UpdatedMetrics != nil { - h.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight()) + if h.qlogger != nil { + h.qlogMetricsUpdated() } } h.initialPackets = newPacketNumberSpace(h.initialPackets.pns.Peek(), false) h.appDataPackets = newPacketNumberSpace(h.appDataPackets.pns.Peek(), true) oldAlarm := h.alarm h.alarm = alarmTimer{} - if h.tracer != nil { - if h.tracer.UpdatedPTOCount != nil { - h.tracer.UpdatedPTOCount(0) - } - if !oldAlarm.Time.IsZero() && h.tracer.LossTimerCanceled != nil { - h.tracer.LossTimerCanceled() + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.PTOCountUpdated{PTOCount: 0}) + if !oldAlarm.Time.IsZero() { + h.qlogger.RecordEvent(qlog.LossTimerUpdated{ + Type: qlog.LossTimerUpdateTypeCancelled, + }) } } h.ptoCount = 0 } -func (h *sentPacketHandler) MigratedPath(now time.Time, initialMaxDatagramSize protocol.ByteCount) { +func (h *sentPacketHandler) MigratedPath(now monotime.Time, initialMaxDatagramSize protocol.ByteCount) { h.rttStats.ResetForPathMigration() - for p := range h.appDataPackets.history.Packets() { - h.appDataPackets.history.DeclareLost(p.PacketNumber) - if !p.skippedPacket && !p.isPathProbePacket { + for pn, p := range h.appDataPackets.history.Packets() { + h.appDataPackets.history.DeclareLost(pn) + if !p.isPathProbePacket { h.removeFromBytesInFlight(p) - h.queueFramesForRetransmission(p) + if p.IsAckEliciting() { + h.queueFramesForRetransmission(p) + } } } - for p := range h.appDataPackets.history.PathProbes() { - h.appDataPackets.history.RemovePathProbe(p.PacketNumber) + for pn := range h.appDataPackets.history.PathProbes() { + h.appDataPackets.history.RemovePathProbe(pn) } h.congestion = congestion.NewCubicSender( congestion.DefaultClock{}, h.rttStats, + h.connStats, initialMaxDatagramSize, true, // use Reno - h.tracer, + h.qlogger, ) h.setLossDetectionTimer(now) } diff --git a/vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_history.go b/vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_history.go index 0aabc6d9..1500e1cd 100644 --- a/vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_history.go +++ b/vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_history.go @@ -3,25 +3,32 @@ package ackhandler import ( "fmt" "iter" + "slices" "github.com/quic-go/quic-go/internal/protocol" ) +const maxSkippedPackets = 4 + type sentPacketHistory struct { packets []*packet - pathProbePackets []*packet + pathProbePackets []packetWithPacketNumber + skippedPackets []protocol.PacketNumber numOutstanding int + firstPacketNumber protocol.PacketNumber highestPacketNumber protocol.PacketNumber } func newSentPacketHistory(isAppData bool) *sentPacketHistory { h := &sentPacketHistory{ highestPacketNumber: protocol.InvalidPacketNumber, + firstPacketNumber: protocol.InvalidPacketNumber, } if isAppData { h.packets = make([]*packet, 0, 32) + h.skippedPackets = make([]protocol.PacketNumber, 0, maxSkippedPackets) } else { h.packets = make([]*packet, 0, 6) } @@ -35,57 +42,56 @@ func (h *sentPacketHistory) checkSequentialPacketNumberUse(pn protocol.PacketNum } } h.highestPacketNumber = pn + if len(h.packets) == 0 { + h.firstPacketNumber = pn + } } func (h *sentPacketHistory) SkippedPacket(pn protocol.PacketNumber) { - h.checkSequentialPacketNumberUse(pn) - h.packets = append(h.packets, &packet{ - PacketNumber: pn, - skippedPacket: true, - }) -} - -func (h *sentPacketHistory) SentNonAckElicitingPacket(pn protocol.PacketNumber) { h.checkSequentialPacketNumberUse(pn) if len(h.packets) > 0 { h.packets = append(h.packets, nil) } + if len(h.skippedPackets) == maxSkippedPackets { + h.skippedPackets = slices.Delete(h.skippedPackets, 0, 1) + } + h.skippedPackets = append(h.skippedPackets, pn) } -func (h *sentPacketHistory) SentAckElicitingPacket(p *packet) { - h.checkSequentialPacketNumberUse(p.PacketNumber) +func (h *sentPacketHistory) SentPacket(pn protocol.PacketNumber, p *packet) { + h.checkSequentialPacketNumberUse(pn) h.packets = append(h.packets, p) - if p.outstanding() { + if p.Outstanding() { h.numOutstanding++ } } -func (h *sentPacketHistory) SentPathProbePacket(p *packet) { - h.checkSequentialPacketNumberUse(p.PacketNumber) - h.packets = append(h.packets, &packet{ - PacketNumber: p.PacketNumber, - isPathProbePacket: true, - }) - h.pathProbePackets = append(h.pathProbePackets, p) +func (h *sentPacketHistory) SentPathProbePacket(pn protocol.PacketNumber, p *packet) { + h.checkSequentialPacketNumberUse(pn) + h.packets = append(h.packets, &packet{isPathProbePacket: true}) + h.pathProbePackets = append(h.pathProbePackets, packetWithPacketNumber{PacketNumber: pn, packet: p}) } -func (h *sentPacketHistory) Packets() iter.Seq[*packet] { - return func(yield func(*packet) bool) { - for _, p := range h.packets { +func (h *sentPacketHistory) Packets() iter.Seq2[protocol.PacketNumber, *packet] { + return func(yield func(protocol.PacketNumber, *packet) bool) { + // h.firstPacketNumber might be updated in the yield function, + // so we need to save it here. + firstPacketNumber := h.firstPacketNumber + for i, p := range h.packets { if p == nil { continue } - if !yield(p) { + if !yield(firstPacketNumber+protocol.PacketNumber(i), p) { return } } } } -func (h *sentPacketHistory) PathProbes() iter.Seq[*packet] { - return func(yield func(*packet) bool) { +func (h *sentPacketHistory) PathProbes() iter.Seq2[protocol.PacketNumber, *packet] { + return func(yield func(protocol.PacketNumber, *packet) bool) { for _, p := range h.pathProbePackets { - if !yield(p) { + if !yield(p.PacketNumber, p.packet) { return } } @@ -93,37 +99,53 @@ func (h *sentPacketHistory) PathProbes() iter.Seq[*packet] { } // FirstOutstanding returns the first outstanding packet. -func (h *sentPacketHistory) FirstOutstanding() *packet { +func (h *sentPacketHistory) FirstOutstanding() (protocol.PacketNumber, *packet) { if !h.HasOutstandingPackets() { - return nil + return protocol.InvalidPacketNumber, nil } - for _, p := range h.packets { - if p != nil && p.outstanding() { - return p + for i, p := range h.packets { + if p != nil && p.Outstanding() { + return h.firstPacketNumber + protocol.PacketNumber(i), p } } - return nil + return protocol.InvalidPacketNumber, nil } // FirstOutstandingPathProbe returns the first outstanding path probe packet -func (h *sentPacketHistory) FirstOutstandingPathProbe() *packet { +func (h *sentPacketHistory) FirstOutstandingPathProbe() (protocol.PacketNumber, *packet) { if len(h.pathProbePackets) == 0 { - return nil + return protocol.InvalidPacketNumber, nil + } + return h.pathProbePackets[0].PacketNumber, h.pathProbePackets[0].packet +} + +func (h *sentPacketHistory) SkippedPackets() iter.Seq[protocol.PacketNumber] { + return func(yield func(protocol.PacketNumber) bool) { + for _, p := range h.skippedPackets { + if !yield(p) { + return + } + } } - return h.pathProbePackets[0] } func (h *sentPacketHistory) Len() int { return len(h.packets) } +func (h *sentPacketHistory) NumOutstanding() int { + return h.numOutstanding +} + +// Remove removes a packet from the sent packet history. +// It must not be used for skipped packet numbers. func (h *sentPacketHistory) Remove(pn protocol.PacketNumber) error { idx, ok := h.getIndex(pn) if !ok { return fmt.Errorf("packet %d not found in sent packet history", pn) } p := h.packets[idx] - if p.outstanding() { + if p.Outstanding() { h.numOutstanding-- if h.numOutstanding < 0 { panic("negative number of outstanding packets") @@ -131,19 +153,19 @@ func (h *sentPacketHistory) Remove(pn protocol.PacketNumber) error { } h.packets[idx] = nil // clean up all skipped packets directly before this packet number + var hasPacketBefore bool for idx > 0 { idx-- - p := h.packets[idx] - if p == nil || !p.skippedPacket { + if h.packets[idx] != nil { + hasPacketBefore = true break } - h.packets[idx] = nil } - if idx == 0 { + if !hasPacketBefore { h.cleanupStart() } if len(h.packets) > 0 && h.packets[0] == nil { - panic("remove failed") + panic("cleanup failed") } return nil } @@ -156,7 +178,7 @@ func (h *sentPacketHistory) RemovePathProbe(pn protocol.PacketNumber) *packet { idx := -1 for i, p := range h.pathProbePackets { if p.PacketNumber == pn { - packetToDelete = p + packetToDelete = p.packet idx = i break } @@ -174,11 +196,10 @@ func (h *sentPacketHistory) getIndex(p protocol.PacketNumber) (int, bool) { if len(h.packets) == 0 { return 0, false } - first := h.packets[0].PacketNumber - if p < first { + if p < h.firstPacketNumber { return 0, false } - index := int(p - first) + index := int(p - h.firstPacketNumber) if index > len(h.packets)-1 { return 0, false } @@ -198,17 +219,19 @@ func (h *sentPacketHistory) cleanupStart() { for i, p := range h.packets { if p != nil { h.packets = h.packets[i:] + h.firstPacketNumber += protocol.PacketNumber(i) return } } h.packets = h.packets[:0] + h.firstPacketNumber = protocol.InvalidPacketNumber } func (h *sentPacketHistory) LowestPacketNumber() protocol.PacketNumber { if len(h.packets) == 0 { return protocol.InvalidPacketNumber } - return h.packets[0].PacketNumber + return h.firstPacketNumber } func (h *sentPacketHistory) DeclareLost(pn protocol.PacketNumber) { @@ -217,7 +240,7 @@ func (h *sentPacketHistory) DeclareLost(pn protocol.PacketNumber) { return } p := h.packets[idx] - if p.outstanding() { + if p.Outstanding() { h.numOutstanding-- if h.numOutstanding < 0 { panic("negative number of outstanding packets") @@ -228,3 +251,24 @@ func (h *sentPacketHistory) DeclareLost(pn protocol.PacketNumber) { h.cleanupStart() } } + +// Difference returns the difference between two packet numbers a and b (a - b), +// taking into account any skipped packet numbers between them. +// +// Note that old skipped packets are garbage collected at some point, +// so this function is not guaranteed to return the correct result after a while. +func (h *sentPacketHistory) Difference(a, b protocol.PacketNumber) protocol.PacketNumber { + diff := a - b + if len(h.skippedPackets) == 0 { + return diff + } + if a < h.skippedPackets[0] || b > h.skippedPackets[len(h.skippedPackets)-1] { + return diff + } + for _, p := range h.skippedPackets { + if p > b && p < a { + diff-- + } + } + return diff +} diff --git a/vendor/github.com/quic-go/quic-go/internal/congestion/bandwidth.go b/vendor/github.com/quic-go/quic-go/internal/congestion/bandwidth.go index 1d03abbb..3ad827d2 100644 --- a/vendor/github.com/quic-go/quic-go/internal/congestion/bandwidth.go +++ b/vendor/github.com/quic-go/quic-go/internal/congestion/bandwidth.go @@ -1,7 +1,6 @@ package congestion import ( - "math" "time" "github.com/quic-go/quic-go/internal/protocol" @@ -10,8 +9,6 @@ import ( // Bandwidth of a connection type Bandwidth uint64 -const infBandwidth Bandwidth = math.MaxUint64 - const ( // BitsPerSecond is 1 bit per second BitsPerSecond Bandwidth = 1 diff --git a/vendor/github.com/quic-go/quic-go/internal/congestion/clock.go b/vendor/github.com/quic-go/quic-go/internal/congestion/clock.go index 405fae70..8315026f 100644 --- a/vendor/github.com/quic-go/quic-go/internal/congestion/clock.go +++ b/vendor/github.com/quic-go/quic-go/internal/congestion/clock.go @@ -1,10 +1,12 @@ package congestion -import "time" +import ( + "github.com/quic-go/quic-go/internal/monotime" +) // A Clock returns the current time type Clock interface { - Now() time.Time + Now() monotime.Time } // DefaultClock implements the Clock interface using the Go stdlib clock. @@ -13,6 +15,6 @@ type DefaultClock struct{} var _ Clock = DefaultClock{} // Now gets the current time -func (DefaultClock) Now() time.Time { - return time.Now() +func (DefaultClock) Now() monotime.Time { + return monotime.Now() } diff --git a/vendor/github.com/quic-go/quic-go/internal/congestion/cubic.go b/vendor/github.com/quic-go/quic-go/internal/congestion/cubic.go index b35d40d4..40655de6 100644 --- a/vendor/github.com/quic-go/quic-go/internal/congestion/cubic.go +++ b/vendor/github.com/quic-go/quic-go/internal/congestion/cubic.go @@ -4,6 +4,7 @@ import ( "math" "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" ) @@ -42,7 +43,7 @@ type Cubic struct { numConnections int // Time when this cycle started, after last loss event. - epoch time.Time + epoch monotime.Time // Max congestion window used just before last loss event. // Note: to improve fairness to other streams an additional back off is @@ -77,7 +78,7 @@ func NewCubic(clock Clock) *Cubic { // Reset is called after a timeout to reset the cubic state func (c *Cubic) Reset() { - c.epoch = time.Time{} + c.epoch = 0 c.lastMaxCongestionWindow = 0 c.ackedBytesCount = 0 c.estimatedTCPcongestionWindow = 0 @@ -121,7 +122,7 @@ func (c *Cubic) OnApplicationLimited() { // in such a period. This reset effectively freezes congestion window growth // through application-limited periods and allows Cubic growth to continue // when the entire window is being used. - c.epoch = time.Time{} + c.epoch = 0 } // CongestionWindowAfterPacketLoss computes a new congestion window to use after @@ -135,7 +136,7 @@ func (c *Cubic) CongestionWindowAfterPacketLoss(currentCongestionWindow protocol } else { c.lastMaxCongestionWindow = currentCongestionWindow } - c.epoch = time.Time{} // Reset time. + c.epoch = 0 // Reset time. return protocol.ByteCount(float32(currentCongestionWindow) * c.beta()) } @@ -147,7 +148,7 @@ func (c *Cubic) CongestionWindowAfterAck( ackedBytes protocol.ByteCount, currentCongestionWindow protocol.ByteCount, delayMin time.Duration, - eventTime time.Time, + eventTime monotime.Time, ) protocol.ByteCount { c.ackedBytesCount += ackedBytes diff --git a/vendor/github.com/quic-go/quic-go/internal/congestion/cubic_sender.go b/vendor/github.com/quic-go/quic-go/internal/congestion/cubic_sender.go index 075b08e0..e5457ddb 100644 --- a/vendor/github.com/quic-go/quic-go/internal/congestion/cubic_sender.go +++ b/vendor/github.com/quic-go/quic-go/internal/congestion/cubic_sender.go @@ -2,11 +2,12 @@ package congestion import ( "fmt" - "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" + "github.com/quic-go/quic-go/qlogwriter" ) const ( @@ -22,6 +23,7 @@ const ( type cubicSender struct { hybridSlowStart HybridSlowStart rttStats *utils.RTTStats + connStats *utils.ConnectionStats cubic *Cubic pacer *pacer clock Clock @@ -55,8 +57,8 @@ type cubicSender struct { maxDatagramSize protocol.ByteCount - lastState logging.CongestionState - tracer *logging.ConnectionTracer + lastState qlog.CongestionState + qlogger qlogwriter.Recorder } var ( @@ -68,32 +70,36 @@ var ( func NewCubicSender( clock Clock, rttStats *utils.RTTStats, + connStats *utils.ConnectionStats, initialMaxDatagramSize protocol.ByteCount, reno bool, - tracer *logging.ConnectionTracer, + qlogger qlogwriter.Recorder, ) *cubicSender { return newCubicSender( clock, rttStats, + connStats, reno, initialMaxDatagramSize, initialCongestionWindow*initialMaxDatagramSize, protocol.MaxCongestionWindowPackets*initialMaxDatagramSize, - tracer, + qlogger, ) } func newCubicSender( clock Clock, rttStats *utils.RTTStats, + connStats *utils.ConnectionStats, reno bool, initialMaxDatagramSize, initialCongestionWindow, initialMaxCongestionWindow protocol.ByteCount, - tracer *logging.ConnectionTracer, + qlogger qlogwriter.Recorder, ) *cubicSender { c := &cubicSender{ rttStats: rttStats, + connStats: connStats, largestSentPacketNumber: protocol.InvalidPacketNumber, largestAckedPacketNumber: protocol.InvalidPacketNumber, largestSentAtLastCutback: protocol.InvalidPacketNumber, @@ -104,23 +110,25 @@ func newCubicSender( cubic: NewCubic(clock), clock: clock, reno: reno, - tracer: tracer, + qlogger: qlogger, maxDatagramSize: initialMaxDatagramSize, } c.pacer = newPacer(c.BandwidthEstimate) - if c.tracer != nil && c.tracer.UpdatedCongestionState != nil { - c.lastState = logging.CongestionStateSlowStart - c.tracer.UpdatedCongestionState(logging.CongestionStateSlowStart) + if c.qlogger != nil { + c.lastState = qlog.CongestionStateSlowStart + c.qlogger.RecordEvent(qlog.CongestionStateUpdated{ + State: qlog.CongestionStateSlowStart, + }) } return c } // TimeUntilSend returns when the next packet should be sent. -func (c *cubicSender) TimeUntilSend(_ protocol.ByteCount) time.Time { +func (c *cubicSender) TimeUntilSend(_ protocol.ByteCount) monotime.Time { return c.pacer.TimeUntilSend() } -func (c *cubicSender) HasPacingBudget(now time.Time) bool { +func (c *cubicSender) HasPacingBudget(now monotime.Time) bool { return c.pacer.Budget(now) >= c.maxDatagramSize } @@ -133,7 +141,7 @@ func (c *cubicSender) minCongestionWindow() protocol.ByteCount { } func (c *cubicSender) OnPacketSent( - sentTime time.Time, + sentTime monotime.Time, _ protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, @@ -168,7 +176,7 @@ func (c *cubicSender) MaybeExitSlowStart() { c.hybridSlowStart.ShouldExitSlowStart(c.rttStats.LatestRTT(), c.rttStats.MinRTT(), c.GetCongestionWindow()/c.maxDatagramSize) { // exit slow start c.slowStartThreshold = c.congestionWindow - c.maybeTraceStateChange(logging.CongestionStateCongestionAvoidance) + c.maybeQlogStateChange(qlog.CongestionStateCongestionAvoidance) } } @@ -176,7 +184,7 @@ func (c *cubicSender) OnPacketAcked( ackedPacketNumber protocol.PacketNumber, ackedBytes protocol.ByteCount, priorInFlight protocol.ByteCount, - eventTime time.Time, + eventTime monotime.Time, ) { c.largestAckedPacketNumber = max(ackedPacketNumber, c.largestAckedPacketNumber) if c.InRecovery() { @@ -189,13 +197,16 @@ func (c *cubicSender) OnPacketAcked( } func (c *cubicSender) OnCongestionEvent(packetNumber protocol.PacketNumber, lostBytes, priorInFlight protocol.ByteCount) { + c.connStats.PacketsLost.Add(1) + c.connStats.BytesLost.Add(uint64(lostBytes)) + // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets // already sent should be treated as a single loss event, since it's expected. if packetNumber <= c.largestSentAtLastCutback { return } c.lastCutbackExitedSlowstart = c.InSlowStart() - c.maybeTraceStateChange(logging.CongestionStateRecovery) + c.maybeQlogStateChange(qlog.CongestionStateRecovery) if c.reno { c.congestionWindow = protocol.ByteCount(float64(c.congestionWindow) * renoBeta) @@ -218,13 +229,13 @@ func (c *cubicSender) maybeIncreaseCwnd( _ protocol.PacketNumber, ackedBytes protocol.ByteCount, priorInFlight protocol.ByteCount, - eventTime time.Time, + eventTime monotime.Time, ) { // Do not increase the congestion window unless the sender is close to using // the current window. if !c.isCwndLimited(priorInFlight) { c.cubic.OnApplicationLimited() - c.maybeTraceStateChange(logging.CongestionStateApplicationLimited) + c.maybeQlogStateChange(qlog.CongestionStateApplicationLimited) return } if c.congestionWindow >= c.maxCongestionWindow() { @@ -233,11 +244,11 @@ func (c *cubicSender) maybeIncreaseCwnd( if c.InSlowStart() { // TCP slow start, exponential growth, increase by one for each ACK. c.congestionWindow += c.maxDatagramSize - c.maybeTraceStateChange(logging.CongestionStateSlowStart) + c.maybeQlogStateChange(qlog.CongestionStateSlowStart) return } // Congestion avoidance - c.maybeTraceStateChange(logging.CongestionStateCongestionAvoidance) + c.maybeQlogStateChange(qlog.CongestionStateCongestionAvoidance) if c.reno { // Classic Reno congestion avoidance. c.numAckedPackets++ @@ -246,7 +257,10 @@ func (c *cubicSender) maybeIncreaseCwnd( c.numAckedPackets = 0 } } else { - c.congestionWindow = min(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime)) + c.congestionWindow = min( + c.maxCongestionWindow(), + c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime), + ) } } @@ -264,8 +278,8 @@ func (c *cubicSender) isCwndLimited(bytesInFlight protocol.ByteCount) bool { func (c *cubicSender) BandwidthEstimate() Bandwidth { srtt := c.rttStats.SmoothedRTT() if srtt == 0 { - // If we haven't measured an rtt, the bandwidth estimate is unknown. - return infBandwidth + // This should never happen, but if it does, avoid division by zero. + srtt = protocol.TimerGranularity } return BandwidthFromDelta(c.GetCongestionWindow(), srtt) } @@ -295,11 +309,11 @@ func (c *cubicSender) OnConnectionMigration() { c.slowStartThreshold = c.initialMaxCongestionWindow } -func (c *cubicSender) maybeTraceStateChange(new logging.CongestionState) { - if c.tracer == nil || c.tracer.UpdatedCongestionState == nil || new == c.lastState { +func (c *cubicSender) maybeQlogStateChange(new qlog.CongestionState) { + if c.qlogger == nil || new == c.lastState { return } - c.tracer.UpdatedCongestionState(new) + c.qlogger.RecordEvent(qlog.CongestionStateUpdated{State: new}) c.lastState = new } diff --git a/vendor/github.com/quic-go/quic-go/internal/congestion/interface.go b/vendor/github.com/quic-go/quic-go/internal/congestion/interface.go index 881f453b..996907c6 100644 --- a/vendor/github.com/quic-go/quic-go/internal/congestion/interface.go +++ b/vendor/github.com/quic-go/quic-go/internal/congestion/interface.go @@ -1,19 +1,18 @@ package congestion import ( - "time" - + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" ) // A SendAlgorithm performs congestion control type SendAlgorithm interface { - TimeUntilSend(bytesInFlight protocol.ByteCount) time.Time - HasPacingBudget(now time.Time) bool - OnPacketSent(sentTime time.Time, bytesInFlight protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, isRetransmittable bool) + TimeUntilSend(bytesInFlight protocol.ByteCount) monotime.Time + HasPacingBudget(now monotime.Time) bool + OnPacketSent(sentTime monotime.Time, bytesInFlight protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, isRetransmittable bool) CanSend(bytesInFlight protocol.ByteCount) bool MaybeExitSlowStart() - OnPacketAcked(number protocol.PacketNumber, ackedBytes protocol.ByteCount, priorInFlight protocol.ByteCount, eventTime time.Time) + OnPacketAcked(number protocol.PacketNumber, ackedBytes protocol.ByteCount, priorInFlight protocol.ByteCount, eventTime monotime.Time) OnCongestionEvent(number protocol.PacketNumber, lostBytes protocol.ByteCount, priorInFlight protocol.ByteCount) OnRetransmissionTimeout(packetsRetransmitted bool) SetMaxDatagramSize(protocol.ByteCount) diff --git a/vendor/github.com/quic-go/quic-go/internal/congestion/pacer.go b/vendor/github.com/quic-go/quic-go/internal/congestion/pacer.go index 34d3d1d0..7656f529 100644 --- a/vendor/github.com/quic-go/quic-go/internal/congestion/pacer.go +++ b/vendor/github.com/quic-go/quic-go/internal/congestion/pacer.go @@ -1,8 +1,10 @@ package congestion import ( + "math" "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" ) @@ -12,7 +14,7 @@ const maxBurstSizePackets = 10 type pacer struct { budgetAtLastSent protocol.ByteCount maxDatagramSize protocol.ByteCount - lastSentTime time.Time + lastSentTime monotime.Time adjustedBandwidth func() uint64 // in bytes/s } @@ -33,7 +35,7 @@ func newPacer(getBandwidth func() Bandwidth) *pacer { return p } -func (p *pacer) SentPacket(sendTime time.Time, size protocol.ByteCount) { +func (p *pacer) SentPacket(sendTime monotime.Time, size protocol.ByteCount) { budget := p.Budget(sendTime) if size >= budget { p.budgetAtLastSent = 0 @@ -43,12 +45,17 @@ func (p *pacer) SentPacket(sendTime time.Time, size protocol.ByteCount) { p.lastSentTime = sendTime } -func (p *pacer) Budget(now time.Time) protocol.ByteCount { +func (p *pacer) Budget(now monotime.Time) protocol.ByteCount { if p.lastSentTime.IsZero() { return p.maxBurstSize() } - budget := p.budgetAtLastSent + (protocol.ByteCount(p.adjustedBandwidth())*protocol.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9 - if budget < 0 { // protect against overflows + delta := now.Sub(p.lastSentTime) + var added protocol.ByteCount + if delta > 0 { + added = p.timeScaledBandwidth(uint64(delta.Nanoseconds())) + } + budget := p.budgetAtLastSent + added + if added > 0 && budget < p.budgetAtLastSent { budget = protocol.MaxByteCount } return min(p.maxBurstSize(), budget) @@ -56,16 +63,35 @@ func (p *pacer) Budget(now time.Time) protocol.ByteCount { func (p *pacer) maxBurstSize() protocol.ByteCount { return max( - protocol.ByteCount(uint64((protocol.MinPacingDelay+protocol.TimerGranularity).Nanoseconds())*p.adjustedBandwidth())/1e9, + p.timeScaledBandwidth(uint64((protocol.MinPacingDelay + protocol.TimerGranularity).Nanoseconds())), maxBurstSizePackets*p.maxDatagramSize, ) } +// timeScaledBandwidth calculates the number of bytes that may be sent within +// a given time interval (ns nanoseconds), based on the current bandwidth estimate. +// It caps the scaled value to the maximum allowed burst and handles overflows. +func (p *pacer) timeScaledBandwidth(ns uint64) protocol.ByteCount { + bw := p.adjustedBandwidth() + if bw == 0 { + return 0 + } + const nsPerSecond = 1e9 + maxBurst := maxBurstSizePackets * p.maxDatagramSize + var scaled protocol.ByteCount + if ns > math.MaxUint64/bw { + scaled = maxBurst + } else { + scaled = protocol.ByteCount(bw * ns / nsPerSecond) + } + return scaled +} + // TimeUntilSend returns when the next packet should be sent. -// It returns the zero value of time.Time if a packet can be sent immediately. -func (p *pacer) TimeUntilSend() time.Time { +// It returns zero if a packet can be sent immediately. +func (p *pacer) TimeUntilSend() monotime.Time { if p.budgetAtLastSent >= p.maxDatagramSize { - return time.Time{} + return 0 } diff := 1e9 * uint64(p.maxDatagramSize-p.budgetAtLastSent) bw := p.adjustedBandwidth() diff --git a/vendor/github.com/quic-go/quic-go/internal/flowcontrol/base_flow_controller.go b/vendor/github.com/quic-go/quic-go/internal/flowcontrol/base_flow_controller.go index 950e5f72..04a9f98e 100644 --- a/vendor/github.com/quic-go/quic-go/internal/flowcontrol/base_flow_controller.go +++ b/vendor/github.com/quic-go/quic-go/internal/flowcontrol/base_flow_controller.go @@ -4,6 +4,7 @@ import ( "sync" "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" ) @@ -25,7 +26,7 @@ type baseFlowController struct { allowWindowIncrease func(size protocol.ByteCount) bool - epochStartTime time.Time + epochStartTime monotime.Time epochStartOffset protocol.ByteCount rttStats *utils.RTTStats @@ -77,7 +78,7 @@ func (c *baseFlowController) hasWindowUpdate() bool { // getWindowUpdate updates the receive window, if necessary // it returns the new offset -func (c *baseFlowController) getWindowUpdate(now time.Time) protocol.ByteCount { +func (c *baseFlowController) getWindowUpdate(now monotime.Time) protocol.ByteCount { if !c.hasWindowUpdate() { return 0 } @@ -89,7 +90,7 @@ func (c *baseFlowController) getWindowUpdate(now time.Time) protocol.ByteCount { // maybeAdjustWindowSize increases the receiveWindowSize if we're sending updates too often. // For details about auto-tuning, see https://docs.google.com/document/d/1SExkMmGiz8VYzV3s9E35JQlJ73vhzCekKkDi85F1qCE/edit?usp=sharing. -func (c *baseFlowController) maybeAdjustWindowSize(now time.Time) { +func (c *baseFlowController) maybeAdjustWindowSize(now monotime.Time) { bytesReadInEpoch := c.bytesRead - c.epochStartOffset // don't do anything if less than half the window has been consumed if bytesReadInEpoch <= c.receiveWindowSize/2 { @@ -111,7 +112,7 @@ func (c *baseFlowController) maybeAdjustWindowSize(now time.Time) { c.startNewAutoTuningEpoch(now) } -func (c *baseFlowController) startNewAutoTuningEpoch(now time.Time) { +func (c *baseFlowController) startNewAutoTuningEpoch(now monotime.Time) { c.epochStartTime = now c.epochStartOffset = c.bytesRead } diff --git a/vendor/github.com/quic-go/quic-go/internal/flowcontrol/connection_flow_controller.go b/vendor/github.com/quic-go/quic-go/internal/flowcontrol/connection_flow_controller.go index c550e75a..0c74dcc9 100644 --- a/vendor/github.com/quic-go/quic-go/internal/flowcontrol/connection_flow_controller.go +++ b/vendor/github.com/quic-go/quic-go/internal/flowcontrol/connection_flow_controller.go @@ -3,8 +3,8 @@ package flowcontrol import ( "errors" "fmt" - "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/utils" @@ -38,7 +38,7 @@ func NewConnectionFlowController( } // IncrementHighestReceived adds an increment to the highestReceived value -func (c *connectionFlowController) IncrementHighestReceived(increment protocol.ByteCount, now time.Time) error { +func (c *connectionFlowController) IncrementHighestReceived(increment protocol.ByteCount, now monotime.Time) error { c.mutex.Lock() defer c.mutex.Unlock() @@ -65,7 +65,7 @@ func (c *connectionFlowController) AddBytesRead(n protocol.ByteCount) (hasWindow return c.hasWindowUpdate() } -func (c *connectionFlowController) GetWindowUpdate(now time.Time) protocol.ByteCount { +func (c *connectionFlowController) GetWindowUpdate(now monotime.Time) protocol.ByteCount { c.mutex.Lock() defer c.mutex.Unlock() @@ -79,7 +79,7 @@ func (c *connectionFlowController) GetWindowUpdate(now time.Time) protocol.ByteC // EnsureMinimumWindowSize sets a minimum window size // it should make sure that the connection-level window is increased when a stream-level window grows -func (c *connectionFlowController) EnsureMinimumWindowSize(inc protocol.ByteCount, now time.Time) { +func (c *connectionFlowController) EnsureMinimumWindowSize(inc protocol.ByteCount, now monotime.Time) { c.mutex.Lock() defer c.mutex.Unlock() diff --git a/vendor/github.com/quic-go/quic-go/internal/flowcontrol/interface.go b/vendor/github.com/quic-go/quic-go/internal/flowcontrol/interface.go index 23cf30c5..e95c65d9 100644 --- a/vendor/github.com/quic-go/quic-go/internal/flowcontrol/interface.go +++ b/vendor/github.com/quic-go/quic-go/internal/flowcontrol/interface.go @@ -1,8 +1,7 @@ package flowcontrol import ( - "time" - + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" ) @@ -12,7 +11,7 @@ type flowController interface { UpdateSendWindow(protocol.ByteCount) (updated bool) AddBytesSent(protocol.ByteCount) // for receiving - GetWindowUpdate(time.Time) protocol.ByteCount // returns 0 if no update is necessary + GetWindowUpdate(monotime.Time) protocol.ByteCount // returns 0 if no update is necessary } // A StreamFlowController is a flow controller for a QUIC stream. @@ -22,7 +21,7 @@ type StreamFlowController interface { // UpdateHighestReceived is called when a new highest offset is received // final has to be to true if this is the final offset of the stream, // as contained in a STREAM frame with FIN bit, and the RESET_STREAM frame - UpdateHighestReceived(offset protocol.ByteCount, final bool, now time.Time) error + UpdateHighestReceived(offset protocol.ByteCount, final bool, now monotime.Time) error // Abandon is called when reading from the stream is aborted early, // and there won't be any further calls to AddBytesRead. Abandon() @@ -41,7 +40,7 @@ type connectionFlowControllerI interface { ConnectionFlowController // The following two methods are not supposed to be called from outside this packet, but are needed internally // for sending - EnsureMinimumWindowSize(protocol.ByteCount, time.Time) + EnsureMinimumWindowSize(protocol.ByteCount, monotime.Time) // for receiving - IncrementHighestReceived(protocol.ByteCount, time.Time) error + IncrementHighestReceived(protocol.ByteCount, monotime.Time) error } diff --git a/vendor/github.com/quic-go/quic-go/internal/flowcontrol/stream_flow_controller.go b/vendor/github.com/quic-go/quic-go/internal/flowcontrol/stream_flow_controller.go index 968e9a5b..ccbfe9cd 100644 --- a/vendor/github.com/quic-go/quic-go/internal/flowcontrol/stream_flow_controller.go +++ b/vendor/github.com/quic-go/quic-go/internal/flowcontrol/stream_flow_controller.go @@ -2,8 +2,8 @@ package flowcontrol import ( "fmt" - "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/utils" @@ -46,7 +46,7 @@ func NewStreamFlowController( } // UpdateHighestReceived updates the highestReceived value, if the offset is higher. -func (c *streamFlowController) UpdateHighestReceived(offset protocol.ByteCount, final bool, now time.Time) error { +func (c *streamFlowController) UpdateHighestReceived(offset protocol.ByteCount, final bool, now monotime.Time) error { // If the final offset for this stream is already known, check for consistency. if c.receivedFinalOffset { // If we receive another final offset, check that it's the same. @@ -135,7 +135,7 @@ func (c *streamFlowController) shouldQueueWindowUpdate() bool { return !c.receivedFinalOffset && c.hasWindowUpdate() } -func (c *streamFlowController) GetWindowUpdate(now time.Time) protocol.ByteCount { +func (c *streamFlowController) GetWindowUpdate(now monotime.Time) protocol.ByteCount { // If we already received the final offset for this stream, the peer won't need any additional flow control credit. if c.receivedFinalOffset { return 0 diff --git a/vendor/github.com/quic-go/quic-go/internal/handshake/aead.go b/vendor/github.com/quic-go/quic-go/internal/handshake/aead.go index 1baf5d6b..ce83ab18 100644 --- a/vendor/github.com/quic-go/quic-go/internal/handshake/aead.go +++ b/vendor/github.com/quic-go/quic-go/internal/handshake/aead.go @@ -6,7 +6,7 @@ import ( "github.com/quic-go/quic-go/internal/protocol" ) -func createAEAD(suite *cipherSuite, trafficSecret []byte, v protocol.Version) *xorNonceAEAD { +func createAEAD(suite cipherSuite, trafficSecret []byte, v protocol.Version) *xorNonceAEAD { keyLabel := hkdfLabelKeyV1 ivLabel := hkdfLabelIVV1 if v == protocol.Version2 { diff --git a/vendor/github.com/quic-go/quic-go/internal/handshake/cipher_suite.go b/vendor/github.com/quic-go/quic-go/internal/handshake/cipher_suite.go index e7fa8e3d..612cefa2 100644 --- a/vendor/github.com/quic-go/quic-go/internal/handshake/cipher_suite.go +++ b/vendor/github.com/quic-go/quic-go/internal/handshake/cipher_suite.go @@ -23,14 +23,14 @@ type cipherSuite struct { func (s cipherSuite) IVLen() int { return aeadNonceLength } -func getCipherSuite(id uint16) *cipherSuite { +func getCipherSuite(id uint16) cipherSuite { switch id { case tls.TLS_AES_128_GCM_SHA256: - return &cipherSuite{ID: tls.TLS_AES_128_GCM_SHA256, Hash: crypto.SHA256, KeyLen: 16, AEAD: aeadAESGCMTLS13} + return cipherSuite{ID: tls.TLS_AES_128_GCM_SHA256, Hash: crypto.SHA256, KeyLen: 16, AEAD: aeadAESGCMTLS13} case tls.TLS_CHACHA20_POLY1305_SHA256: - return &cipherSuite{ID: tls.TLS_CHACHA20_POLY1305_SHA256, Hash: crypto.SHA256, KeyLen: 32, AEAD: aeadChaCha20Poly1305} + return cipherSuite{ID: tls.TLS_CHACHA20_POLY1305_SHA256, Hash: crypto.SHA256, KeyLen: 32, AEAD: aeadChaCha20Poly1305} case tls.TLS_AES_256_GCM_SHA384: - return &cipherSuite{ID: tls.TLS_AES_256_GCM_SHA384, Hash: crypto.SHA384, KeyLen: 32, AEAD: aeadAESGCMTLS13} + return cipherSuite{ID: tls.TLS_AES_256_GCM_SHA384, Hash: crypto.SHA384, KeyLen: 32, AEAD: aeadAESGCMTLS13} default: panic(fmt.Sprintf("unknown cypher suite: %d", id)) } diff --git a/vendor/github.com/quic-go/quic-go/internal/handshake/crypto_setup.go b/vendor/github.com/quic-go/quic-go/internal/handshake/crypto_setup.go index 1a86c675..d481ac67 100644 --- a/vendor/github.com/quic-go/quic-go/internal/handshake/crypto_setup.go +++ b/vendor/github.com/quic-go/quic-go/internal/handshake/crypto_setup.go @@ -14,7 +14,8 @@ import ( "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" + "github.com/quic-go/quic-go/qlogwriter" "github.com/quic-go/quic-go/quicvarint" ) @@ -22,7 +23,7 @@ type quicVersionContextKey struct{} var QUICVersionContextKey = &quicVersionContextKey{} -const clientSessionStateRevision = 4 +const clientSessionStateRevision = 5 type cryptoSetup struct { tlsConf *tls.Config @@ -40,8 +41,8 @@ type cryptoSetup struct { rttStats *utils.RTTStats - tracer *logging.ConnectionTracer - logger utils.Logger + qlogger qlogwriter.Recorder + logger utils.Logger perspective protocol.Perspective @@ -72,7 +73,7 @@ func NewCryptoSetupClient( tlsConf *tls.Config, enable0RTT bool, rttStats *utils.RTTStats, - tracer *logging.ConnectionTracer, + qlogger qlogwriter.Recorder, logger utils.Logger, version protocol.Version, ) CryptoSetup { @@ -80,7 +81,7 @@ func NewCryptoSetupClient( connID, tp, rttStats, - tracer, + qlogger, logger, protocol.PerspectiveClient, version, @@ -108,7 +109,7 @@ func NewCryptoSetupServer( tlsConf *tls.Config, allow0RTT bool, rttStats *utils.RTTStats, - tracer *logging.ConnectionTracer, + qlogger qlogwriter.Recorder, logger utils.Logger, version protocol.Version, ) CryptoSetup { @@ -116,7 +117,7 @@ func NewCryptoSetupServer( connID, tp, rttStats, - tracer, + qlogger, logger, protocol.PerspectiveServer, version, @@ -137,24 +138,30 @@ func newCryptoSetup( connID protocol.ConnectionID, tp *wire.TransportParameters, rttStats *utils.RTTStats, - tracer *logging.ConnectionTracer, + qlogger qlogwriter.Recorder, logger utils.Logger, perspective protocol.Perspective, version protocol.Version, ) *cryptoSetup { initialSealer, initialOpener := NewInitialAEAD(connID, perspective, version) - if tracer != nil && tracer.UpdatedKeyFromTLS != nil { - tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveClient) - tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveServer) + if qlogger != nil { + qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateTLS, + KeyType: encLevelToKeyType(protocol.EncryptionInitial, protocol.PerspectiveClient), + }) + qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateTLS, + KeyType: encLevelToKeyType(protocol.EncryptionInitial, protocol.PerspectiveServer), + }) } return &cryptoSetup{ initialSealer: initialSealer, initialOpener: initialOpener, - aead: newUpdatableAEAD(rttStats, tracer, logger, version), + aead: newUpdatableAEAD(rttStats, qlogger, logger, version), events: make([]Event, 0, 16), ourParams: tp, rttStats: rttStats, - tracer: tracer, + qlogger: qlogger, logger: logger, perspective: perspective, version: version, @@ -165,9 +172,15 @@ func (h *cryptoSetup) ChangeConnectionID(id protocol.ConnectionID) { initialSealer, initialOpener := NewInitialAEAD(id, h.perspective, h.version) h.initialSealer = initialSealer h.initialOpener = initialOpener - if h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil { - h.tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveClient) - h.tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveServer) + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateTLS, + KeyType: encLevelToKeyType(protocol.EncryptionInitial, protocol.PerspectiveClient), + }) + h.qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateTLS, + KeyType: encLevelToKeyType(protocol.EncryptionInitial, protocol.PerspectiveServer), + }) } } @@ -314,7 +327,6 @@ func (h *cryptoSetup) handleTransportParameters(data []byte) error { func (h *cryptoSetup) marshalDataForSessionState(earlyData bool) []byte { b := make([]byte, 0, 256) b = quicvarint.Append(b, clientSessionStateRevision) - b = quicvarint.Append(b, uint64(h.rttStats.SmoothedRTT().Microseconds())) if earlyData { // only save the transport parameters for 0-RTT enabled session tickets return h.peerParams.MarshalForSessionTicket(b) @@ -323,12 +335,11 @@ func (h *cryptoSetup) marshalDataForSessionState(earlyData bool) []byte { } func (h *cryptoSetup) handleDataFromSessionState(data []byte, earlyData bool) (allowEarlyData bool) { - rtt, tp, err := decodeDataFromSessionState(data, earlyData) + tp, err := decodeDataFromSessionState(data, earlyData) if err != nil { h.logger.Debugf("Restoring of transport parameters from session ticket failed: %s", err.Error()) return } - h.rttStats.SetInitialRTT(rtt) // The session ticket might have been saved from a connection that allowed 0-RTT, // and therefore contain transport parameters. // Only use them if 0-RTT is actually used on the new connection. @@ -339,39 +350,29 @@ func (h *cryptoSetup) handleDataFromSessionState(data []byte, earlyData bool) (a return false } -func decodeDataFromSessionState(b []byte, earlyData bool) (time.Duration, *wire.TransportParameters, error) { +func decodeDataFromSessionState(b []byte, earlyData bool) (*wire.TransportParameters, error) { ver, l, err := quicvarint.Parse(b) if err != nil { - return 0, nil, err + return nil, err } b = b[l:] if ver != clientSessionStateRevision { - return 0, nil, fmt.Errorf("mismatching version. Got %d, expected %d", ver, clientSessionStateRevision) + return nil, fmt.Errorf("mismatching version. Got %d, expected %d", ver, clientSessionStateRevision) } - rttEncoded, l, err := quicvarint.Parse(b) - if err != nil { - return 0, nil, err - } - b = b[l:] - rtt := time.Duration(rttEncoded) * time.Microsecond if !earlyData { - return rtt, nil, nil + return nil, nil } var tp wire.TransportParameters if err := tp.UnmarshalFromSessionTicket(b); err != nil { - return 0, nil, err + return nil, err } - return rtt, &tp, nil + return &tp, nil } func (h *cryptoSetup) getDataForSessionTicket() []byte { - ticket := &sessionTicket{ - RTT: h.rttStats.SmoothedRTT(), - } - if h.allow0RTT { - ticket.Parameters = h.ourParams - } - return ticket.Marshal() + return (&sessionTicket{ + Parameters: h.ourParams, + }).Marshal() } // GetSessionTicket generates a new session ticket. @@ -386,19 +387,29 @@ func (h *cryptoSetup) GetSessionTicket() ([]byte, error) { // We can't check h.tlsConfig here, since the actual config might have been obtained from // the GetConfigForClient callback. // See https://github.com/golang/go/issues/62032. - // Once that issue is resolved, this error assertion can be removed. + // This error assertion can be removed once we drop support for Go 1.25. if strings.Contains(err.Error(), "session ticket keys unavailable") { return nil, nil } return nil, err } - ev := h.conn.NextEvent() - if ev.Kind != tls.QUICWriteData || ev.Level != tls.QUICEncryptionLevelApplication { - panic("crypto/tls bug: where's my session ticket?") - } - ticket := ev.Data - if ev := h.conn.NextEvent(); ev.Kind != tls.QUICNoEvent { - panic("crypto/tls bug: why more than one ticket?") + // If session tickets are disabled, NextEvent will immediately return QUICNoEvent, + // and we will return a nil ticket. + var ticket []byte + for { + ev := h.conn.NextEvent() + if ev.Kind == tls.QUICNoEvent { + break + } + if ev.Kind == tls.QUICWriteData && ev.Level == tls.QUICEncryptionLevelApplication { + if ticket != nil { + h.logger.Errorf("unexpected multiple session tickets") + continue + } + ticket = ev.Data + } else { + h.logger.Errorf("unexpected event: %v", ev.Kind) + } } return ticket, nil } @@ -409,11 +420,10 @@ func (h *cryptoSetup) GetSessionTicket() ([]byte, error) { // A client may use a 0-RTT enabled session to resume a TLS session without using 0-RTT. func (h *cryptoSetup) handleSessionTicket(data []byte, using0RTT bool) (allowEarlyData bool) { var t sessionTicket - if err := t.Unmarshal(data, using0RTT); err != nil { + if err := t.Unmarshal(data); err != nil { h.logger.Debugf("Unmarshalling session ticket failed: %s", err.Error()) return false } - h.rttStats.SetInitialRTT(t.RTT) if !using0RTT { return false } @@ -426,7 +436,6 @@ func (h *cryptoSetup) handleSessionTicket(data []byte, using0RTT bool) (allowEar h.logger.Debugf("0-RTT not allowed. Rejecting 0-RTT.") return false } - h.logger.Debugf("Accepting 0-RTT. Restoring RTT from session ticket: %s", t.RTT) return true } @@ -476,8 +485,11 @@ func (h *cryptoSetup) setReadKey(el tls.QUICEncryptionLevel, suiteID uint16, tra panic("unexpected read encryption level") } h.events = append(h.events, Event{Kind: EventReceivedReadKeys}) - if h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil { - h.tracer.UpdatedKeyFromTLS(protocol.FromTLSEncryptionLevel(el), h.perspective.Opposite()) + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateTLS, + KeyType: encLevelToKeyType(protocol.FromTLSEncryptionLevel(el), h.perspective.Opposite()), + }) } } @@ -496,8 +508,11 @@ func (h *cryptoSetup) setWriteKey(el tls.QUICEncryptionLevel, suiteID uint16, tr if h.logger.Debug() { h.logger.Debugf("Installed 0-RTT Write keys (using %s)", tls.CipherSuiteName(suite.ID)) } - if h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil { - h.tracer.UpdatedKeyFromTLS(protocol.Encryption0RTT, h.perspective) + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateTLS, + KeyType: encLevelToKeyType(protocol.Encryption0RTT, h.perspective), + }) } // don't set used0RTT here. 0-RTT might still get rejected. return @@ -520,15 +535,18 @@ func (h *cryptoSetup) setWriteKey(el tls.QUICEncryptionLevel, suiteID uint16, tr h.used0RTT.Store(true) h.zeroRTTSealer = nil h.logger.Debugf("Dropping 0-RTT keys.") - if h.tracer != nil && h.tracer.DroppedEncryptionLevel != nil { - h.tracer.DroppedEncryptionLevel(protocol.Encryption0RTT) + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.KeyDiscarded{KeyType: qlog.KeyTypeClient0RTT}) } } default: panic("unexpected write encryption level") } - if h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil { - h.tracer.UpdatedKeyFromTLS(protocol.FromTLSEncryptionLevel(el), h.perspective) + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateTLS, + KeyType: encLevelToKeyType(protocol.FromTLSEncryptionLevel(el), h.perspective), + }) } } @@ -553,6 +571,10 @@ func (h *cryptoSetup) DiscardInitialKeys() { h.initialSealer = nil if dropped { h.logger.Debugf("Dropping Initial keys.") + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.KeyDiscarded{KeyType: qlog.KeyTypeClientInitial}) + h.qlogger.RecordEvent(qlog.KeyDiscarded{KeyType: qlog.KeyTypeServerInitial}) + } } } @@ -572,6 +594,10 @@ func (h *cryptoSetup) SetHandshakeConfirmed() { } if dropped { h.logger.Debugf("Dropping Handshake keys.") + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.KeyDiscarded{KeyType: qlog.KeyTypeClientHandshake}) + h.qlogger.RecordEvent(qlog.KeyDiscarded{KeyType: qlog.KeyTypeServerHandshake}) + } } } @@ -639,8 +665,8 @@ func (h *cryptoSetup) Get1RTTOpener() (ShortHeaderOpener, error) { if h.zeroRTTOpener != nil && time.Since(h.handshakeCompleteTime) > 3*h.rttStats.PTO(true) { h.zeroRTTOpener = nil h.logger.Debugf("Dropping 0-RTT keys.") - if h.tracer != nil && h.tracer.DroppedEncryptionLevel != nil { - h.tracer.DroppedEncryptionLevel(protocol.Encryption0RTT) + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.KeyDiscarded{KeyType: qlog.KeyTypeClient0RTT}) } } @@ -663,3 +689,32 @@ func wrapError(err error) error { } return &qerr.TransportError{ErrorCode: qerr.InternalError, ErrorMessage: err.Error()} } + +func encLevelToKeyType(encLevel protocol.EncryptionLevel, pers protocol.Perspective) qlog.KeyType { + if pers == protocol.PerspectiveServer { + switch encLevel { + case protocol.EncryptionInitial: + return qlog.KeyTypeServerInitial + case protocol.EncryptionHandshake: + return qlog.KeyTypeServerHandshake + case protocol.Encryption0RTT: + return qlog.KeyTypeServer0RTT + case protocol.Encryption1RTT: + return qlog.KeyTypeServer1RTT + default: + return "" + } + } + switch encLevel { + case protocol.EncryptionInitial: + return qlog.KeyTypeClientInitial + case protocol.EncryptionHandshake: + return qlog.KeyTypeClientHandshake + case protocol.Encryption0RTT: + return qlog.KeyTypeClient0RTT + case protocol.Encryption1RTT: + return qlog.KeyTypeClient1RTT + default: + return "" + } +} diff --git a/vendor/github.com/quic-go/quic-go/internal/handshake/header_protector.go b/vendor/github.com/quic-go/quic-go/internal/handshake/header_protector.go index 2c5ee42f..93c3cd98 100644 --- a/vendor/github.com/quic-go/quic-go/internal/handshake/header_protector.go +++ b/vendor/github.com/quic-go/quic-go/internal/handshake/header_protector.go @@ -24,7 +24,7 @@ func hkdfHeaderProtectionLabel(v protocol.Version) string { return "quic hp" } -func newHeaderProtector(suite *cipherSuite, trafficSecret []byte, isLongHeader bool, v protocol.Version) headerProtector { +func newHeaderProtector(suite cipherSuite, trafficSecret []byte, isLongHeader bool, v protocol.Version) headerProtector { hkdfLabel := hkdfHeaderProtectionLabel(v) switch suite.ID { case tls.TLS_AES_128_GCM_SHA256, tls.TLS_AES_256_GCM_SHA384: @@ -44,7 +44,7 @@ type aesHeaderProtector struct { var _ headerProtector = &aesHeaderProtector{} -func newAESHeaderProtector(suite *cipherSuite, trafficSecret []byte, isLongHeader bool, hkdfLabel string) headerProtector { +func newAESHeaderProtector(suite cipherSuite, trafficSecret []byte, isLongHeader bool, hkdfLabel string) headerProtector { hpKey := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, hkdfLabel, suite.KeyLen) block, err := aes.NewCipher(hpKey) if err != nil { @@ -88,7 +88,7 @@ type chachaHeaderProtector struct { var _ headerProtector = &chachaHeaderProtector{} -func newChaChaHeaderProtector(suite *cipherSuite, trafficSecret []byte, isLongHeader bool, hkdfLabel string) headerProtector { +func newChaChaHeaderProtector(suite cipherSuite, trafficSecret []byte, isLongHeader bool, hkdfLabel string) headerProtector { hpKey := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, hkdfLabel, suite.KeyLen) p := &chachaHeaderProtector{ diff --git a/vendor/github.com/quic-go/quic-go/internal/handshake/interface.go b/vendor/github.com/quic-go/quic-go/internal/handshake/interface.go index c3a59fcd..d9227339 100644 --- a/vendor/github.com/quic-go/quic-go/internal/handshake/interface.go +++ b/vendor/github.com/quic-go/quic-go/internal/handshake/interface.go @@ -5,8 +5,8 @@ import ( "crypto/tls" "errors" "io" - "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/wire" ) @@ -38,7 +38,7 @@ type LongHeaderOpener interface { type ShortHeaderOpener interface { headerDecryptor DecodePacketNumber(wirePN protocol.PacketNumber, wirePNLen protocol.PacketNumberLen) protocol.PacketNumber - Open(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, associatedData []byte) ([]byte, error) + Open(dst, src []byte, rcvTime monotime.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, associatedData []byte) ([]byte, error) } // LongHeaderSealer seals a long header packet diff --git a/vendor/github.com/quic-go/quic-go/internal/handshake/session_ticket.go b/vendor/github.com/quic-go/quic-go/internal/handshake/session_ticket.go index 4da517fc..875b0d84 100644 --- a/vendor/github.com/quic-go/quic-go/internal/handshake/session_ticket.go +++ b/vendor/github.com/quic-go/quic-go/internal/handshake/session_ticket.go @@ -4,30 +4,24 @@ import ( "bytes" "errors" "fmt" - "time" "github.com/quic-go/quic-go/internal/wire" "github.com/quic-go/quic-go/quicvarint" ) -const sessionTicketRevision = 4 +const sessionTicketRevision = 5 type sessionTicket struct { Parameters *wire.TransportParameters - RTT time.Duration // to be encoded in mus } func (t *sessionTicket) Marshal() []byte { b := make([]byte, 0, 256) b = quicvarint.Append(b, sessionTicketRevision) - b = quicvarint.Append(b, uint64(t.RTT.Microseconds())) - if t.Parameters == nil { - return b - } return t.Parameters.MarshalForSessionTicket(b) } -func (t *sessionTicket) Unmarshal(b []byte, using0RTT bool) error { +func (t *sessionTicket) Unmarshal(b []byte) error { rev, l, err := quicvarint.Parse(b) if err != nil { return errors.New("failed to read session ticket revision") @@ -36,21 +30,11 @@ func (t *sessionTicket) Unmarshal(b []byte, using0RTT bool) error { if rev != sessionTicketRevision { return fmt.Errorf("unknown session ticket revision: %d", rev) } - rtt, l, err := quicvarint.Parse(b) - if err != nil { - return errors.New("failed to read RTT") + var tp wire.TransportParameters + if err := tp.UnmarshalFromSessionTicket(b); err != nil { + return fmt.Errorf("unmarshaling transport parameters from session ticket failed: %s", err.Error()) } - b = b[l:] - if using0RTT { - var tp wire.TransportParameters - if err := tp.UnmarshalFromSessionTicket(b); err != nil { - return fmt.Errorf("unmarshaling transport parameters from session ticket failed: %s", err.Error()) - } - t.Parameters = &tp - } else if len(b) > 0 { - return fmt.Errorf("the session ticket has more bytes than expected") - } - t.RTT = time.Duration(rtt) * time.Microsecond + t.Parameters = &tp return nil } diff --git a/vendor/github.com/quic-go/quic-go/internal/handshake/token_generator.go b/vendor/github.com/quic-go/quic-go/internal/handshake/token_generator.go index 84e58cfc..933670dd 100644 --- a/vendor/github.com/quic-go/quic-go/internal/handshake/token_generator.go +++ b/vendor/github.com/quic-go/quic-go/internal/handshake/token_generator.go @@ -20,6 +20,8 @@ type Token struct { IsRetryToken bool SentTime time.Time encodedRemoteAddr []byte + // only set for tokens sent in NEW_TOKEN frames + RTT time.Duration // only set for retry tokens OriginalDestConnectionID protocol.ConnectionID RetrySrcConnectionID protocol.ConnectionID @@ -35,6 +37,7 @@ type token struct { IsRetryToken bool RemoteAddr []byte Timestamp int64 + RTT int64 // in mus OriginalDestConnectionID []byte RetrySrcConnectionID []byte } @@ -69,10 +72,11 @@ func (g *TokenGenerator) NewRetryToken( } // NewToken generates a new token to be sent in a NEW_TOKEN frame -func (g *TokenGenerator) NewToken(raddr net.Addr) ([]byte, error) { +func (g *TokenGenerator) NewToken(raddr net.Addr, rtt time.Duration) ([]byte, error) { data, err := asn1.Marshal(token{ RemoteAddr: encodeRemoteAddr(raddr), Timestamp: time.Now().UnixNano(), + RTT: rtt.Microseconds(), }) if err != nil { return nil, err @@ -107,6 +111,8 @@ func (g *TokenGenerator) DecodeToken(encrypted []byte) (*Token, error) { if t.IsRetryToken { token.OriginalDestConnectionID = protocol.ParseConnectionID(t.OriginalDestConnectionID) token.RetrySrcConnectionID = protocol.ParseConnectionID(t.RetrySrcConnectionID) + } else { + token.RTT = time.Duration(t.RTT) * time.Microsecond } return token, nil } diff --git a/vendor/github.com/quic-go/quic-go/internal/handshake/updatable_aead.go b/vendor/github.com/quic-go/quic-go/internal/handshake/updatable_aead.go index ceaa8047..f88f76ad 100644 --- a/vendor/github.com/quic-go/quic-go/internal/handshake/updatable_aead.go +++ b/vendor/github.com/quic-go/quic-go/internal/handshake/updatable_aead.go @@ -6,24 +6,33 @@ import ( "crypto/tls" "encoding/binary" "fmt" - "time" + "sync/atomic" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/utils" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" + "github.com/quic-go/quic-go/qlogwriter" ) -// KeyUpdateInterval is the maximum number of packets we send or receive before initiating a key update. -// It's a package-level variable to allow modifying it for testing purposes. -var KeyUpdateInterval uint64 = protocol.KeyUpdateInterval +var keyUpdateInterval atomic.Uint64 + +func init() { + keyUpdateInterval.Store(protocol.KeyUpdateInterval) +} + +func SetKeyUpdateInterval(v uint64) (reset func()) { + old := keyUpdateInterval.Swap(v) + return func() { keyUpdateInterval.Store(old) } +} // FirstKeyUpdateInterval is the maximum number of packets we send or receive before initiating the first key update. // It's a package-level variable to allow modifying it for testing purposes. var FirstKeyUpdateInterval uint64 = 100 type updatableAEAD struct { - suite *cipherSuite + suite cipherSuite keyPhase protocol.KeyPhase largestAcked protocol.PacketNumber @@ -34,7 +43,7 @@ type updatableAEAD struct { invalidPacketCount uint64 // Time when the keys should be dropped. Keys are dropped on the next call to Open(). - prevRcvAEADExpiry time.Time + prevRcvAEADExpiry monotime.Time prevRcvAEAD cipher.AEAD firstRcvdWithCurrentKey protocol.PacketNumber @@ -57,7 +66,7 @@ type updatableAEAD struct { rttStats *utils.RTTStats - tracer *logging.ConnectionTracer + qlogger qlogwriter.Recorder logger utils.Logger version protocol.Version @@ -70,14 +79,14 @@ var ( _ ShortHeaderSealer = &updatableAEAD{} ) -func newUpdatableAEAD(rttStats *utils.RTTStats, tracer *logging.ConnectionTracer, logger utils.Logger, version protocol.Version) *updatableAEAD { +func newUpdatableAEAD(rttStats *utils.RTTStats, qlogger qlogwriter.Recorder, logger utils.Logger, version protocol.Version) *updatableAEAD { return &updatableAEAD{ firstPacketNumber: protocol.InvalidPacketNumber, largestAcked: protocol.InvalidPacketNumber, firstRcvdWithCurrentKey: protocol.InvalidPacketNumber, firstSentWithCurrentKey: protocol.InvalidPacketNumber, rttStats: rttStats, - tracer: tracer, + qlogger: qlogger, logger: logger, version: version, } @@ -86,10 +95,17 @@ func newUpdatableAEAD(rttStats *utils.RTTStats, tracer *logging.ConnectionTracer func (a *updatableAEAD) rollKeys() { if a.prevRcvAEAD != nil { a.logger.Debugf("Dropping key phase %d ahead of scheduled time. Drop time was: %s", a.keyPhase-1, a.prevRcvAEADExpiry) - if a.tracer != nil && a.tracer.DroppedKey != nil { - a.tracer.DroppedKey(a.keyPhase - 1) + if a.qlogger != nil { + a.qlogger.RecordEvent(qlog.KeyDiscarded{ + KeyType: qlog.KeyTypeClient1RTT, + KeyPhase: a.keyPhase - 1, + }) + a.qlogger.RecordEvent(qlog.KeyDiscarded{ + KeyType: qlog.KeyTypeServer1RTT, + KeyPhase: a.keyPhase - 1, + }) } - a.prevRcvAEADExpiry = time.Time{} + a.prevRcvAEADExpiry = 0 } a.keyPhase++ @@ -107,7 +123,7 @@ func (a *updatableAEAD) rollKeys() { a.nextSendAEAD = createAEAD(a.suite, a.nextSendTrafficSecret, a.version) } -func (a *updatableAEAD) startKeyDropTimer(now time.Time) { +func (a *updatableAEAD) startKeyDropTimer(now monotime.Time) { d := 3 * a.rttStats.PTO(true) a.logger.Debugf("Starting key drop timer to drop key phase %d (in %s)", a.keyPhase-1, d) a.prevRcvAEADExpiry = now.Add(d) @@ -120,10 +136,10 @@ func (a *updatableAEAD) getNextTrafficSecret(hash crypto.Hash, ts []byte) []byte // SetReadKey sets the read key. // For the client, this function is called before SetWriteKey. // For the server, this function is called after SetWriteKey. -func (a *updatableAEAD) SetReadKey(suite *cipherSuite, trafficSecret []byte) { +func (a *updatableAEAD) SetReadKey(suite cipherSuite, trafficSecret []byte) { a.rcvAEAD = createAEAD(suite, trafficSecret, a.version) a.headerDecrypter = newHeaderProtector(suite, trafficSecret, false, a.version) - if a.suite == nil { + if a.suite.ID == 0 { // suite is not set yet a.setAEADParameters(a.rcvAEAD, suite) } @@ -134,10 +150,10 @@ func (a *updatableAEAD) SetReadKey(suite *cipherSuite, trafficSecret []byte) { // SetWriteKey sets the write key. // For the client, this function is called after SetReadKey. // For the server, this function is called before SetReadKey. -func (a *updatableAEAD) SetWriteKey(suite *cipherSuite, trafficSecret []byte) { +func (a *updatableAEAD) SetWriteKey(suite cipherSuite, trafficSecret []byte) { a.sendAEAD = createAEAD(suite, trafficSecret, a.version) a.headerEncrypter = newHeaderProtector(suite, trafficSecret, false, a.version) - if a.suite == nil { + if a.suite.ID == 0 { // suite is not set yet a.setAEADParameters(a.sendAEAD, suite) } @@ -145,7 +161,7 @@ func (a *updatableAEAD) SetWriteKey(suite *cipherSuite, trafficSecret []byte) { a.nextSendAEAD = createAEAD(suite, a.nextSendTrafficSecret, a.version) } -func (a *updatableAEAD) setAEADParameters(aead cipher.AEAD, suite *cipherSuite) { +func (a *updatableAEAD) setAEADParameters(aead cipher.AEAD, suite cipherSuite) { a.nonceBuf = make([]byte, aead.NonceSize()) a.aeadOverhead = aead.Overhead() a.suite = suite @@ -163,7 +179,7 @@ func (a *updatableAEAD) DecodePacketNumber(wirePN protocol.PacketNumber, wirePNL return protocol.DecodePacketNumber(wirePNLen, a.highestRcvdPN, wirePN) } -func (a *updatableAEAD) Open(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, ad []byte) ([]byte, error) { +func (a *updatableAEAD) Open(dst, src []byte, rcvTime monotime.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, ad []byte) ([]byte, error) { dec, err := a.open(dst, src, rcvTime, pn, kp, ad) if err == ErrDecryptionFailed { a.invalidPacketCount++ @@ -177,13 +193,20 @@ func (a *updatableAEAD) Open(dst, src []byte, rcvTime time.Time, pn protocol.Pac return dec, err } -func (a *updatableAEAD) open(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, ad []byte) ([]byte, error) { +func (a *updatableAEAD) open(dst, src []byte, rcvTime monotime.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, ad []byte) ([]byte, error) { if a.prevRcvAEAD != nil && !a.prevRcvAEADExpiry.IsZero() && rcvTime.After(a.prevRcvAEADExpiry) { a.prevRcvAEAD = nil a.logger.Debugf("Dropping key phase %d", a.keyPhase-1) - a.prevRcvAEADExpiry = time.Time{} - if a.tracer != nil && a.tracer.DroppedKey != nil { - a.tracer.DroppedKey(a.keyPhase - 1) + a.prevRcvAEADExpiry = 0 + if a.qlogger != nil { + a.qlogger.RecordEvent(qlog.KeyDiscarded{ + KeyType: qlog.KeyTypeClient1RTT, + KeyPhase: a.keyPhase - 1, + }) + a.qlogger.RecordEvent(qlog.KeyDiscarded{ + KeyType: qlog.KeyTypeServer1RTT, + KeyPhase: a.keyPhase - 1, + }) } } binary.BigEndian.PutUint64(a.nonceBuf[len(a.nonceBuf)-8:], uint64(pn)) @@ -216,8 +239,17 @@ func (a *updatableAEAD) open(dst, src []byte, rcvTime time.Time, pn protocol.Pac // The peer initiated this key update. It's safe to drop the keys for the previous generation now. // Start a timer to drop the previous key generation. a.startKeyDropTimer(rcvTime) - if a.tracer != nil && a.tracer.UpdatedKey != nil { - a.tracer.UpdatedKey(a.keyPhase, true) + if a.qlogger != nil { + a.qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateRemote, + KeyType: qlog.KeyTypeClient1RTT, + KeyPhase: a.keyPhase, + }) + a.qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateRemote, + KeyType: qlog.KeyTypeServer1RTT, + KeyPhase: a.keyPhase, + }) } a.firstRcvdWithCurrentKey = pn return dec, err @@ -293,11 +325,11 @@ func (a *updatableAEAD) shouldInitiateKeyUpdate() bool { return true } } - if a.numRcvdWithCurrentKey >= KeyUpdateInterval { + if a.numRcvdWithCurrentKey >= keyUpdateInterval.Load() { a.logger.Debugf("Received %d packets with current key phase. Initiating key update to the next key phase: %d", a.numRcvdWithCurrentKey, a.keyPhase+1) return true } - if a.numSentWithCurrentKey >= KeyUpdateInterval { + if a.numSentWithCurrentKey >= keyUpdateInterval.Load() { a.logger.Debugf("Sent %d packets with current key phase. Initiating key update to the next key phase: %d", a.numSentWithCurrentKey, a.keyPhase+1) return true } @@ -307,9 +339,17 @@ func (a *updatableAEAD) shouldInitiateKeyUpdate() bool { func (a *updatableAEAD) KeyPhase() protocol.KeyPhaseBit { if a.shouldInitiateKeyUpdate() { a.rollKeys() - a.logger.Debugf("Initiating key update to key phase %d", a.keyPhase) - if a.tracer != nil && a.tracer.UpdatedKey != nil { - a.tracer.UpdatedKey(a.keyPhase, false) + if a.qlogger != nil { + a.qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateLocal, + KeyType: qlog.KeyTypeClient1RTT, + KeyPhase: a.keyPhase, + }) + a.qlogger.RecordEvent(qlog.KeyUpdated{ + Trigger: qlog.KeyUpdateLocal, + KeyType: qlog.KeyTypeServer1RTT, + KeyPhase: a.keyPhase, + }) } } return a.keyPhase.Bit() diff --git a/vendor/github.com/quic-go/quic-go/internal/monotime/time.go b/vendor/github.com/quic-go/quic-go/internal/monotime/time.go new file mode 100644 index 00000000..eda61dc6 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/internal/monotime/time.go @@ -0,0 +1,90 @@ +// Package monotime provides a monotonic time representation that is useful for +// measuring elapsed time. +// It is designed as a memory optimized drop-in replacement for time.Time, with +// a monotime.Time consuming just 8 bytes instead of 24 bytes. +package monotime + +import ( + "time" +) + +// The absolute value doesn't matter, but it should be in the past, +// so that every timestamp obtained with Now() is non-zero, +// even on systems with low timer resolutions (e.g. Windows). +var start = time.Now().Add(-time.Hour) + +// A Time represents an instant in monotonic time. +// Times can be compared using the comparison operators, but the specific +// value is implementation-dependent and should not be relied upon. +// The zero value of Time doesn't have any specific meaning. +type Time int64 + +// Now returns the current monotonic time. +func Now() Time { + return Time(time.Since(start).Nanoseconds()) +} + +// Sub returns the duration t-t2. If the result exceeds the maximum (or minimum) +// value that can be stored in a Duration, the maximum (or minimum) duration +// will be returned. +// To compute t-d for a duration d, use t.Add(-d). +func (t Time) Sub(t2 Time) time.Duration { + return time.Duration(t - t2) +} + +// Add returns the time t+d. +func (t Time) Add(d time.Duration) Time { + return Time(int64(t) + d.Nanoseconds()) +} + +// After reports whether the time instant t is after t2. +func (t Time) After(t2 Time) bool { + return t > t2 +} + +// Before reports whether the time instant t is before t2. +func (t Time) Before(t2 Time) bool { + return t < t2 +} + +// IsZero reports whether t represents the zero time instant. +func (t Time) IsZero() bool { + return t == 0 +} + +// Equal reports whether t and t2 represent the same time instant. +func (t Time) Equal(t2 Time) bool { + return t == t2 +} + +// ToTime converts the monotonic time to a time.Time value. +// The returned time.Time will have the same instant as the monotonic time, +// but may be subject to clock adjustments. +func (t Time) ToTime() time.Time { + if t.IsZero() { + return time.Time{} + } + return start.Add(time.Duration(t)) +} + +// Since returns the time elapsed since t. It is shorthand for Now().Sub(t). +func Since(t Time) time.Duration { + return Now().Sub(t) +} + +// Until returns the duration until t. +// It is shorthand for t.Sub(Now()). +// If t is in the past, the returned duration will be negative. +func Until(t Time) time.Duration { + return time.Duration(t - Now()) +} + +// FromTime converts a time.Time to a monotonic Time. +// The conversion is relative to the package's start time and may lose +// precision if the time.Time is far from the start time. +func FromTime(t time.Time) Time { + if t.IsZero() { + return 0 + } + return Time(t.Sub(start).Nanoseconds()) +} diff --git a/vendor/github.com/quic-go/quic-go/internal/protocol/connection_id.go b/vendor/github.com/quic-go/quic-go/internal/protocol/connection_id.go index 77259b5f..ce3171fc 100644 --- a/vendor/github.com/quic-go/quic-go/internal/protocol/connection_id.go +++ b/vendor/github.com/quic-go/quic-go/internal/protocol/connection_id.go @@ -2,8 +2,8 @@ package protocol import ( "crypto/rand" + "encoding/hex" "errors" - "fmt" "io" ) @@ -26,7 +26,7 @@ func (c ArbitraryLenConnectionID) String() string { if c.Len() == 0 { return "(empty)" } - return fmt.Sprintf("%x", c.Bytes()) + return hex.EncodeToString(c.Bytes()) } const maxConnectionIDLen = 20 @@ -100,7 +100,7 @@ func (c ConnectionID) String() string { if c.Len() == 0 { return "(empty)" } - return fmt.Sprintf("%x", c.Bytes()) + return hex.EncodeToString(c.Bytes()) } type DefaultConnectionIDGenerator struct { diff --git a/vendor/github.com/quic-go/quic-go/internal/protocol/params.go b/vendor/github.com/quic-go/quic-go/internal/protocol/params.go index f0aa3ad9..0861d57f 100644 --- a/vendor/github.com/quic-go/quic-go/internal/protocol/params.go +++ b/vendor/github.com/quic-go/quic-go/internal/protocol/params.go @@ -102,10 +102,6 @@ const DefaultIdleTimeout = 30 * time.Second // DefaultHandshakeIdleTimeout is the default idle timeout used before handshake completion. const DefaultHandshakeIdleTimeout = 5 * time.Second -// RetiredConnectionIDDeleteTimeout is the time we keep closed connections around in order to retransmit the CONNECTION_CLOSE. -// after this time all information about the old connection will be deleted -const RetiredConnectionIDDeleteTimeout = 5 * time.Second - // MinStreamFrameSize is the minimum size that has to be left in a packet, so that we add another STREAM frame. // This avoids splitting up STREAM frames into small pieces, which has 2 advantages: // 1. it reduces the framing overhead @@ -116,16 +112,13 @@ const MinStreamFrameSize ByteCount = 128 // we send after the handshake completes. const MaxPostHandshakeCryptoFrameSize = 1000 -// MaxAckFrameSize is the maximum size for an ACK frame that we write -// Due to the varint encoding, ACK frames can grow (almost) indefinitely large. -// The MaxAckFrameSize should be large enough to encode many ACK range, -// but must ensure that a maximum size ACK frame fits into one packet. -const MaxAckFrameSize ByteCount = 1000 - // MaxNumAckRanges is the maximum number of ACK ranges that we send in an ACK frame. // It also serves as a limit for the packet history. // If at any point we keep track of more ranges, old ranges are discarded. -const MaxNumAckRanges = 32 +// +// This value also guarantees that ACK Range Count value in the ACK frame can be encoded +// in a single byte varint. +const MaxNumAckRanges = 64 // MinPacingDelay is the minimum duration that is used for packet pacing // If the packet packing frequency is higher, multiple packets might be sent at once. diff --git a/vendor/github.com/quic-go/quic-go/internal/protocol/protocol.go b/vendor/github.com/quic-go/quic-go/internal/protocol/protocol.go index b1109ff4..a8813a66 100644 --- a/vendor/github.com/quic-go/quic-go/internal/protocol/protocol.go +++ b/vendor/github.com/quic-go/quic-go/internal/protocol/protocol.go @@ -2,6 +2,7 @@ package protocol import ( "fmt" + "sync/atomic" "time" ) @@ -95,6 +96,8 @@ func (e ECN) String() string { // A ByteCount in QUIC type ByteCount int64 +type AtomicByteCount atomic.Int64 + // MaxByteCount is the maximum value of a ByteCount const MaxByteCount = ByteCount(1<<62 - 1) diff --git a/vendor/github.com/quic-go/quic-go/internal/protocol/stream.go b/vendor/github.com/quic-go/quic-go/internal/protocol/stream.go index ad7de864..6db4a95b 100644 --- a/vendor/github.com/quic-go/quic-go/internal/protocol/stream.go +++ b/vendor/github.com/quic-go/quic-go/internal/protocol/stream.go @@ -1,5 +1,7 @@ package protocol +import "github.com/quic-go/quic-go/quicvarint" + // StreamType encodes if this is a unidirectional or bidirectional stream type StreamType uint8 @@ -23,6 +25,30 @@ const ( // MaxStreamCount is the maximum stream count value that can be sent in MAX_STREAMS frames // and as the stream count in the transport parameters MaxStreamCount StreamNum = 1 << 60 + // MaxStreamID is the maximum stream ID + MaxStreamID StreamID = quicvarint.Max +) + +const ( + // FirstOutgoingBidiStreamClient is the first bidirectional stream opened by the client + FirstOutgoingBidiStreamClient StreamID = 0 + // FirstOutgoingUniStreamClient is the first unidirectional stream opened by the client + FirstOutgoingUniStreamClient StreamID = 2 + // FirstOutgoingBidiStreamServer is the first bidirectional stream opened by the server + FirstOutgoingBidiStreamServer StreamID = 1 + // FirstOutgoingUniStreamServer is the first unidirectional stream opened by the server + FirstOutgoingUniStreamServer StreamID = 3 +) + +const ( + // FirstIncomingBidiStreamServer is the first bidirectional stream accepted by the server + FirstIncomingBidiStreamServer = FirstOutgoingBidiStreamClient + // FirstIncomingUniStreamServer is the first unidirectional stream accepted by the server + FirstIncomingUniStreamServer = FirstOutgoingUniStreamClient + // FirstIncomingBidiStreamClient is the first bidirectional stream accepted by the client + FirstIncomingBidiStreamClient = FirstOutgoingBidiStreamServer + // FirstIncomingUniStreamClient is the first unidirectional stream accepted by the client + FirstIncomingUniStreamClient = FirstOutgoingUniStreamServer ) // StreamID calculates the stream ID. diff --git a/vendor/github.com/quic-go/quic-go/internal/protocol/version.go b/vendor/github.com/quic-go/quic-go/internal/protocol/version.go index 646587f3..8abca506 100644 --- a/vendor/github.com/quic-go/quic-go/internal/protocol/version.go +++ b/vendor/github.com/quic-go/quic-go/internal/protocol/version.go @@ -6,6 +6,7 @@ import ( "fmt" "math" mrand "math/rand/v2" + "slices" "sync" ) @@ -36,7 +37,6 @@ func IsValidVersion(v Version) bool { } func (vn Version) String() string { - //nolint:exhaustive switch vn { case VersionUnknown: return "unknown" @@ -64,12 +64,7 @@ func (vn Version) toGQUICVersion() int { // IsSupportedVersion returns true if the server supports this version func IsSupportedVersion(supported []Version, v Version) bool { - for _, t := range supported { - if t == v { - return true - } - } - return false + return slices.Contains(supported, v) } // ChooseSupportedVersion finds the best version in the overlap of ours and theirs @@ -78,10 +73,8 @@ func IsSupportedVersion(supported []Version, v Version) bool { // The bool returned indicates if a matching version was found. func ChooseSupportedVersion(ours, theirs []Version) (Version, bool) { for _, ourVer := range ours { - for _, theirVer := range theirs { - if ourVer == theirVer { - return ourVer, true - } + if slices.Contains(theirs, ourVer) { + return ourVer, true } } return 0, false diff --git a/vendor/github.com/quic-go/quic-go/internal/utils/connstats.go b/vendor/github.com/quic-go/quic-go/internal/utils/connstats.go new file mode 100644 index 00000000..19d88312 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/internal/utils/connstats.go @@ -0,0 +1,14 @@ +package utils + +import "sync/atomic" + +// ConnectionStats stores stats for the connection. See the public +// ConnectionStats struct in connection.go for more information +type ConnectionStats struct { + BytesSent atomic.Uint64 + PacketsSent atomic.Uint64 + BytesReceived atomic.Uint64 + PacketsReceived atomic.Uint64 + BytesLost atomic.Uint64 + PacketsLost atomic.Uint64 +} diff --git a/vendor/github.com/quic-go/quic-go/internal/utils/log.go b/vendor/github.com/quic-go/quic-go/internal/utils/log.go index 89b52c0d..558803ef 100644 --- a/vendor/github.com/quic-go/quic-go/internal/utils/log.go +++ b/vendor/github.com/quic-go/quic-go/internal/utils/log.go @@ -31,9 +31,9 @@ type Logger interface { WithPrefix(prefix string) Logger Debug() bool - Errorf(format string, args ...interface{}) - Infof(format string, args ...interface{}) - Debugf(format string, args ...interface{}) + Errorf(format string, args ...any) + Infof(format string, args ...any) + Debugf(format string, args ...any) } // DefaultLogger is used by quic-go for logging. @@ -61,27 +61,27 @@ func (l *defaultLogger) SetLogTimeFormat(format string) { } // Debugf logs something -func (l *defaultLogger) Debugf(format string, args ...interface{}) { +func (l *defaultLogger) Debugf(format string, args ...any) { if l.logLevel == LogLevelDebug { l.logMessage(format, args...) } } // Infof logs something -func (l *defaultLogger) Infof(format string, args ...interface{}) { +func (l *defaultLogger) Infof(format string, args ...any) { if l.logLevel >= LogLevelInfo { l.logMessage(format, args...) } } // Errorf logs something -func (l *defaultLogger) Errorf(format string, args ...interface{}) { +func (l *defaultLogger) Errorf(format string, args ...any) { if l.logLevel >= LogLevelError { l.logMessage(format, args...) } } -func (l *defaultLogger) logMessage(format string, args ...interface{}) { +func (l *defaultLogger) logMessage(format string, args ...any) { var pre string if len(l.timeFormat) > 0 { diff --git a/vendor/github.com/quic-go/quic-go/internal/utils/rtt_stats.go b/vendor/github.com/quic-go/quic-go/internal/utils/rtt_stats.go index 0efd8354..27531307 100644 --- a/vendor/github.com/quic-go/quic-go/internal/utils/rtt_stats.go +++ b/vendor/github.com/quic-go/quic-go/internal/utils/rtt_stats.go @@ -1,6 +1,7 @@ package utils import ( + "sync/atomic" "time" "github.com/quic-go/quic-go/internal/protocol" @@ -11,44 +12,63 @@ const ( oneMinusAlpha = 1 - rttAlpha rttBeta = 0.25 oneMinusBeta = 1 - rttBeta - // The default RTT used before an RTT sample is taken. - defaultInitialRTT = 100 * time.Millisecond ) +// The default RTT used before an RTT sample is taken +const DefaultInitialRTT = 100 * time.Millisecond + // RTTStats provides round-trip statistics type RTTStats struct { hasMeasurement bool - minRTT time.Duration - latestRTT time.Duration - smoothedRTT time.Duration - meanDeviation time.Duration + minRTT atomic.Int64 // nanoseconds + latestRTT atomic.Int64 // nanoseconds + smoothedRTT atomic.Int64 // nanoseconds + meanDeviation atomic.Int64 // nanoseconds - maxAckDelay time.Duration + maxAckDelay atomic.Int64 // nanoseconds +} + +func NewRTTStats() *RTTStats { + var rttStats RTTStats + rttStats.minRTT.Store(DefaultInitialRTT.Nanoseconds()) + rttStats.latestRTT.Store(DefaultInitialRTT.Nanoseconds()) + rttStats.smoothedRTT.Store(DefaultInitialRTT.Nanoseconds()) + return &rttStats } // MinRTT Returns the minRTT for the entire connection. // May return Zero if no valid updates have occurred. -func (r *RTTStats) MinRTT() time.Duration { return r.minRTT } +func (r *RTTStats) MinRTT() time.Duration { + return time.Duration(r.minRTT.Load()) +} // LatestRTT returns the most recent rtt measurement. // May return Zero if no valid updates have occurred. -func (r *RTTStats) LatestRTT() time.Duration { return r.latestRTT } +func (r *RTTStats) LatestRTT() time.Duration { + return time.Duration(r.latestRTT.Load()) +} // SmoothedRTT returns the smoothed RTT for the connection. // May return Zero if no valid updates have occurred. -func (r *RTTStats) SmoothedRTT() time.Duration { return r.smoothedRTT } +func (r *RTTStats) SmoothedRTT() time.Duration { + return time.Duration(r.smoothedRTT.Load()) +} // MeanDeviation gets the mean deviation -func (r *RTTStats) MeanDeviation() time.Duration { return r.meanDeviation } +func (r *RTTStats) MeanDeviation() time.Duration { + return time.Duration(r.meanDeviation.Load()) +} // MaxAckDelay gets the max_ack_delay advertised by the peer -func (r *RTTStats) MaxAckDelay() time.Duration { return r.maxAckDelay } +func (r *RTTStats) MaxAckDelay() time.Duration { + return time.Duration(r.maxAckDelay.Load()) +} // PTO gets the probe timeout duration. func (r *RTTStats) PTO(includeMaxAckDelay bool) time.Duration { - if r.SmoothedRTT() == 0 { - return 2 * defaultInitialRTT + if !r.hasMeasurement { + return 2 * DefaultInitialRTT } pto := r.SmoothedRTT() + max(4*r.MeanDeviation(), protocol.TimerGranularity) if includeMaxAckDelay { @@ -67,36 +87,45 @@ func (r *RTTStats) UpdateRTT(sendDelta, ackDelay time.Duration) { // ackDelay but the raw observed sendDelta, since poor clock granularity at // the client may cause a high ackDelay to result in underestimation of the // r.minRTT. - if r.minRTT == 0 || r.minRTT > sendDelta { - r.minRTT = sendDelta + minRTT := time.Duration(r.minRTT.Load()) + if !r.hasMeasurement || minRTT > sendDelta { + minRTT = sendDelta + r.minRTT.Store(sendDelta.Nanoseconds()) } // Correct for ackDelay if information received from the peer results in a // an RTT sample at least as large as minRTT. Otherwise, only use the // sendDelta. sample := sendDelta - if sample-r.minRTT >= ackDelay { + if sample-minRTT >= ackDelay { sample -= ackDelay } - r.latestRTT = sample + r.latestRTT.Store(sample.Nanoseconds()) // First time call. if !r.hasMeasurement { r.hasMeasurement = true - r.smoothedRTT = sample - r.meanDeviation = sample / 2 + r.smoothedRTT.Store(sample.Nanoseconds()) + r.meanDeviation.Store(sample.Nanoseconds() / 2) } else { - r.meanDeviation = time.Duration(oneMinusBeta*float32(r.meanDeviation/time.Microsecond)+rttBeta*float32((r.smoothedRTT-sample).Abs()/time.Microsecond)) * time.Microsecond - r.smoothedRTT = time.Duration((float32(r.smoothedRTT/time.Microsecond)*oneMinusAlpha)+(float32(sample/time.Microsecond)*rttAlpha)) * time.Microsecond + smoothedRTT := r.SmoothedRTT() + meanDev := time.Duration(oneMinusBeta*float32(r.MeanDeviation()/time.Microsecond)+rttBeta*float32((smoothedRTT-sample).Abs()/time.Microsecond)) * time.Microsecond + newSmoothedRTT := time.Duration((float32(smoothedRTT/time.Microsecond)*oneMinusAlpha)+(float32(sample/time.Microsecond)*rttAlpha)) * time.Microsecond + r.meanDeviation.Store(meanDev.Nanoseconds()) + r.smoothedRTT.Store(newSmoothedRTT.Nanoseconds()) } } +func (r *RTTStats) HasMeasurement() bool { + return r.hasMeasurement +} + // SetMaxAckDelay sets the max_ack_delay func (r *RTTStats) SetMaxAckDelay(mad time.Duration) { - r.maxAckDelay = mad + r.maxAckDelay.Store(int64(mad)) } // SetInitialRTT sets the initial RTT. -// It is used during the 0-RTT handshake when restoring the RTT stats from the session state. +// It is used during handshake when restoring the RTT stats from the token. func (r *RTTStats) SetInitialRTT(t time.Duration) { // On the server side, by the time we get to process the session ticket, // we might already have obtained an RTT measurement. @@ -105,15 +134,26 @@ func (r *RTTStats) SetInitialRTT(t time.Duration) { if r.hasMeasurement { return } - r.smoothedRTT = t - r.latestRTT = t + r.smoothedRTT.Store(int64(t)) + r.latestRTT.Store(int64(t)) } func (r *RTTStats) ResetForPathMigration() { r.hasMeasurement = false - r.minRTT = 0 - r.latestRTT = 0 - r.smoothedRTT = 0 - r.meanDeviation = 0 + r.minRTT.Store(DefaultInitialRTT.Nanoseconds()) + r.latestRTT.Store(DefaultInitialRTT.Nanoseconds()) + r.smoothedRTT.Store(DefaultInitialRTT.Nanoseconds()) + r.meanDeviation.Store(0) // max_ack_delay remains valid } + +func (r *RTTStats) Clone() *RTTStats { + out := &RTTStats{} + out.hasMeasurement = r.hasMeasurement + out.minRTT.Store(r.minRTT.Load()) + out.latestRTT.Store(r.latestRTT.Load()) + out.smoothedRTT.Store(r.smoothedRTT.Load()) + out.meanDeviation.Store(r.meanDeviation.Load()) + out.maxAckDelay.Store(r.maxAckDelay.Load()) + return out +} diff --git a/vendor/github.com/quic-go/quic-go/internal/utils/timer.go b/vendor/github.com/quic-go/quic-go/internal/utils/timer.go deleted file mode 100644 index 361106c8..00000000 --- a/vendor/github.com/quic-go/quic-go/internal/utils/timer.go +++ /dev/null @@ -1,57 +0,0 @@ -package utils - -import ( - "math" - "time" -) - -// A Timer wrapper that behaves correctly when resetting -type Timer struct { - t *time.Timer - read bool - deadline time.Time -} - -// NewTimer creates a new timer that is not set -func NewTimer() *Timer { - return &Timer{t: time.NewTimer(time.Duration(math.MaxInt64))} -} - -// Chan returns the channel of the wrapped timer -func (t *Timer) Chan() <-chan time.Time { - return t.t.C -} - -// Reset the timer, no matter whether the value was read or not -func (t *Timer) Reset(deadline time.Time) { - if deadline.Equal(t.deadline) && !t.read { - // No need to reset the timer - return - } - - // We need to drain the timer if the value from its channel was not read yet. - // See https://groups.google.com/forum/#!topic/golang-dev/c9UUfASVPoU - if !t.t.Stop() && !t.read { - <-t.t.C - } - if !deadline.IsZero() { - t.t.Reset(time.Until(deadline)) - } - - t.read = false - t.deadline = deadline -} - -// SetRead should be called after the value from the chan was read -func (t *Timer) SetRead() { - t.read = true -} - -func (t *Timer) Deadline() time.Time { - return t.deadline -} - -// Stop stops the timer -func (t *Timer) Stop() { - t.t.Stop() -} diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/ack_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/ack_frame.go index 8befef4f..191e1530 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/ack_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/ack_frame.go @@ -21,9 +21,9 @@ type AckFrame struct { } // parseAckFrame reads an ACK frame -func parseAckFrame(frame *AckFrame, b []byte, typ uint64, ackDelayExponent uint8, _ protocol.Version) (int, error) { +func parseAckFrame(frame *AckFrame, b []byte, typ FrameType, ackDelayExponent uint8, _ protocol.Version) (int, error) { startLen := len(b) - ecn := typ == ackECNFrameType + ecn := typ == FrameTypeAckECN la, l, err := quicvarint.Parse(b) if err != nil { @@ -64,7 +64,7 @@ func parseAckFrame(frame *AckFrame, b []byte, typ uint64, ackDelayExponent uint8 frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largestAcked}) // read all the other ACK ranges - for i := uint64(0); i < numBlocks; i++ { + for range numBlocks { g, l, err := quicvarint.Parse(b) if err != nil { return 0, replaceUnexpectedEOF(err) @@ -122,14 +122,14 @@ func parseAckFrame(frame *AckFrame, b []byte, typ uint64, ackDelayExponent uint8 func (f *AckFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { hasECN := f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0 if hasECN { - b = append(b, ackECNFrameType) + b = append(b, byte(FrameTypeAckECN)) } else { - b = append(b, ackFrameType) + b = append(b, byte(FrameTypeAck)) } b = quicvarint.Append(b, uint64(f.LargestAcked())) b = quicvarint.Append(b, encodeAckDelay(f.DelayTime)) - numRanges := f.numEncodableAckRanges() + numRanges := min(len(f.AckRanges), protocol.MaxNumAckRanges) b = quicvarint.Append(b, uint64(numRanges-1)) // write the first range @@ -154,46 +154,69 @@ func (f *AckFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { // Length of a written frame func (f *AckFrame) Length(_ protocol.Version) protocol.ByteCount { largestAcked := f.AckRanges[0].Largest - numRanges := f.numEncodableAckRanges() - length := 1 + quicvarint.Len(uint64(largestAcked)) + quicvarint.Len(encodeAckDelay(f.DelayTime)) + // The number of ACK ranges is limited to 64, which guarantees that the + // ACK Range Count value can be encoded in a single byte varint. + length := 1 + quicvarint.Len(uint64(largestAcked)) + quicvarint.Len(encodeAckDelay(f.DelayTime)) + 1 - length += quicvarint.Len(uint64(numRanges - 1)) lowestInFirstRange := f.AckRanges[0].Smallest length += quicvarint.Len(uint64(largestAcked - lowestInFirstRange)) - for i := 1; i < numRanges; i++ { + for i := 1; i < min(len(f.AckRanges), protocol.MaxNumAckRanges); i++ { gap, len := f.encodeAckRange(i) length += quicvarint.Len(gap) length += quicvarint.Len(len) } if f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0 { - length += quicvarint.Len(f.ECT0) - length += quicvarint.Len(f.ECT1) - length += quicvarint.Len(f.ECNCE) + length += quicvarint.Len(f.ECT0) + quicvarint.Len(f.ECT1) + quicvarint.Len(f.ECNCE) } return protocol.ByteCount(length) } +// Truncate truncates the ACK frame to fit into maxSize, +// and to at most 64 ACK ranges. +// maxSize must be large enough to fit at least one ACK range. +func (f *AckFrame) Truncate(maxSize protocol.ByteCount, _ protocol.Version) { + f.AckRanges = f.AckRanges[:f.numEncodableAckRanges(maxSize)] +} + // gets the number of ACK ranges that can be encoded -// such that the resulting frame is smaller than the maximum ACK frame size -func (f *AckFrame) numEncodableAckRanges() int { - length := 1 + quicvarint.Len(uint64(f.LargestAcked())) + quicvarint.Len(encodeAckDelay(f.DelayTime)) - length += 2 // assume that the number of ranges will consume 2 bytes - for i := 1; i < len(f.AckRanges); i++ { - gap, len := f.encodeAckRange(i) - rangeLen := quicvarint.Len(gap) + quicvarint.Len(len) - if protocol.ByteCount(length+rangeLen) > protocol.MaxAckFrameSize { - // Writing range i would exceed the MaxAckFrameSize. - // So encode one range less than that. - return i - 1 +// such that the resulting frame is smaller than maxSize +func (f *AckFrame) numEncodableAckRanges(maxSize protocol.ByteCount) int { + // Fast path: Most ACK frames are relatively small, and we don't need to calculate the exact length. + // We just assume the worst case scenario: every varint is encoded to 8 bytes. + // If the result is still smaller than the maximum ACK frame size, the actual ACK frame will definitely fit. + length := 1 + 8 /* largest acked */ + 8 /* delay */ + 1 /* ack range count */ + 8 /* first range */ + if f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0 { + length += 8 + 8 + 8 + } + numRanges := min(len(f.AckRanges), protocol.MaxNumAckRanges) + length += 2 * 8 * (numRanges - 1) + if protocol.ByteCount(length) <= maxSize { + return numRanges + } + + // Slow path: Calculate the exact length of the ACK frame. + length = 1 + quicvarint.Len(uint64(f.LargestAcked())) + quicvarint.Len(encodeAckDelay(f.DelayTime)) + 1 + _, firstRange := f.encodeAckRange(0) + length += quicvarint.Len(firstRange) + if f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0 { + length += quicvarint.Len(f.ECT0) + quicvarint.Len(f.ECT1) + quicvarint.Len(f.ECNCE) + } + for i := 1; i < numRanges; i++ { + gap, l := f.encodeAckRange(i) + rangeLen := quicvarint.Len(gap) + quicvarint.Len(l) + if protocol.ByteCount(length+rangeLen) > maxSize { + // Writing range i would exceed the maximum size, + // so encode one range less than that. + return i } length += rangeLen } - return len(f.AckRanges) + return numRanges } -func (f *AckFrame) encodeAckRange(i int) (uint64 /* gap */, uint64 /* length */) { +func (f *AckFrame) encodeAckRange(i int) (gap, length uint64) { if i == 0 { return 0, uint64(f.AckRanges[0].Largest - f.AckRanges[0].Smallest) } @@ -218,7 +241,7 @@ func (f *AckFrame) validateAckRanges() bool { } } - // check the consistency for ACK with multiple NACK ranges + // check the consistency for ACK with multiple ACK ranges for i, ackRange := range f.AckRanges { if i == 0 { continue diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/ack_frequency_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/ack_frequency_frame.go new file mode 100644 index 00000000..0735d70b --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/internal/wire/ack_frequency_frame.go @@ -0,0 +1,65 @@ +package wire + +import ( + "math" + "time" + + "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/quicvarint" +) + +type AckFrequencyFrame struct { + SequenceNumber uint64 + AckElicitingThreshold uint64 + RequestMaxAckDelay time.Duration + ReorderingThreshold protocol.PacketNumber +} + +func parseAckFrequencyFrame(b []byte, _ protocol.Version) (*AckFrequencyFrame, int, error) { + startLen := len(b) + seq, l, err := quicvarint.Parse(b) + if err != nil { + return nil, 0, replaceUnexpectedEOF(err) + } + b = b[l:] + aeth, l, err := quicvarint.Parse(b) + if err != nil { + return nil, 0, replaceUnexpectedEOF(err) + } + b = b[l:] + mad, l, err := quicvarint.Parse(b) + if err != nil { + return nil, 0, replaceUnexpectedEOF(err) + } + // prevents overflows if the peer sends a very large value + maxAckDelay := time.Duration(mad) * time.Microsecond + if maxAckDelay < 0 { + maxAckDelay = math.MaxInt64 + } + b = b[l:] + rth, l, err := quicvarint.Parse(b) + if err != nil { + return nil, 0, replaceUnexpectedEOF(err) + } + b = b[l:] + + return &AckFrequencyFrame{ + SequenceNumber: seq, + AckElicitingThreshold: aeth, + RequestMaxAckDelay: maxAckDelay, + ReorderingThreshold: protocol.PacketNumber(rth), + }, startLen - len(b), nil +} + +func (f *AckFrequencyFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { + b = quicvarint.Append(b, uint64(FrameTypeAckFrequency)) + b = quicvarint.Append(b, f.SequenceNumber) + b = quicvarint.Append(b, f.AckElicitingThreshold) + b = quicvarint.Append(b, uint64(f.RequestMaxAckDelay/time.Microsecond)) + return quicvarint.Append(b, uint64(f.ReorderingThreshold)), nil +} + +func (f *AckFrequencyFrame) Length(_ protocol.Version) protocol.ByteCount { + return protocol.ByteCount(2 + quicvarint.Len(f.SequenceNumber) + quicvarint.Len(f.AckElicitingThreshold) + + quicvarint.Len(uint64(f.RequestMaxAckDelay/time.Microsecond)) + quicvarint.Len(uint64(f.ReorderingThreshold))) +} diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/connection_close_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/connection_close_frame.go index be11a1b2..6c71aab6 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/connection_close_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/connection_close_frame.go @@ -15,9 +15,9 @@ type ConnectionCloseFrame struct { ReasonPhrase string } -func parseConnectionCloseFrame(b []byte, typ uint64, _ protocol.Version) (*ConnectionCloseFrame, int, error) { +func parseConnectionCloseFrame(b []byte, typ FrameType, _ protocol.Version) (*ConnectionCloseFrame, int, error) { startLen := len(b) - f := &ConnectionCloseFrame{IsApplicationError: typ == applicationCloseFrameType} + f := &ConnectionCloseFrame{IsApplicationError: typ == FrameTypeApplicationClose} ec, l, err := quicvarint.Parse(b) if err != nil { return nil, 0, replaceUnexpectedEOF(err) @@ -60,9 +60,9 @@ func (f *ConnectionCloseFrame) Length(protocol.Version) protocol.ByteCount { func (f *ConnectionCloseFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { if f.IsApplicationError { - b = append(b, applicationCloseFrameType) + b = append(b, byte(FrameTypeApplicationClose)) } else { - b = append(b, connectionCloseFrameType) + b = append(b, byte(FrameTypeConnectionClose)) } b = quicvarint.Append(b, f.ErrorCode) diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/crypto_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/crypto_frame.go index 0aa7fe7b..60a713f7 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/crypto_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/crypto_frame.go @@ -38,7 +38,7 @@ func parseCryptoFrame(b []byte, _ protocol.Version) (*CryptoFrame, int, error) { } func (f *CryptoFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - b = append(b, cryptoFrameType) + b = append(b, byte(FrameTypeCrypto)) b = quicvarint.Append(b, uint64(f.Offset)) b = quicvarint.Append(b, uint64(len(f.Data))) b = append(b, f.Data...) diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/data_blocked_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/data_blocked_frame.go index c97d4c62..11c72ea3 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/data_blocked_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/data_blocked_frame.go @@ -19,7 +19,7 @@ func parseDataBlockedFrame(b []byte, _ protocol.Version) (*DataBlockedFrame, int } func (f *DataBlockedFrame) Append(b []byte, version protocol.Version) ([]byte, error) { - b = append(b, dataBlockedFrameType) + b = append(b, byte(FrameTypeDataBlocked)) return quicvarint.Append(b, uint64(f.MaximumData)), nil } diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/datagram_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/datagram_frame.go index 071fda9a..a6034867 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/datagram_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/datagram_frame.go @@ -19,10 +19,10 @@ type DatagramFrame struct { Data []byte } -func parseDatagramFrame(b []byte, typ uint64, _ protocol.Version) (*DatagramFrame, int, error) { +func parseDatagramFrame(b []byte, typ FrameType, _ protocol.Version) (*DatagramFrame, int, error) { startLen := len(b) f := &DatagramFrame{} - f.DataLenPresent = typ&0x1 > 0 + f.DataLenPresent = uint64(typ)&0x1 > 0 var length uint64 if f.DataLenPresent { diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/extended_header.go b/vendor/github.com/quic-go/quic-go/internal/wire/extended_header.go index 1c6ad991..6ab9fb98 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/extended_header.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/extended_header.go @@ -61,7 +61,6 @@ func (h *ExtendedHeader) Append(b []byte, v protocol.Version) ([]byte, error) { var packetType uint8 if v == protocol.Version2 { - //nolint:exhaustive switch h.Type { case protocol.PacketTypeInitial: packetType = 0b01 @@ -73,7 +72,6 @@ func (h *ExtendedHeader) Append(b []byte, v protocol.Version) ([]byte, error) { packetType = 0b00 } } else { - //nolint:exhaustive switch h.Type { case protocol.PacketTypeInitial: packetType = 0b00 diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/frame.go index 10d4eebc..09ea92f7 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/frame.go @@ -19,3 +19,15 @@ func IsProbingFrame(f Frame) bool { } return false } + +// IsProbingFrameType returns true if the FrameType is a probing frame. +// See section 9.1 of RFC 9000. +func IsProbingFrameType(f FrameType) bool { + //nolint:exhaustive // PATH_CHALLENGE, PATH_RESPONSE and NEW_CONNECTION_ID are the only probing frames + switch f { + case FrameTypePathChallenge, FrameTypePathResponse, FrameTypeNewConnectionID: + return true + default: + return false + } +} diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/frame_parser.go b/vendor/github.com/quic-go/quic-go/internal/wire/frame_parser.go index 59d41444..afc3bedb 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/frame_parser.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/frame_parser.go @@ -4,42 +4,20 @@ import ( "errors" "fmt" "io" - "reflect" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/quicvarint" ) -const ( - pingFrameType = 0x1 - ackFrameType = 0x2 - ackECNFrameType = 0x3 - resetStreamFrameType = 0x4 - stopSendingFrameType = 0x5 - cryptoFrameType = 0x6 - newTokenFrameType = 0x7 - maxDataFrameType = 0x10 - maxStreamDataFrameType = 0x11 - bidiMaxStreamsFrameType = 0x12 - uniMaxStreamsFrameType = 0x13 - dataBlockedFrameType = 0x14 - streamDataBlockedFrameType = 0x15 - bidiStreamBlockedFrameType = 0x16 - uniStreamBlockedFrameType = 0x17 - newConnectionIDFrameType = 0x18 - retireConnectionIDFrameType = 0x19 - pathChallengeFrameType = 0x1a - pathResponseFrameType = 0x1b - connectionCloseFrameType = 0x1c - applicationCloseFrameType = 0x1d - handshakeDoneFrameType = 0x1e -) +var errUnknownFrameType = errors.New("unknown frame type") // The FrameParser parses QUIC frames, one by one. type FrameParser struct { - ackDelayExponent uint8 - supportsDatagrams bool + ackDelayExponent uint8 + supportsDatagrams bool + supportsResetStreamAt bool + supportsAckFrequency bool // To avoid allocating when parsing, keep a single ACK frame struct. // It is used over and over again. @@ -47,27 +25,24 @@ type FrameParser struct { } // NewFrameParser creates a new frame parser. -func NewFrameParser(supportsDatagrams bool) *FrameParser { +func NewFrameParser(supportsDatagrams, supportsResetStreamAt, supportsAckFrequency bool) *FrameParser { return &FrameParser{ - supportsDatagrams: supportsDatagrams, - ackFrame: &AckFrame{}, + supportsDatagrams: supportsDatagrams, + supportsResetStreamAt: supportsResetStreamAt, + supportsAckFrequency: supportsAckFrequency, + ackFrame: &AckFrame{}, } } -// ParseNext parses the next frame. -// It skips PADDING frames. -func (p *FrameParser) ParseNext(data []byte, encLevel protocol.EncryptionLevel, v protocol.Version) (int, Frame, error) { - frame, l, err := p.parseNext(data, encLevel, v) - return l, frame, err -} - -func (p *FrameParser) parseNext(b []byte, encLevel protocol.EncryptionLevel, v protocol.Version) (Frame, int, error) { +// ParseType parses the frame type of the next frame. +// It skips over PADDING frames. +func (p *FrameParser) ParseType(b []byte, encLevel protocol.EncryptionLevel) (FrameType, int, error) { var parsed int for len(b) != 0 { typ, l, err := quicvarint.Parse(b) parsed += l if err != nil { - return nil, parsed, &qerr.TransportError{ + return 0, parsed, &qerr.TransportError{ ErrorCode: qerr.FrameEncodingError, ErrorMessage: err.Error(), } @@ -76,111 +51,131 @@ func (p *FrameParser) parseNext(b []byte, encLevel protocol.EncryptionLevel, v p if typ == 0x0 { // skip PADDING frames continue } - - f, l, err := p.parseFrame(b, typ, encLevel, v) - parsed += l - if err != nil { - return nil, parsed, &qerr.TransportError{ - FrameType: typ, + ft := FrameType(typ) + valid := ft.isValidRFC9000() || + (p.supportsDatagrams && ft.IsDatagramFrameType()) || + (p.supportsResetStreamAt && ft == FrameTypeResetStreamAt) || + (p.supportsAckFrequency && (ft == FrameTypeAckFrequency || ft == FrameTypeImmediateAck)) + if !valid { + return 0, parsed, &qerr.TransportError{ ErrorCode: qerr.FrameEncodingError, - ErrorMessage: err.Error(), + FrameType: typ, + ErrorMessage: errUnknownFrameType.Error(), } } - return f, parsed, nil + if !ft.isAllowedAtEncLevel(encLevel) { + return 0, parsed, &qerr.TransportError{ + ErrorCode: qerr.FrameEncodingError, + FrameType: typ, + ErrorMessage: fmt.Sprintf("%d not allowed at encryption level %s", ft, encLevel), + } + } + return ft, parsed, nil } - return nil, parsed, nil + return 0, parsed, io.EOF } -func (p *FrameParser) parseFrame(b []byte, typ uint64, encLevel protocol.EncryptionLevel, v protocol.Version) (Frame, int, error) { - var frame Frame - var err error - var l int - if typ&0xf8 == 0x8 { - frame, l, err = parseStreamFrame(b, typ, v) - } else { - switch typ { - case pingFrameType: - frame = &PingFrame{} - case ackFrameType, ackECNFrameType: - ackDelayExponent := p.ackDelayExponent - if encLevel != protocol.Encryption1RTT { - ackDelayExponent = protocol.DefaultAckDelayExponent - } - p.ackFrame.Reset() - l, err = parseAckFrame(p.ackFrame, b, typ, ackDelayExponent, v) - frame = p.ackFrame - case resetStreamFrameType: - frame, l, err = parseResetStreamFrame(b, v) - case stopSendingFrameType: - frame, l, err = parseStopSendingFrame(b, v) - case cryptoFrameType: - frame, l, err = parseCryptoFrame(b, v) - case newTokenFrameType: - frame, l, err = parseNewTokenFrame(b, v) - case maxDataFrameType: - frame, l, err = parseMaxDataFrame(b, v) - case maxStreamDataFrameType: - frame, l, err = parseMaxStreamDataFrame(b, v) - case bidiMaxStreamsFrameType, uniMaxStreamsFrameType: - frame, l, err = parseMaxStreamsFrame(b, typ, v) - case dataBlockedFrameType: - frame, l, err = parseDataBlockedFrame(b, v) - case streamDataBlockedFrameType: - frame, l, err = parseStreamDataBlockedFrame(b, v) - case bidiStreamBlockedFrameType, uniStreamBlockedFrameType: - frame, l, err = parseStreamsBlockedFrame(b, typ, v) - case newConnectionIDFrameType: - frame, l, err = parseNewConnectionIDFrame(b, v) - case retireConnectionIDFrameType: - frame, l, err = parseRetireConnectionIDFrame(b, v) - case pathChallengeFrameType: - frame, l, err = parsePathChallengeFrame(b, v) - case pathResponseFrameType: - frame, l, err = parsePathResponseFrame(b, v) - case connectionCloseFrameType, applicationCloseFrameType: - frame, l, err = parseConnectionCloseFrame(b, typ, v) - case handshakeDoneFrameType: - frame = &HandshakeDoneFrame{} - case 0x30, 0x31: - if p.supportsDatagrams { - frame, l, err = parseDatagramFrame(b, typ, v) - break - } - fallthrough - default: - err = errors.New("unknown frame type") +func (p *FrameParser) ParseStreamFrame(frameType FrameType, data []byte, v protocol.Version) (*StreamFrame, int, error) { + frame, n, err := ParseStreamFrame(data, frameType, v) + if err != nil { + return nil, n, &qerr.TransportError{ + ErrorCode: qerr.FrameEncodingError, + FrameType: uint64(frameType), + ErrorMessage: err.Error(), } } + return frame, n, nil +} + +func (p *FrameParser) ParseAckFrame(frameType FrameType, data []byte, encLevel protocol.EncryptionLevel, v protocol.Version) (*AckFrame, int, error) { + ackDelayExponent := p.ackDelayExponent + if encLevel != protocol.Encryption1RTT { + ackDelayExponent = protocol.DefaultAckDelayExponent + } + p.ackFrame.Reset() + l, err := parseAckFrame(p.ackFrame, data, frameType, ackDelayExponent, v) + if err != nil { + return nil, l, &qerr.TransportError{ + ErrorCode: qerr.FrameEncodingError, + FrameType: uint64(frameType), + ErrorMessage: err.Error(), + } + } + + return p.ackFrame, l, nil +} + +func (p *FrameParser) ParseDatagramFrame(frameType FrameType, data []byte, v protocol.Version) (*DatagramFrame, int, error) { + f, l, err := parseDatagramFrame(data, frameType, v) + if err != nil { + return nil, 0, &qerr.TransportError{ + ErrorCode: qerr.FrameEncodingError, + FrameType: uint64(frameType), + ErrorMessage: err.Error(), + } + } + return f, l, nil +} + +// ParseLessCommonFrame parses everything except STREAM, ACK or DATAGRAM. +// These cases should be handled separately for performance reasons. +func (p *FrameParser) ParseLessCommonFrame(frameType FrameType, data []byte, v protocol.Version) (Frame, int, error) { + var frame Frame + var l int + var err error + //nolint:exhaustive // Common frames should already be handled. + switch frameType { + case FrameTypePing: + frame = &PingFrame{} + case FrameTypeResetStream: + frame, l, err = parseResetStreamFrame(data, false, v) + case FrameTypeStopSending: + frame, l, err = parseStopSendingFrame(data, v) + case FrameTypeCrypto: + frame, l, err = parseCryptoFrame(data, v) + case FrameTypeNewToken: + frame, l, err = parseNewTokenFrame(data, v) + case FrameTypeMaxData: + frame, l, err = parseMaxDataFrame(data, v) + case FrameTypeMaxStreamData: + frame, l, err = parseMaxStreamDataFrame(data, v) + case FrameTypeBidiMaxStreams, FrameTypeUniMaxStreams: + frame, l, err = parseMaxStreamsFrame(data, frameType, v) + case FrameTypeDataBlocked: + frame, l, err = parseDataBlockedFrame(data, v) + case FrameTypeStreamDataBlocked: + frame, l, err = parseStreamDataBlockedFrame(data, v) + case FrameTypeBidiStreamBlocked, FrameTypeUniStreamBlocked: + frame, l, err = parseStreamsBlockedFrame(data, frameType, v) + case FrameTypeNewConnectionID: + frame, l, err = parseNewConnectionIDFrame(data, v) + case FrameTypeRetireConnectionID: + frame, l, err = parseRetireConnectionIDFrame(data, v) + case FrameTypePathChallenge: + frame, l, err = parsePathChallengeFrame(data, v) + case FrameTypePathResponse: + frame, l, err = parsePathResponseFrame(data, v) + case FrameTypeConnectionClose, FrameTypeApplicationClose: + frame, l, err = parseConnectionCloseFrame(data, frameType, v) + case FrameTypeHandshakeDone: + frame = &HandshakeDoneFrame{} + case FrameTypeResetStreamAt: + frame, l, err = parseResetStreamFrame(data, true, v) + case FrameTypeAckFrequency: + frame, l, err = parseAckFrequencyFrame(data, v) + case FrameTypeImmediateAck: + frame = &ImmediateAckFrame{} + default: + err = errUnknownFrameType + } if err != nil { - return nil, 0, err - } - if !p.isAllowedAtEncLevel(frame, encLevel) { - return nil, l, fmt.Errorf("%s not allowed at encryption level %s", reflect.TypeOf(frame).Elem().Name(), encLevel) - } - return frame, l, nil -} - -func (p *FrameParser) isAllowedAtEncLevel(f Frame, encLevel protocol.EncryptionLevel) bool { - switch encLevel { - case protocol.EncryptionInitial, protocol.EncryptionHandshake: - switch f.(type) { - case *CryptoFrame, *AckFrame, *ConnectionCloseFrame, *PingFrame: - return true - default: - return false + return frame, l, &qerr.TransportError{ + ErrorCode: qerr.FrameEncodingError, + FrameType: uint64(frameType), + ErrorMessage: err.Error(), } - case protocol.Encryption0RTT: - switch f.(type) { - case *CryptoFrame, *AckFrame, *ConnectionCloseFrame, *NewTokenFrame, *PathResponseFrame, *RetireConnectionIDFrame: - return false - default: - return true - } - case protocol.Encryption1RTT: - return true - default: - panic("unknown encryption level") } + return frame, l, err } // SetAckDelayExponent sets the acknowledgment delay exponent (sent in the transport parameters). diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/frame_type.go b/vendor/github.com/quic-go/quic-go/internal/wire/frame_type.go new file mode 100644 index 00000000..d3d086d9 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/internal/wire/frame_type.go @@ -0,0 +1,81 @@ +package wire + +import "github.com/quic-go/quic-go/internal/protocol" + +type FrameType uint64 + +// These constants correspond to those defined in RFC 9000. +// Stream frame types are not listed explicitly here; use FrameType.IsStreamFrameType() to identify them. +const ( + FrameTypePing FrameType = 0x1 + FrameTypeAck FrameType = 0x2 + FrameTypeAckECN FrameType = 0x3 + FrameTypeResetStream FrameType = 0x4 + FrameTypeStopSending FrameType = 0x5 + FrameTypeCrypto FrameType = 0x6 + FrameTypeNewToken FrameType = 0x7 + + FrameTypeMaxData FrameType = 0x10 + FrameTypeMaxStreamData FrameType = 0x11 + FrameTypeBidiMaxStreams FrameType = 0x12 + FrameTypeUniMaxStreams FrameType = 0x13 + FrameTypeDataBlocked FrameType = 0x14 + FrameTypeStreamDataBlocked FrameType = 0x15 + FrameTypeBidiStreamBlocked FrameType = 0x16 + FrameTypeUniStreamBlocked FrameType = 0x17 + FrameTypeNewConnectionID FrameType = 0x18 + FrameTypeRetireConnectionID FrameType = 0x19 + FrameTypePathChallenge FrameType = 0x1a + FrameTypePathResponse FrameType = 0x1b + FrameTypeConnectionClose FrameType = 0x1c + FrameTypeApplicationClose FrameType = 0x1d + FrameTypeHandshakeDone FrameType = 0x1e + // https://datatracker.ietf.org/doc/draft-ietf-quic-reliable-stream-reset/07/ + FrameTypeResetStreamAt FrameType = 0x24 + // https://datatracker.ietf.org/doc/draft-ietf-quic-ack-frequency/11/ + FrameTypeAckFrequency FrameType = 0xaf + FrameTypeImmediateAck FrameType = 0x1f + + FrameTypeDatagramNoLength FrameType = 0x30 + FrameTypeDatagramWithLength FrameType = 0x31 +) + +func (t FrameType) IsStreamFrameType() bool { + return t >= 0x8 && t <= 0xf +} + +func (t FrameType) isValidRFC9000() bool { + return t <= 0x1e +} + +func (t FrameType) IsAckFrameType() bool { + return t == FrameTypeAck || t == FrameTypeAckECN +} + +func (t FrameType) IsDatagramFrameType() bool { + return t == FrameTypeDatagramNoLength || t == FrameTypeDatagramWithLength +} + +func (t FrameType) isAllowedAtEncLevel(encLevel protocol.EncryptionLevel) bool { + //nolint:exhaustive + switch encLevel { + case protocol.EncryptionInitial, protocol.EncryptionHandshake: + switch t { + case FrameTypeCrypto, FrameTypeAck, FrameTypeAckECN, FrameTypeConnectionClose, FrameTypePing: + return true + default: + return false + } + case protocol.Encryption0RTT: + switch t { + case FrameTypeCrypto, FrameTypeAck, FrameTypeAckECN, FrameTypeConnectionClose, FrameTypeNewToken, FrameTypePathResponse, FrameTypeRetireConnectionID: + return false + default: + return true + } + case protocol.Encryption1RTT: + return true + default: + panic("unknown encryption level") + } +} diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/handshake_done_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/handshake_done_frame.go index 85dd6474..bf95f525 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/handshake_done_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/handshake_done_frame.go @@ -8,7 +8,7 @@ import ( type HandshakeDoneFrame struct{} func (f *HandshakeDoneFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - return append(b, handshakeDoneFrameType), nil + return append(b, byte(FrameTypeHandshakeDone)), nil } // Length of a written frame diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/immediate_ack_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/immediate_ack_frame.go new file mode 100644 index 00000000..aeff71b4 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/internal/wire/immediate_ack_frame.go @@ -0,0 +1,18 @@ +package wire + +import ( + "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/quicvarint" +) + +// An ImmediateAckFrame is an IMMEDIATE_ACK frame +type ImmediateAckFrame struct{} + +func (f *ImmediateAckFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { + return quicvarint.Append(b, uint64(FrameTypeImmediateAck)), nil +} + +// Length of a written frame +func (f *ImmediateAckFrame) Length(_ protocol.Version) protocol.ByteCount { + return protocol.ByteCount(quicvarint.Len(uint64(FrameTypeImmediateAck))) +} diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/max_data_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/max_data_frame.go index 5819c027..bfbdcba6 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/max_data_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/max_data_frame.go @@ -22,7 +22,7 @@ func parseMaxDataFrame(b []byte, _ protocol.Version) (*MaxDataFrame, int, error) } func (f *MaxDataFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - b = append(b, maxDataFrameType) + b = append(b, byte(FrameTypeMaxData)) b = quicvarint.Append(b, uint64(f.MaximumData)) return b, nil } diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/max_stream_data_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/max_stream_data_frame.go index db9091af..0966ea46 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/max_stream_data_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/max_stream_data_frame.go @@ -31,7 +31,7 @@ func parseMaxStreamDataFrame(b []byte, _ protocol.Version) (*MaxStreamDataFrame, } func (f *MaxStreamDataFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - b = append(b, maxStreamDataFrameType) + b = append(b, byte(FrameTypeMaxStreamData)) b = quicvarint.Append(b, uint64(f.StreamID)) b = quicvarint.Append(b, uint64(f.MaximumStreamData)) return b, nil diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/max_streams_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/max_streams_frame.go index a8745bd1..30612e23 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/max_streams_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/max_streams_frame.go @@ -13,12 +13,13 @@ type MaxStreamsFrame struct { MaxStreamNum protocol.StreamNum } -func parseMaxStreamsFrame(b []byte, typ uint64, _ protocol.Version) (*MaxStreamsFrame, int, error) { +func parseMaxStreamsFrame(b []byte, typ FrameType, _ protocol.Version) (*MaxStreamsFrame, int, error) { f := &MaxStreamsFrame{} + //nolint:exhaustive // Function will only be called with BidiMaxStreamsFrameType or UniMaxStreamsFrameType switch typ { - case bidiMaxStreamsFrameType: + case FrameTypeBidiMaxStreams: f.Type = protocol.StreamTypeBidi - case uniMaxStreamsFrameType: + case FrameTypeUniMaxStreams: f.Type = protocol.StreamTypeUni } streamID, l, err := quicvarint.Parse(b) @@ -35,9 +36,9 @@ func parseMaxStreamsFrame(b []byte, typ uint64, _ protocol.Version) (*MaxStreams func (f *MaxStreamsFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { switch f.Type { case protocol.StreamTypeBidi: - b = append(b, bidiMaxStreamsFrameType) + b = append(b, byte(FrameTypeBidiMaxStreams)) case protocol.StreamTypeUni: - b = append(b, uniMaxStreamsFrameType) + b = append(b, byte(FrameTypeUniMaxStreams)) } b = quicvarint.Append(b, uint64(f.MaxStreamNum)) return b, nil diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/new_connection_id_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/new_connection_id_frame.go index 6f2287f4..05831926 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/new_connection_id_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/new_connection_id_frame.go @@ -61,7 +61,7 @@ func parseNewConnectionIDFrame(b []byte, _ protocol.Version) (*NewConnectionIDFr } func (f *NewConnectionIDFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - b = append(b, newConnectionIDFrameType) + b = append(b, byte(FrameTypeNewConnectionID)) b = quicvarint.Append(b, f.SequenceNumber) b = quicvarint.Append(b, f.RetirePriorTo) connIDLen := f.ConnectionID.Len() diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/new_token_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/new_token_frame.go index f1d4d00f..73d356b1 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/new_token_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/new_token_frame.go @@ -31,7 +31,7 @@ func parseNewTokenFrame(b []byte, _ protocol.Version) (*NewTokenFrame, int, erro } func (f *NewTokenFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - b = append(b, newTokenFrameType) + b = append(b, byte(FrameTypeNewToken)) b = quicvarint.Append(b, uint64(len(f.Token))) b = append(b, f.Token...) return b, nil diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/path_challenge_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/path_challenge_frame.go index 2aca989f..7a4a767e 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/path_challenge_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/path_challenge_frame.go @@ -21,7 +21,7 @@ func parsePathChallengeFrame(b []byte, _ protocol.Version) (*PathChallengeFrame, } func (f *PathChallengeFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - b = append(b, pathChallengeFrameType) + b = append(b, byte(FrameTypePathChallenge)) b = append(b, f.Data[:]...) return b, nil } diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/path_response_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/path_response_frame.go index 76532c85..e76d037b 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/path_response_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/path_response_frame.go @@ -21,7 +21,7 @@ func parsePathResponseFrame(b []byte, _ protocol.Version) (*PathResponseFrame, i } func (f *PathResponseFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - b = append(b, pathResponseFrameType) + b = append(b, byte(FrameTypePathResponse)) b = append(b, f.Data[:]...) return b, nil } diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/ping_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/ping_frame.go index 71f8d16c..5d344d44 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/ping_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/ping_frame.go @@ -8,7 +8,7 @@ import ( type PingFrame struct{} func (f *PingFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - return append(b, pingFrameType), nil + return append(b, byte(FrameTypePing)), nil } // Length of a written frame diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/pool.go b/vendor/github.com/quic-go/quic-go/internal/wire/pool.go index 18ab4379..d656fad4 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/pool.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/pool.go @@ -9,7 +9,7 @@ import ( var pool sync.Pool func init() { - pool.New = func() interface{} { + pool.New = func() any { return &StreamFrame{ Data: make([]byte, 0, protocol.MaxPacketBufferSize), fromPool: true, diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/reset_stream_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/reset_stream_frame.go index a20029af..4101b76b 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/reset_stream_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/reset_stream_frame.go @@ -1,55 +1,79 @@ package wire import ( + "fmt" + "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/quicvarint" ) -// A ResetStreamFrame is a RESET_STREAM frame in QUIC +// A ResetStreamFrame is a RESET_STREAM or RESET_STREAM_AT frame in QUIC type ResetStreamFrame struct { - StreamID protocol.StreamID - ErrorCode qerr.StreamErrorCode - FinalSize protocol.ByteCount + StreamID protocol.StreamID + ErrorCode qerr.StreamErrorCode + FinalSize protocol.ByteCount + ReliableSize protocol.ByteCount } -func parseResetStreamFrame(b []byte, _ protocol.Version) (*ResetStreamFrame, int, error) { +func parseResetStreamFrame(b []byte, isResetStreamAt bool, _ protocol.Version) (*ResetStreamFrame, int, error) { startLen := len(b) - var streamID protocol.StreamID - var byteOffset protocol.ByteCount - sid, l, err := quicvarint.Parse(b) + streamID, l, err := quicvarint.Parse(b) if err != nil { return nil, 0, replaceUnexpectedEOF(err) } b = b[l:] - streamID = protocol.StreamID(sid) errorCode, l, err := quicvarint.Parse(b) if err != nil { return nil, 0, replaceUnexpectedEOF(err) } b = b[l:] - bo, l, err := quicvarint.Parse(b) + finalSize, l, err := quicvarint.Parse(b) if err != nil { return nil, 0, replaceUnexpectedEOF(err) } - byteOffset = protocol.ByteCount(bo) + b = b[l:] + + var reliableSize uint64 + if isResetStreamAt { + reliableSize, l, err = quicvarint.Parse(b) + if err != nil { + return nil, 0, replaceUnexpectedEOF(err) + } + b = b[l:] + } + if reliableSize > finalSize { + return nil, 0, fmt.Errorf("RESET_STREAM_AT: reliable size can't be larger than final size (%d vs %d)", reliableSize, finalSize) + } return &ResetStreamFrame{ - StreamID: streamID, - ErrorCode: qerr.StreamErrorCode(errorCode), - FinalSize: byteOffset, - }, startLen - len(b) + l, nil + StreamID: protocol.StreamID(streamID), + ErrorCode: qerr.StreamErrorCode(errorCode), + FinalSize: protocol.ByteCount(finalSize), + ReliableSize: protocol.ByteCount(reliableSize), + }, startLen - len(b), nil } func (f *ResetStreamFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - b = append(b, resetStreamFrameType) + if f.ReliableSize == 0 { + b = quicvarint.Append(b, uint64(FrameTypeResetStream)) + } else { + b = quicvarint.Append(b, uint64(FrameTypeResetStreamAt)) + } b = quicvarint.Append(b, uint64(f.StreamID)) b = quicvarint.Append(b, uint64(f.ErrorCode)) b = quicvarint.Append(b, uint64(f.FinalSize)) + if f.ReliableSize > 0 { + b = quicvarint.Append(b, uint64(f.ReliableSize)) + } return b, nil } // Length of a written frame func (f *ResetStreamFrame) Length(protocol.Version) protocol.ByteCount { - return 1 + protocol.ByteCount(quicvarint.Len(uint64(f.StreamID))+quicvarint.Len(uint64(f.ErrorCode))+quicvarint.Len(uint64(f.FinalSize))) + size := 1 // the frame type for both RESET_STREAM and RESET_STREAM_AT fits into 1 byte + if f.ReliableSize > 0 { + size += quicvarint.Len(uint64(f.ReliableSize)) + } + return protocol.ByteCount(size + quicvarint.Len(uint64(f.StreamID)) + quicvarint.Len(uint64(f.ErrorCode)) + quicvarint.Len(uint64(f.FinalSize))) } diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/retire_connection_id_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/retire_connection_id_frame.go index 27aeff84..1927f9dc 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/retire_connection_id_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/retire_connection_id_frame.go @@ -19,7 +19,7 @@ func parseRetireConnectionIDFrame(b []byte, _ protocol.Version) (*RetireConnecti } func (f *RetireConnectionIDFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - b = append(b, retireConnectionIDFrameType) + b = append(b, byte(FrameTypeRetireConnectionID)) b = quicvarint.Append(b, f.SequenceNumber) return b, nil } diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/stop_sending_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/stop_sending_frame.go index a2326f8e..2b15c710 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/stop_sending_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/stop_sending_frame.go @@ -38,7 +38,7 @@ func (f *StopSendingFrame) Length(_ protocol.Version) protocol.ByteCount { } func (f *StopSendingFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { - b = append(b, stopSendingFrameType) + b = append(b, byte(FrameTypeStopSending)) b = quicvarint.Append(b, uint64(f.StreamID)) b = quicvarint.Append(b, uint64(f.ErrorCode)) return b, nil diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/stream_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/stream_frame.go index cdc32722..e53962b1 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/stream_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/stream_frame.go @@ -19,7 +19,7 @@ type StreamFrame struct { fromPool bool } -func parseStreamFrame(b []byte, typ uint64, _ protocol.Version) (*StreamFrame, int, error) { +func ParseStreamFrame(b []byte, typ FrameType, _ protocol.Version) (*StreamFrame, int, error) { startLen := len(b) hasOffset := typ&0b100 > 0 fin := typ&0b1 > 0 diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/streams_blocked_frame.go b/vendor/github.com/quic-go/quic-go/internal/wire/streams_blocked_frame.go index c946fec3..d98fde46 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/streams_blocked_frame.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/streams_blocked_frame.go @@ -13,12 +13,13 @@ type StreamsBlockedFrame struct { StreamLimit protocol.StreamNum } -func parseStreamsBlockedFrame(b []byte, typ uint64, _ protocol.Version) (*StreamsBlockedFrame, int, error) { +func parseStreamsBlockedFrame(b []byte, typ FrameType, _ protocol.Version) (*StreamsBlockedFrame, int, error) { f := &StreamsBlockedFrame{} + //nolint:exhaustive // This will only be called with a BidiStreamBlockedFrameType or a UniStreamBlockedFrameType. switch typ { - case bidiStreamBlockedFrameType: + case FrameTypeBidiStreamBlocked: f.Type = protocol.StreamTypeBidi - case uniStreamBlockedFrameType: + case FrameTypeUniStreamBlocked: f.Type = protocol.StreamTypeUni } streamLimit, l, err := quicvarint.Parse(b) @@ -35,9 +36,9 @@ func parseStreamsBlockedFrame(b []byte, typ uint64, _ protocol.Version) (*Stream func (f *StreamsBlockedFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { switch f.Type { case protocol.StreamTypeBidi: - b = append(b, bidiStreamBlockedFrameType) + b = append(b, byte(FrameTypeBidiStreamBlocked)) case protocol.StreamTypeUni: - b = append(b, uniStreamBlockedFrameType) + b = append(b, byte(FrameTypeUniStreamBlocked)) } b = quicvarint.Append(b, uint64(f.StreamLimit)) return b, nil diff --git a/vendor/github.com/quic-go/quic-go/internal/wire/transport_parameters.go b/vendor/github.com/quic-go/quic-go/internal/wire/transport_parameters.go index d39189a0..ff101b6e 100644 --- a/vendor/github.com/quic-go/quic-go/internal/wire/transport_parameters.go +++ b/vendor/github.com/quic-go/quic-go/internal/wire/transport_parameters.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "math" "net/netip" "slices" "time" @@ -45,6 +46,10 @@ const ( retrySourceConnectionIDParameterID transportParameterID = 0x10 // RFC 9221 maxDatagramFrameSizeParameterID transportParameterID = 0x20 + // https://datatracker.ietf.org/doc/draft-ietf-quic-reliable-stream-reset/06/ + resetStreamAtParameterID transportParameterID = 0x17f7586d2cb571 + // https://datatracker.ietf.org/doc/draft-ietf-quic-ack-frequency/11/ + minAckDelayParameterID transportParameterID = 0xff04de1b ) // PreferredAddress is the value encoding in the preferred_address transport parameter @@ -82,7 +87,9 @@ type TransportParameters struct { StatelessResetToken *protocol.StatelessResetToken ActiveConnectionIDLimit uint64 - MaxDatagramFrameSize protocol.ByteCount + MaxDatagramFrameSize protocol.ByteCount // RFC 9221 + EnableResetStreamAt bool // https://datatracker.ietf.org/doc/draft-ietf-quic-reliable-stream-reset/06/ + MinAckDelay *time.Duration } // Unmarshal the transport parameters @@ -103,12 +110,12 @@ func (p *TransportParameters) unmarshal(b []byte, sentBy protocol.Perspective, f var ( readOriginalDestinationConnectionID bool readInitialSourceConnectionID bool - readActiveConnectionIDLimit bool ) p.AckDelayExponent = protocol.DefaultAckDelayExponent p.MaxAckDelay = protocol.DefaultMaxAckDelay p.MaxDatagramFrameSize = protocol.InvalidByteCount + p.ActiveConnectionIDLimit = protocol.DefaultActiveConnectionIDLimit for len(b) > 0 { paramIDInt, l, err := quicvarint.Parse(b) @@ -127,9 +134,6 @@ func (p *TransportParameters) unmarshal(b []byte, sentBy protocol.Perspective, f } parameterIDs = append(parameterIDs, paramID) switch paramID { - case activeConnectionIDLimitParameterID: - readActiveConnectionIDLimit = true - fallthrough case maxIdleTimeoutParameterID, maxUDPPayloadSizeParameterID, initialMaxDataParameterID, @@ -140,7 +144,9 @@ func (p *TransportParameters) unmarshal(b []byte, sentBy protocol.Perspective, f initialMaxStreamsUniParameterID, maxAckDelayParameterID, maxDatagramFrameSizeParameterID, - ackDelayExponentParameterID: + ackDelayExponentParameterID, + activeConnectionIDLimitParameterID, + minAckDelayParameterID: if err := p.readNumericTransportParameter(b, paramID, int(paramLen)); err != nil { return err } @@ -199,13 +205,19 @@ func (p *TransportParameters) unmarshal(b []byte, sentBy protocol.Perspective, f connID := protocol.ParseConnectionID(b[:paramLen]) b = b[paramLen:] p.RetrySourceConnectionID = &connID + case resetStreamAtParameterID: + if paramLen != 0 { + return fmt.Errorf("wrong length for reset_stream_at: %d (expected empty)", paramLen) + } + p.EnableResetStreamAt = true default: b = b[paramLen:] } } - if !readActiveConnectionIDLimit { - p.ActiveConnectionIDLimit = protocol.DefaultActiveConnectionIDLimit + // min_ack_delay must be less or equal to max_ack_delay + if p.MinAckDelay != nil && *p.MinAckDelay > p.MaxAckDelay { + return fmt.Errorf("min_ack_delay (%s) is greater than max_ack_delay (%s)", *p.MinAckDelay, p.MaxAckDelay) } if !fromSessionTicket { if sentBy == protocol.PerspectiveServer && !readOriginalDestinationConnectionID { @@ -326,6 +338,12 @@ func (p *TransportParameters) readNumericTransportParameter(b []byte, paramID tr p.ActiveConnectionIDLimit = val case maxDatagramFrameSizeParameterID: p.MaxDatagramFrameSize = protocol.ByteCount(val) + case minAckDelayParameterID: + mad := time.Duration(val) * time.Microsecond + if mad < 0 { + mad = math.MaxInt64 + } + p.MinAckDelay = &mad default: return fmt.Errorf("TransportParameter BUG: transport parameter %d not found", paramID) } @@ -428,9 +446,18 @@ func (p *TransportParameters) Marshal(pers protocol.Perspective) []byte { b = quicvarint.Append(b, uint64(p.RetrySourceConnectionID.Len())) b = append(b, p.RetrySourceConnectionID.Bytes()...) } + // QUIC datagrams if p.MaxDatagramFrameSize != protocol.InvalidByteCount { b = p.marshalVarintParam(b, maxDatagramFrameSizeParameterID, uint64(p.MaxDatagramFrameSize)) } + // QUIC Stream Resets with Partial Delivery + if p.EnableResetStreamAt { + b = quicvarint.Append(b, uint64(resetStreamAtParameterID)) + b = quicvarint.Append(b, 0) + } + if p.MinAckDelay != nil { + b = p.marshalVarintParam(b, minAckDelayParameterID, uint64(*p.MinAckDelay/time.Microsecond)) + } if pers == protocol.PerspectiveClient && len(AdditionalTransportParametersClient) > 0 { for k, v := range AdditionalTransportParametersClient { @@ -472,12 +499,18 @@ func (p *TransportParameters) MarshalForSessionTicket(b []byte) []byte { b = p.marshalVarintParam(b, initialMaxStreamsBidiParameterID, uint64(p.MaxBidiStreamNum)) // initial_max_uni_streams b = p.marshalVarintParam(b, initialMaxStreamsUniParameterID, uint64(p.MaxUniStreamNum)) + // active_connection_id_limit + b = p.marshalVarintParam(b, activeConnectionIDLimitParameterID, p.ActiveConnectionIDLimit) // max_datagram_frame_size if p.MaxDatagramFrameSize != protocol.InvalidByteCount { b = p.marshalVarintParam(b, maxDatagramFrameSizeParameterID, uint64(p.MaxDatagramFrameSize)) } - // active_connection_id_limit - return p.marshalVarintParam(b, activeConnectionIDLimitParameterID, p.ActiveConnectionIDLimit) + // reset_stream_at + if p.EnableResetStreamAt { + b = quicvarint.Append(b, uint64(resetStreamAtParameterID)) + b = quicvarint.Append(b, 0) + } + return b } // UnmarshalFromSessionTicket unmarshals transport parameters from a session ticket. @@ -524,13 +557,13 @@ func (p *TransportParameters) ValidForUpdate(saved *TransportParameters) bool { // String returns a string representation, intended for logging. func (p *TransportParameters) String() string { logString := "&wire.TransportParameters{OriginalDestinationConnectionID: %s, InitialSourceConnectionID: %s, " - logParams := []interface{}{p.OriginalDestinationConnectionID, p.InitialSourceConnectionID} + logParams := []any{p.OriginalDestinationConnectionID, p.InitialSourceConnectionID} if p.RetrySourceConnectionID != nil { logString += "RetrySourceConnectionID: %s, " logParams = append(logParams, p.RetrySourceConnectionID) } logString += "InitialMaxStreamDataBidiLocal: %d, InitialMaxStreamDataBidiRemote: %d, InitialMaxStreamDataUni: %d, InitialMaxData: %d, MaxBidiStreamNum: %d, MaxUniStreamNum: %d, MaxIdleTimeout: %s, AckDelayExponent: %d, MaxAckDelay: %s, ActiveConnectionIDLimit: %d" - logParams = append(logParams, []interface{}{p.InitialMaxStreamDataBidiLocal, p.InitialMaxStreamDataBidiRemote, p.InitialMaxStreamDataUni, p.InitialMaxData, p.MaxBidiStreamNum, p.MaxUniStreamNum, p.MaxIdleTimeout, p.AckDelayExponent, p.MaxAckDelay, p.ActiveConnectionIDLimit}...) + logParams = append(logParams, []any{p.InitialMaxStreamDataBidiLocal, p.InitialMaxStreamDataBidiRemote, p.InitialMaxStreamDataUni, p.InitialMaxData, p.MaxBidiStreamNum, p.MaxUniStreamNum, p.MaxIdleTimeout, p.AckDelayExponent, p.MaxAckDelay, p.ActiveConnectionIDLimit}...) if p.StatelessResetToken != nil { // the client never sends a stateless reset token logString += ", StatelessResetToken: %#x" logParams = append(logParams, *p.StatelessResetToken) @@ -539,6 +572,12 @@ func (p *TransportParameters) String() string { logString += ", MaxDatagramFrameSize: %d" logParams = append(logParams, p.MaxDatagramFrameSize) } + logString += ", EnableResetStreamAt: %t" + logParams = append(logParams, p.EnableResetStreamAt) + if p.MinAckDelay != nil { + logString += ", MinAckDelay: %s" + logParams = append(logParams, *p.MinAckDelay) + } logString += "}" return fmt.Sprintf(logString, logParams...) } diff --git a/vendor/github.com/quic-go/quic-go/logging/connection_tracer.go b/vendor/github.com/quic-go/quic-go/logging/connection_tracer.go deleted file mode 100644 index f218e046..00000000 --- a/vendor/github.com/quic-go/quic-go/logging/connection_tracer.go +++ /dev/null @@ -1,44 +0,0 @@ -package logging - -import ( - "net" - "time" -) - -//go:generate go run generate_multiplexer.go ConnectionTracer connection_tracer.go multiplexer.tmpl connection_tracer_multiplexer.go - -// A ConnectionTracer records events. -type ConnectionTracer struct { - StartedConnection func(local, remote net.Addr, srcConnID, destConnID ConnectionID) - NegotiatedVersion func(chosen Version, clientVersions, serverVersions []Version) - ClosedConnection func(err error) - SentTransportParameters func(parameters *TransportParameters) - ReceivedTransportParameters func(parameters *TransportParameters) - RestoredTransportParameters func(parameters *TransportParameters) // for 0-RTT - SentLongHeaderPacket func(hdr *ExtendedHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) - SentShortHeaderPacket func(hdr *ShortHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) - ReceivedVersionNegotiationPacket func(dest, src ArbitraryLenConnectionID, versions []Version) - ReceivedRetry func(hdr *Header) - ReceivedLongHeaderPacket func(hdr *ExtendedHeader, size ByteCount, ecn ECN, frames []Frame) - ReceivedShortHeaderPacket func(hdr *ShortHeader, size ByteCount, ecn ECN, frames []Frame) - BufferedPacket func(packetType PacketType, size ByteCount) - DroppedPacket func(packetType PacketType, pn PacketNumber, size ByteCount, reason PacketDropReason) - UpdatedMetrics func(rttStats *RTTStats, cwnd, bytesInFlight ByteCount, packetsInFlight int) - AcknowledgedPacket func(encLevel EncryptionLevel, pn PacketNumber) - LostPacket func(encLevel EncryptionLevel, pn PacketNumber, reason PacketLossReason) - UpdatedMTU func(mtu ByteCount, done bool) - UpdatedCongestionState func(state CongestionState) - UpdatedPTOCount func(value uint32) - UpdatedKeyFromTLS func(encLevel EncryptionLevel, p Perspective) - UpdatedKey func(keyPhase KeyPhase, remote bool) - DroppedEncryptionLevel func(encLevel EncryptionLevel) - DroppedKey func(keyPhase KeyPhase) - SetLossTimer func(timerType TimerType, encLevel EncryptionLevel, time time.Time) - LossTimerExpired func(timerType TimerType, encLevel EncryptionLevel) - LossTimerCanceled func() - ECNStateUpdated func(state ECNState, trigger ECNStateTrigger) - ChoseALPN func(protocol string) - // Close is called when the connection is closed. - Close func() - Debug func(name, msg string) -} diff --git a/vendor/github.com/quic-go/quic-go/logging/connection_tracer_multiplexer.go b/vendor/github.com/quic-go/quic-go/logging/connection_tracer_multiplexer.go deleted file mode 100644 index 3a87058c..00000000 --- a/vendor/github.com/quic-go/quic-go/logging/connection_tracer_multiplexer.go +++ /dev/null @@ -1,236 +0,0 @@ -// Code generated by generate_multiplexer.go; DO NOT EDIT. - -package logging - -import ( - "net" - "time" -) - -func NewMultiplexedConnectionTracer(tracers ...*ConnectionTracer) *ConnectionTracer { - if len(tracers) == 0 { - return nil - } - if len(tracers) == 1 { - return tracers[0] - } - return &ConnectionTracer{ - StartedConnection: func(local net.Addr, remote net.Addr, srcConnID ConnectionID, destConnID ConnectionID) { - for _, t := range tracers { - if t.StartedConnection != nil { - t.StartedConnection(local, remote, srcConnID, destConnID) - } - } - }, - NegotiatedVersion: func(chosen Version, clientVersions []Version, serverVersions []Version) { - for _, t := range tracers { - if t.NegotiatedVersion != nil { - t.NegotiatedVersion(chosen, clientVersions, serverVersions) - } - } - }, - ClosedConnection: func(err error) { - for _, t := range tracers { - if t.ClosedConnection != nil { - t.ClosedConnection(err) - } - } - }, - SentTransportParameters: func(parameters *TransportParameters) { - for _, t := range tracers { - if t.SentTransportParameters != nil { - t.SentTransportParameters(parameters) - } - } - }, - ReceivedTransportParameters: func(parameters *TransportParameters) { - for _, t := range tracers { - if t.ReceivedTransportParameters != nil { - t.ReceivedTransportParameters(parameters) - } - } - }, - RestoredTransportParameters: func(parameters *TransportParameters) { - for _, t := range tracers { - if t.RestoredTransportParameters != nil { - t.RestoredTransportParameters(parameters) - } - } - }, - SentLongHeaderPacket: func(hdr *ExtendedHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) { - for _, t := range tracers { - if t.SentLongHeaderPacket != nil { - t.SentLongHeaderPacket(hdr, size, ecn, ack, frames) - } - } - }, - SentShortHeaderPacket: func(hdr *ShortHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) { - for _, t := range tracers { - if t.SentShortHeaderPacket != nil { - t.SentShortHeaderPacket(hdr, size, ecn, ack, frames) - } - } - }, - ReceivedVersionNegotiationPacket: func(dest ArbitraryLenConnectionID, src ArbitraryLenConnectionID, versions []Version) { - for _, t := range tracers { - if t.ReceivedVersionNegotiationPacket != nil { - t.ReceivedVersionNegotiationPacket(dest, src, versions) - } - } - }, - ReceivedRetry: func(hdr *Header) { - for _, t := range tracers { - if t.ReceivedRetry != nil { - t.ReceivedRetry(hdr) - } - } - }, - ReceivedLongHeaderPacket: func(hdr *ExtendedHeader, size ByteCount, ecn ECN, frames []Frame) { - for _, t := range tracers { - if t.ReceivedLongHeaderPacket != nil { - t.ReceivedLongHeaderPacket(hdr, size, ecn, frames) - } - } - }, - ReceivedShortHeaderPacket: func(hdr *ShortHeader, size ByteCount, ecn ECN, frames []Frame) { - for _, t := range tracers { - if t.ReceivedShortHeaderPacket != nil { - t.ReceivedShortHeaderPacket(hdr, size, ecn, frames) - } - } - }, - BufferedPacket: func(packetType PacketType, size ByteCount) { - for _, t := range tracers { - if t.BufferedPacket != nil { - t.BufferedPacket(packetType, size) - } - } - }, - DroppedPacket: func(packetType PacketType, pn PacketNumber, size ByteCount, reason PacketDropReason) { - for _, t := range tracers { - if t.DroppedPacket != nil { - t.DroppedPacket(packetType, pn, size, reason) - } - } - }, - UpdatedMetrics: func(rttStats *RTTStats, cwnd ByteCount, bytesInFlight ByteCount, packetsInFlight int) { - for _, t := range tracers { - if t.UpdatedMetrics != nil { - t.UpdatedMetrics(rttStats, cwnd, bytesInFlight, packetsInFlight) - } - } - }, - AcknowledgedPacket: func(encLevel EncryptionLevel, pn PacketNumber) { - for _, t := range tracers { - if t.AcknowledgedPacket != nil { - t.AcknowledgedPacket(encLevel, pn) - } - } - }, - LostPacket: func(encLevel EncryptionLevel, pn PacketNumber, reason PacketLossReason) { - for _, t := range tracers { - if t.LostPacket != nil { - t.LostPacket(encLevel, pn, reason) - } - } - }, - UpdatedMTU: func(mtu ByteCount, done bool) { - for _, t := range tracers { - if t.UpdatedMTU != nil { - t.UpdatedMTU(mtu, done) - } - } - }, - UpdatedCongestionState: func(state CongestionState) { - for _, t := range tracers { - if t.UpdatedCongestionState != nil { - t.UpdatedCongestionState(state) - } - } - }, - UpdatedPTOCount: func(value uint32) { - for _, t := range tracers { - if t.UpdatedPTOCount != nil { - t.UpdatedPTOCount(value) - } - } - }, - UpdatedKeyFromTLS: func(encLevel EncryptionLevel, p Perspective) { - for _, t := range tracers { - if t.UpdatedKeyFromTLS != nil { - t.UpdatedKeyFromTLS(encLevel, p) - } - } - }, - UpdatedKey: func(keyPhase KeyPhase, remote bool) { - for _, t := range tracers { - if t.UpdatedKey != nil { - t.UpdatedKey(keyPhase, remote) - } - } - }, - DroppedEncryptionLevel: func(encLevel EncryptionLevel) { - for _, t := range tracers { - if t.DroppedEncryptionLevel != nil { - t.DroppedEncryptionLevel(encLevel) - } - } - }, - DroppedKey: func(keyPhase KeyPhase) { - for _, t := range tracers { - if t.DroppedKey != nil { - t.DroppedKey(keyPhase) - } - } - }, - SetLossTimer: func(timerType TimerType, encLevel EncryptionLevel, time time.Time) { - for _, t := range tracers { - if t.SetLossTimer != nil { - t.SetLossTimer(timerType, encLevel, time) - } - } - }, - LossTimerExpired: func(timerType TimerType, encLevel EncryptionLevel) { - for _, t := range tracers { - if t.LossTimerExpired != nil { - t.LossTimerExpired(timerType, encLevel) - } - } - }, - LossTimerCanceled: func() { - for _, t := range tracers { - if t.LossTimerCanceled != nil { - t.LossTimerCanceled() - } - } - }, - ECNStateUpdated: func(state ECNState, trigger ECNStateTrigger) { - for _, t := range tracers { - if t.ECNStateUpdated != nil { - t.ECNStateUpdated(state, trigger) - } - } - }, - ChoseALPN: func(protocol string) { - for _, t := range tracers { - if t.ChoseALPN != nil { - t.ChoseALPN(protocol) - } - } - }, - Close: func() { - for _, t := range tracers { - if t.Close != nil { - t.Close() - } - } - }, - Debug: func(name string, msg string) { - for _, t := range tracers { - if t.Debug != nil { - t.Debug(name, msg) - } - } - }, - } -} diff --git a/vendor/github.com/quic-go/quic-go/logging/frame.go b/vendor/github.com/quic-go/quic-go/logging/frame.go deleted file mode 100644 index 9a055db3..00000000 --- a/vendor/github.com/quic-go/quic-go/logging/frame.go +++ /dev/null @@ -1,66 +0,0 @@ -package logging - -import "github.com/quic-go/quic-go/internal/wire" - -// A Frame is a QUIC frame -type Frame interface{} - -// The AckRange is used within the AckFrame. -// It is a range of packet numbers that is being acknowledged. -type AckRange = wire.AckRange - -type ( - // An AckFrame is an ACK frame. - AckFrame = wire.AckFrame - // A ConnectionCloseFrame is a CONNECTION_CLOSE frame. - ConnectionCloseFrame = wire.ConnectionCloseFrame - // A DataBlockedFrame is a DATA_BLOCKED frame. - DataBlockedFrame = wire.DataBlockedFrame - // A HandshakeDoneFrame is a HANDSHAKE_DONE frame. - HandshakeDoneFrame = wire.HandshakeDoneFrame - // A MaxDataFrame is a MAX_DATA frame. - MaxDataFrame = wire.MaxDataFrame - // A MaxStreamDataFrame is a MAX_STREAM_DATA frame. - MaxStreamDataFrame = wire.MaxStreamDataFrame - // A MaxStreamsFrame is a MAX_STREAMS_FRAME. - MaxStreamsFrame = wire.MaxStreamsFrame - // A NewConnectionIDFrame is a NEW_CONNECTION_ID frame. - NewConnectionIDFrame = wire.NewConnectionIDFrame - // A NewTokenFrame is a NEW_TOKEN frame. - NewTokenFrame = wire.NewTokenFrame - // A PathChallengeFrame is a PATH_CHALLENGE frame. - PathChallengeFrame = wire.PathChallengeFrame - // A PathResponseFrame is a PATH_RESPONSE frame. - PathResponseFrame = wire.PathResponseFrame - // A PingFrame is a PING frame. - PingFrame = wire.PingFrame - // A ResetStreamFrame is a RESET_STREAM frame. - ResetStreamFrame = wire.ResetStreamFrame - // A RetireConnectionIDFrame is a RETIRE_CONNECTION_ID frame. - RetireConnectionIDFrame = wire.RetireConnectionIDFrame - // A StopSendingFrame is a STOP_SENDING frame. - StopSendingFrame = wire.StopSendingFrame - // A StreamsBlockedFrame is a STREAMS_BLOCKED frame. - StreamsBlockedFrame = wire.StreamsBlockedFrame - // A StreamDataBlockedFrame is a STREAM_DATA_BLOCKED frame. - StreamDataBlockedFrame = wire.StreamDataBlockedFrame -) - -// A CryptoFrame is a CRYPTO frame. -type CryptoFrame struct { - Offset ByteCount - Length ByteCount -} - -// A StreamFrame is a STREAM frame. -type StreamFrame struct { - StreamID StreamID - Offset ByteCount - Length ByteCount - Fin bool -} - -// A DatagramFrame is a DATAGRAM frame. -type DatagramFrame struct { - Length ByteCount -} diff --git a/vendor/github.com/quic-go/quic-go/logging/generate_multiplexer.go b/vendor/github.com/quic-go/quic-go/logging/generate_multiplexer.go deleted file mode 100644 index c152b846..00000000 --- a/vendor/github.com/quic-go/quic-go/logging/generate_multiplexer.go +++ /dev/null @@ -1,161 +0,0 @@ -//go:build generate - -package main - -import ( - "bytes" - "fmt" - "go/ast" - "go/parser" - "go/printer" - "go/token" - "log" - "os" - "strings" - "text/template" - - "golang.org/x/tools/imports" -) - -func main() { - if len(os.Args) != 5 { - log.Fatalf("Usage: %s ", os.Args[0]) - } - - structName := os.Args[1] - inputFile := os.Args[2] - templateFile := os.Args[3] - outputFile := os.Args[4] - - fset := token.NewFileSet() - - // Parse the input file containing the struct type - file, err := parser.ParseFile(fset, inputFile, nil, parser.AllErrors) - if err != nil { - log.Fatalf("Failed to parse file: %v", err) - } - - var fields []*ast.Field - - // Find the specified struct type in the AST - for _, decl := range file.Decls { - genDecl, ok := decl.(*ast.GenDecl) - if !ok || genDecl.Tok != token.TYPE { - continue - } - for _, spec := range genDecl.Specs { - typeSpec, ok := spec.(*ast.TypeSpec) - if !ok || typeSpec.Name.Name != structName { - continue - } - structType, ok := typeSpec.Type.(*ast.StructType) - if !ok { - log.Fatalf("%s is not a struct", structName) - } - fields = structType.Fields.List - break - } - } - - if fields == nil { - log.Fatalf("Could not find %s type", structName) - } - - // Prepare data for the template - type FieldData struct { - Name string - Params string - Args string - HasParams bool - ReturnTypes string - HasReturn bool - } - - var fieldDataList []FieldData - - for _, field := range fields { - funcType, ok := field.Type.(*ast.FuncType) - if !ok { - continue - } - for _, name := range field.Names { - fieldData := FieldData{Name: name.Name} - - // extract parameters - var params []string - var args []string - if funcType.Params != nil { - for i, param := range funcType.Params.List { - // We intentionally reject unnamed (and, further down, "_") function parameters. - // We could auto-generate parameter names, - // but having meaningful variable names will be more helpful for the user. - if len(param.Names) == 0 { - log.Fatalf("encountered unnamed parameter at position %d in function %s", i, fieldData.Name) - } - var buf bytes.Buffer - printer.Fprint(&buf, fset, param.Type) - paramType := buf.String() - for _, paramName := range param.Names { - if paramName.Name == "_" { - log.Fatalf("encountered underscore parameter at position %d in function %s", i, fieldData.Name) - } - params = append(params, fmt.Sprintf("%s %s", paramName.Name, paramType)) - args = append(args, paramName.Name) - } - } - } - fieldData.Params = strings.Join(params, ", ") - fieldData.Args = strings.Join(args, ", ") - fieldData.HasParams = len(params) > 0 - - // extract return types - if funcType.Results != nil && len(funcType.Results.List) > 0 { - fieldData.HasReturn = true - var returns []string - for _, result := range funcType.Results.List { - var buf bytes.Buffer - printer.Fprint(&buf, fset, result.Type) - returns = append(returns, buf.String()) - } - if len(returns) == 1 { - fieldData.ReturnTypes = fmt.Sprintf(" %s", returns[0]) - } else { - fieldData.ReturnTypes = fmt.Sprintf(" (%s)", strings.Join(returns, ", ")) - } - } - - fieldDataList = append(fieldDataList, fieldData) - } - } - - // Read the template from file - templateContent, err := os.ReadFile(templateFile) - if err != nil { - log.Fatalf("Failed to read template file: %v", err) - } - - // Generate the code using the template - tmpl, err := template.New("multiplexer").Funcs(template.FuncMap{"join": strings.Join}).Parse(string(templateContent)) - if err != nil { - log.Fatalf("Failed to parse template: %v", err) - } - - var generatedCode bytes.Buffer - generatedCode.WriteString("// Code generated by generate_multiplexer.go; DO NOT EDIT.\n\n") - if err = tmpl.Execute(&generatedCode, map[string]interface{}{ - "Fields": fieldDataList, - "StructName": structName, - }); err != nil { - log.Fatalf("Failed to execute template: %v", err) - } - - // Format the generated code and add imports - formattedCode, err := imports.Process(outputFile, generatedCode.Bytes(), nil) - if err != nil { - log.Fatalf("Failed to process imports: %v", err) - } - - if err := os.WriteFile(outputFile, formattedCode, 0o644); err != nil { - log.Fatalf("Failed to write output file: %v", err) - } -} diff --git a/vendor/github.com/quic-go/quic-go/logging/interface.go b/vendor/github.com/quic-go/quic-go/logging/interface.go deleted file mode 100644 index 1f8edb92..00000000 --- a/vendor/github.com/quic-go/quic-go/logging/interface.go +++ /dev/null @@ -1,111 +0,0 @@ -// Package logging defines a logging interface for quic-go. -// This package should not be considered stable -package logging - -import ( - "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/qerr" - "github.com/quic-go/quic-go/internal/utils" - "github.com/quic-go/quic-go/internal/wire" -) - -type ( - // A ByteCount is used to count bytes. - ByteCount = protocol.ByteCount - // ECN is the ECN value - ECN = protocol.ECN - // A ConnectionID is a QUIC Connection ID. - ConnectionID = protocol.ConnectionID - // An ArbitraryLenConnectionID is a QUIC Connection ID that can be up to 255 bytes long. - ArbitraryLenConnectionID = protocol.ArbitraryLenConnectionID - // The EncryptionLevel is the encryption level of a packet. - EncryptionLevel = protocol.EncryptionLevel - // The KeyPhase is the key phase of the 1-RTT keys. - KeyPhase = protocol.KeyPhase - // The KeyPhaseBit is the value of the key phase bit of the 1-RTT packets. - KeyPhaseBit = protocol.KeyPhaseBit - // The PacketNumber is the packet number of a packet. - PacketNumber = protocol.PacketNumber - // The Perspective is the role of a QUIC endpoint (client or server). - Perspective = protocol.Perspective - // A StatelessResetToken is a stateless reset token. - StatelessResetToken = protocol.StatelessResetToken - // The StreamID is the stream ID. - StreamID = protocol.StreamID - // The StreamNum is the number of the stream. - StreamNum = protocol.StreamNum - // The StreamType is the type of the stream (unidirectional or bidirectional). - StreamType = protocol.StreamType - // The Version is the QUIC version. - Version = protocol.Version - - // The Header is the QUIC packet header, before removing header protection. - Header = wire.Header - // The ExtendedHeader is the QUIC Long Header packet header, after removing header protection. - ExtendedHeader = wire.ExtendedHeader - // The TransportParameters are QUIC transport parameters. - TransportParameters = wire.TransportParameters - // The PreferredAddress is the preferred address sent in the transport parameters. - PreferredAddress = wire.PreferredAddress - - // A TransportError is a transport-level error code. - TransportError = qerr.TransportErrorCode - // An ApplicationError is an application-defined error code. - ApplicationError = qerr.TransportErrorCode - - // The RTTStats contain statistics used by the congestion controller. - RTTStats = utils.RTTStats -) - -const ( - // ECNUnsupported means that no ECN value was set / received - ECNUnsupported = protocol.ECNUnsupported - // ECTNot is Not-ECT - ECTNot = protocol.ECNNon - // ECT0 is ECT(0) - ECT0 = protocol.ECT0 - // ECT1 is ECT(1) - ECT1 = protocol.ECT1 - // ECNCE is CE - ECNCE = protocol.ECNCE -) - -const ( - // KeyPhaseZero is key phase bit 0 - KeyPhaseZero = protocol.KeyPhaseZero - // KeyPhaseOne is key phase bit 1 - KeyPhaseOne = protocol.KeyPhaseOne -) - -const ( - // PerspectiveServer is used for a QUIC server - PerspectiveServer = protocol.PerspectiveServer - // PerspectiveClient is used for a QUIC client - PerspectiveClient = protocol.PerspectiveClient -) - -const ( - // EncryptionInitial is the Initial encryption level - EncryptionInitial = protocol.EncryptionInitial - // EncryptionHandshake is the Handshake encryption level - EncryptionHandshake = protocol.EncryptionHandshake - // Encryption1RTT is the 1-RTT encryption level - Encryption1RTT = protocol.Encryption1RTT - // Encryption0RTT is the 0-RTT encryption level - Encryption0RTT = protocol.Encryption0RTT -) - -const ( - // StreamTypeUni is a unidirectional stream - StreamTypeUni = protocol.StreamTypeUni - // StreamTypeBidi is a bidirectional stream - StreamTypeBidi = protocol.StreamTypeBidi -) - -// The ShortHeader is the QUIC Short Header packet header, after removing header protection. -type ShortHeader struct { - DestConnectionID ConnectionID - PacketNumber PacketNumber - PacketNumberLen protocol.PacketNumberLen - KeyPhase KeyPhaseBit -} diff --git a/vendor/github.com/quic-go/quic-go/logging/multiplexer.tmpl b/vendor/github.com/quic-go/quic-go/logging/multiplexer.tmpl deleted file mode 100644 index 9ba52e0f..00000000 --- a/vendor/github.com/quic-go/quic-go/logging/multiplexer.tmpl +++ /dev/null @@ -1,21 +0,0 @@ -package logging - -func NewMultiplexed{{ .StructName }} (tracers ...*{{ .StructName }}) *{{ .StructName }} { - if len(tracers) == 0 { - return nil - } - if len(tracers) == 1 { - return tracers[0] - } - return &{{ .StructName }}{ - {{- range .Fields }} - {{ .Name }}: func({{ .Params }}){{ .ReturnTypes }} { - for _, t := range tracers { - if t.{{ .Name }} != nil { - t.{{ .Name }}({{ .Args }}) - } - } - }, - {{- end }} - } -} diff --git a/vendor/github.com/quic-go/quic-go/logging/packet_header.go b/vendor/github.com/quic-go/quic-go/logging/packet_header.go deleted file mode 100644 index 6b8df58d..00000000 --- a/vendor/github.com/quic-go/quic-go/logging/packet_header.go +++ /dev/null @@ -1,24 +0,0 @@ -package logging - -import ( - "github.com/quic-go/quic-go/internal/protocol" -) - -// PacketTypeFromHeader determines the packet type from a *wire.Header. -func PacketTypeFromHeader(hdr *Header) PacketType { - if hdr.Version == 0 { - return PacketTypeVersionNegotiation - } - switch hdr.Type { - case protocol.PacketTypeInitial: - return PacketTypeInitial - case protocol.PacketTypeHandshake: - return PacketTypeHandshake - case protocol.PacketType0RTT: - return PacketType0RTT - case protocol.PacketTypeRetry: - return PacketTypeRetry - default: - return PacketTypeNotDetermined - } -} diff --git a/vendor/github.com/quic-go/quic-go/logging/tracer.go b/vendor/github.com/quic-go/quic-go/logging/tracer.go deleted file mode 100644 index 4fe01462..00000000 --- a/vendor/github.com/quic-go/quic-go/logging/tracer.go +++ /dev/null @@ -1,14 +0,0 @@ -package logging - -import "net" - -//go:generate go run generate_multiplexer.go Tracer tracer.go multiplexer.tmpl tracer_multiplexer.go - -// A Tracer traces events. -type Tracer struct { - SentPacket func(dest net.Addr, hdr *Header, size ByteCount, frames []Frame) - SentVersionNegotiationPacket func(dest net.Addr, destConnID, srcConnID ArbitraryLenConnectionID, versions []Version) - DroppedPacket func(addr net.Addr, packetType PacketType, size ByteCount, reason PacketDropReason) - Debug func(name, msg string) - Close func() -} diff --git a/vendor/github.com/quic-go/quic-go/logging/tracer_multiplexer.go b/vendor/github.com/quic-go/quic-go/logging/tracer_multiplexer.go deleted file mode 100644 index f0878cfe..00000000 --- a/vendor/github.com/quic-go/quic-go/logging/tracer_multiplexer.go +++ /dev/null @@ -1,51 +0,0 @@ -// Code generated by generate_multiplexer.go; DO NOT EDIT. - -package logging - -import "net" - -func NewMultiplexedTracer(tracers ...*Tracer) *Tracer { - if len(tracers) == 0 { - return nil - } - if len(tracers) == 1 { - return tracers[0] - } - return &Tracer{ - SentPacket: func(dest net.Addr, hdr *Header, size ByteCount, frames []Frame) { - for _, t := range tracers { - if t.SentPacket != nil { - t.SentPacket(dest, hdr, size, frames) - } - } - }, - SentVersionNegotiationPacket: func(dest net.Addr, destConnID ArbitraryLenConnectionID, srcConnID ArbitraryLenConnectionID, versions []Version) { - for _, t := range tracers { - if t.SentVersionNegotiationPacket != nil { - t.SentVersionNegotiationPacket(dest, destConnID, srcConnID, versions) - } - } - }, - DroppedPacket: func(addr net.Addr, packetType PacketType, size ByteCount, reason PacketDropReason) { - for _, t := range tracers { - if t.DroppedPacket != nil { - t.DroppedPacket(addr, packetType, size, reason) - } - } - }, - Debug: func(name string, msg string) { - for _, t := range tracers { - if t.Debug != nil { - t.Debug(name, msg) - } - } - }, - Close: func() { - for _, t := range tracers { - if t.Close != nil { - t.Close() - } - } - }, - } -} diff --git a/vendor/github.com/quic-go/quic-go/logging/types.go b/vendor/github.com/quic-go/quic-go/logging/types.go deleted file mode 100644 index 65da3559..00000000 --- a/vendor/github.com/quic-go/quic-go/logging/types.go +++ /dev/null @@ -1,130 +0,0 @@ -package logging - -// PacketType is the packet type of a QUIC packet -type PacketType uint8 - -const ( - // PacketTypeInitial is the packet type of an Initial packet - PacketTypeInitial PacketType = iota - // PacketTypeHandshake is the packet type of a Handshake packet - PacketTypeHandshake - // PacketTypeRetry is the packet type of a Retry packet - PacketTypeRetry - // PacketType0RTT is the packet type of a 0-RTT packet - PacketType0RTT - // PacketTypeVersionNegotiation is the packet type of a Version Negotiation packet - PacketTypeVersionNegotiation - // PacketType1RTT is a 1-RTT packet - PacketType1RTT - // PacketTypeStatelessReset is a stateless reset - PacketTypeStatelessReset - // PacketTypeNotDetermined is the packet type when it could not be determined - PacketTypeNotDetermined -) - -type PacketLossReason uint8 - -const ( - // PacketLossReorderingThreshold: when a packet is deemed lost due to reordering threshold - PacketLossReorderingThreshold PacketLossReason = iota - // PacketLossTimeThreshold: when a packet is deemed lost due to time threshold - PacketLossTimeThreshold -) - -type PacketDropReason uint8 - -const ( - // PacketDropKeyUnavailable is used when a packet is dropped because keys are unavailable - PacketDropKeyUnavailable PacketDropReason = iota - // PacketDropUnknownConnectionID is used when a packet is dropped because the connection ID is unknown - PacketDropUnknownConnectionID - // PacketDropHeaderParseError is used when a packet is dropped because header parsing failed - PacketDropHeaderParseError - // PacketDropPayloadDecryptError is used when a packet is dropped because decrypting the payload failed - PacketDropPayloadDecryptError - // PacketDropProtocolViolation is used when a packet is dropped due to a protocol violation - PacketDropProtocolViolation - // PacketDropDOSPrevention is used when a packet is dropped to mitigate a DoS attack - PacketDropDOSPrevention - // PacketDropUnsupportedVersion is used when a packet is dropped because the version is not supported - PacketDropUnsupportedVersion - // PacketDropUnexpectedPacket is used when an unexpected packet is received - PacketDropUnexpectedPacket - // PacketDropUnexpectedSourceConnectionID is used when a packet with an unexpected source connection ID is received - PacketDropUnexpectedSourceConnectionID - // PacketDropUnexpectedVersion is used when a packet with an unexpected version is received - PacketDropUnexpectedVersion - // PacketDropDuplicate is used when a duplicate packet is received - PacketDropDuplicate -) - -// TimerType is the type of the loss detection timer -type TimerType uint8 - -const ( - // TimerTypeACK is the timer type for the early retransmit timer - TimerTypeACK TimerType = iota + 1 - // TimerTypePTO is the timer type for the PTO retransmit timer - TimerTypePTO - // TimerTypePathProbe is the timer type for the path probe retransmit timer - TimerTypePathProbe -) - -// TimeoutReason is the reason why a connection is closed -type TimeoutReason uint8 - -const ( - // TimeoutReasonHandshake is used when the connection is closed due to a handshake timeout - // This reason is not defined in the qlog draft, but very useful for debugging. - TimeoutReasonHandshake TimeoutReason = iota - // TimeoutReasonIdle is used when the connection is closed due to an idle timeout - // This reason is not defined in the qlog draft, but very useful for debugging. - TimeoutReasonIdle -) - -type CongestionState uint8 - -const ( - // CongestionStateSlowStart is the slow start phase of Reno / Cubic - CongestionStateSlowStart CongestionState = iota - // CongestionStateCongestionAvoidance is the slow start phase of Reno / Cubic - CongestionStateCongestionAvoidance - // CongestionStateRecovery is the recovery phase of Reno / Cubic - CongestionStateRecovery - // CongestionStateApplicationLimited means that the congestion controller is application limited - CongestionStateApplicationLimited -) - -// ECNState is the state of the ECN state machine (see Appendix A.4 of RFC 9000) -type ECNState uint8 - -const ( - // ECNStateTesting is the testing state - ECNStateTesting ECNState = 1 + iota - // ECNStateUnknown is the unknown state - ECNStateUnknown - // ECNStateFailed is the failed state - ECNStateFailed - // ECNStateCapable is the capable state - ECNStateCapable -) - -// ECNStateTrigger is a trigger for an ECN state transition. -type ECNStateTrigger uint8 - -const ( - ECNTriggerNoTrigger ECNStateTrigger = iota - // ECNFailedNoECNCounts is emitted when an ACK acknowledges ECN-marked packets, - // but doesn't contain any ECN counts - ECNFailedNoECNCounts - // ECNFailedDecreasedECNCounts is emitted when an ACK frame decreases ECN counts - ECNFailedDecreasedECNCounts - // ECNFailedLostAllTestingPackets is emitted when all ECN testing packets are declared lost - ECNFailedLostAllTestingPackets - // ECNFailedMoreECNCountsThanSent is emitted when an ACK contains more ECN counts than ECN-marked packets were sent - ECNFailedMoreECNCountsThanSent - // ECNFailedTooFewECNCounts is emitted when an ACK contains fewer ECN counts than it acknowledges packets - ECNFailedTooFewECNCounts - // ECNFailedManglingDetected is emitted when the path marks all ECN-marked packets as CE - ECNFailedManglingDetected -) diff --git a/vendor/github.com/quic-go/quic-go/mockgen.go b/vendor/github.com/quic-go/quic-go/mockgen.go index 1a8b28db..65160d0d 100644 --- a/vendor/github.com/quic-go/quic-go/mockgen.go +++ b/vendor/github.com/quic-go/quic-go/mockgen.go @@ -2,63 +2,46 @@ package quic -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn" type SendConn = sendConn -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn" type RawConn = rawConn -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender" type Sender = sender -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_internal_test.go github.com/quic-go/quic-go StreamI" -type StreamI = streamI - -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_receive_stream_internal_test.go github.com/quic-go/quic-go ReceiveStreamI" -type ReceiveStreamI = receiveStreamI - -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_stream_internal_test.go github.com/quic-go/quic-go SendStreamI" -type SendStreamI = sendStreamI - -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_sender_test.go github.com/quic-go/quic-go StreamSender" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_sender_test.go github.com/quic-go/quic-go StreamSender" type StreamSender = streamSender -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_control_frame_getter_test.go github.com/quic-go/quic-go StreamControlFrameGetter" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_control_frame_getter_test.go github.com/quic-go/quic-go StreamControlFrameGetter" type StreamControlFrameGetter = streamControlFrameGetter -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_frame_source_test.go github.com/quic-go/quic-go FrameSource" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_frame_getter_test.go github.com/quic-go/quic-go StreamFrameGetter" +type StreamFrameGetter = streamFrameGetter + +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_frame_source_test.go github.com/quic-go/quic-go FrameSource" type FrameSource = frameSource -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_ack_frame_source_test.go github.com/quic-go/quic-go AckFrameSource" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_ack_frame_source_test.go github.com/quic-go/quic-go AckFrameSource" type AckFrameSource = ackFrameSource -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_manager_test.go github.com/quic-go/quic-go StreamManager" -type StreamManager = streamManager - -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sealing_manager_test.go github.com/quic-go/quic-go SealingManager" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sealing_manager_test.go github.com/quic-go/quic-go SealingManager" type SealingManager = sealingManager -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_unpacker_test.go github.com/quic-go/quic-go Unpacker" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_unpacker_test.go github.com/quic-go/quic-go Unpacker" type Unpacker = unpacker -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packer_test.go github.com/quic-go/quic-go Packer" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packer_test.go github.com/quic-go/quic-go Packer" type Packer = packer -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_mtu_discoverer_test.go github.com/quic-go/quic-go MTUDiscoverer" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_mtu_discoverer_test.go github.com/quic-go/quic-go MTUDiscoverer" type MTUDiscoverer = mtuDiscoverer -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_conn_runner_test.go github.com/quic-go/quic-go ConnRunner" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_conn_runner_test.go github.com/quic-go/quic-go ConnRunner" type ConnRunner = connRunner -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_quic_conn_test.go github.com/quic-go/quic-go QUICConn" -type QUICConn = quicConn - -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler" +//go:generate sh -c "go tool mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler" type PacketHandler = packetHandler -//go:generate sh -c "go run go.uber.org/mock/mockgen -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager" - -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -build_flags=\"-tags=gomock\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager" -type PacketHandlerManager = packetHandlerManager - -//go:generate sh -c "go run go.uber.org/mock/mockgen -typed -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_packetconn_test.go net PacketConn" +//go:generate sh -c "go tool mockgen -typed -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_packetconn_test.go net PacketConn" diff --git a/vendor/github.com/quic-go/quic-go/mtu_discoverer.go b/vendor/github.com/quic-go/quic-go/mtu_discoverer.go index 096eba14..950757f0 100644 --- a/vendor/github.com/quic-go/quic-go/mtu_discoverer.go +++ b/vendor/github.com/quic-go/quic-go/mtu_discoverer.go @@ -1,23 +1,23 @@ package quic import ( - "time" - "github.com/quic-go/quic-go/internal/ackhandler" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" + "github.com/quic-go/quic-go/qlogwriter" ) type mtuDiscoverer interface { // Start starts the MTU discovery process. // It's unnecessary to call ShouldSendProbe before that. - Start(now time.Time) - ShouldSendProbe(now time.Time) bool + Start(now monotime.Time) + ShouldSendProbe(now monotime.Time) bool CurrentSize() protocol.ByteCount - GetPing(now time.Time) (ping ackhandler.Frame, datagramSize protocol.ByteCount) - Reset(now time.Time, start, max protocol.ByteCount) + GetPing(now monotime.Time) (ping ackhandler.Frame, datagramSize protocol.ByteCount) + Reset(now monotime.Time, start, max protocol.ByteCount) } const ( @@ -88,7 +88,7 @@ const ( // MTU discovery concludes once the interval min and max has been narrowed down to maxMTUDiff. type mtuFinder struct { - lastProbeTime time.Time + lastProbeTime monotime.Time rttStats *utils.RTTStats @@ -104,7 +104,7 @@ type mtuFinder struct { // We're therefore not concerned about overflows of this counter. generation uint8 - tracer *logging.ConnectionTracer + qlogger qlogwriter.Recorder } var _ mtuDiscoverer = &mtuFinder{} @@ -112,12 +112,12 @@ var _ mtuDiscoverer = &mtuFinder{} func newMTUDiscoverer( rttStats *utils.RTTStats, start, max protocol.ByteCount, - tracer *logging.ConnectionTracer, + qlogger qlogwriter.Recorder, ) *mtuFinder { f := &mtuFinder{ inFlight: protocol.InvalidByteCount, rttStats: rttStats, - tracer: tracer, + qlogger: qlogger, } f.init(start, max) return f @@ -147,11 +147,11 @@ func (f *mtuFinder) max() protocol.ByteCount { return f.lost[len(f.lost)-1] } -func (f *mtuFinder) Start(now time.Time) { +func (f *mtuFinder) Start(now monotime.Time) { f.lastProbeTime = now // makes sure the first probe packet is not sent immediately } -func (f *mtuFinder) ShouldSendProbe(now time.Time) bool { +func (f *mtuFinder) ShouldSendProbe(now monotime.Time) bool { if f.lastProbeTime.IsZero() { return false } @@ -161,7 +161,7 @@ func (f *mtuFinder) ShouldSendProbe(now time.Time) bool { return !now.Before(f.lastProbeTime.Add(mtuProbeDelay * f.rttStats.SmoothedRTT())) } -func (f *mtuFinder) GetPing(now time.Time) (ackhandler.Frame, protocol.ByteCount) { +func (f *mtuFinder) GetPing(now monotime.Time) (ackhandler.Frame, protocol.ByteCount) { var size protocol.ByteCount if f.lastProbeWasLost { size = (f.min + f.lost[0]) / 2 @@ -180,7 +180,7 @@ func (f *mtuFinder) CurrentSize() protocol.ByteCount { return f.min } -func (f *mtuFinder) Reset(now time.Time, start, max protocol.ByteCount) { +func (f *mtuFinder) Reset(now monotime.Time, start, max protocol.ByteCount) { f.generation++ f.lastProbeTime = now f.lastProbeWasLost = false @@ -224,8 +224,11 @@ func (h *mtuFinderAckHandler) OnAcked(wire.Frame) { } } } - if h.tracer != nil && h.tracer.UpdatedMTU != nil { - h.tracer.UpdatedMTU(size, h.done()) + if h.qlogger != nil { + h.qlogger.RecordEvent(qlog.MTUUpdated{ + Value: int(size), + Done: h.done(), + }) } } diff --git a/vendor/github.com/quic-go/quic-go/oss-fuzz.sh b/vendor/github.com/quic-go/quic-go/oss-fuzz.sh index 92a57a2c..3884a10f 100644 --- a/vendor/github.com/quic-go/quic-go/oss-fuzz.sh +++ b/vendor/github.com/quic-go/quic-go/oss-fuzz.sh @@ -3,12 +3,12 @@ # Install Go manually, since oss-fuzz ships with an outdated Go version. # See https://github.com/google/oss-fuzz/pull/10643. export CXX="${CXX} -lresolv" # required by Go 1.20 -wget https://go.dev/dl/go1.23.0.linux-amd64.tar.gz \ +wget https://go.dev/dl/go1.25.0.linux-amd64.tar.gz \ && mkdir temp-go \ && rm -rf /root/.go/* \ - && tar -C temp-go/ -xzf go1.23.0.linux-amd64.tar.gz \ + && tar -C temp-go/ -xzf go1.25.0.linux-amd64.tar.gz \ && mv temp-go/go/* /root/.go/ \ - && rm -rf temp-go go1.23.0.linux-amd64.tar.gz + && rm -rf temp-go go1.25.0.linux-amd64.tar.gz ( # fuzz qpack diff --git a/vendor/github.com/quic-go/quic-go/packet_handler_map.go b/vendor/github.com/quic-go/quic-go/packet_handler_map.go deleted file mode 100644 index 84841984..00000000 --- a/vendor/github.com/quic-go/quic-go/packet_handler_map.go +++ /dev/null @@ -1,228 +0,0 @@ -package quic - -import ( - "io" - "net" - "sync" - "time" - - "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/utils" -) - -type connCapabilities struct { - // This connection has the Don't Fragment (DF) bit set. - // This means it makes to run DPLPMTUD. - DF bool - // GSO (Generic Segmentation Offload) supported - GSO bool - // ECN (Explicit Congestion Notifications) supported - ECN bool -} - -// rawConn is a connection that allow reading of a receivedPackeh. -type rawConn interface { - ReadPacket() (receivedPacket, error) - // WritePacket writes a packet on the wire. - // gsoSize is the size of a single packet, or 0 to disable GSO. - // It is invalid to set gsoSize if capabilities.GSO is not set. - WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16, ecn protocol.ECN) (int, error) - LocalAddr() net.Addr - SetReadDeadline(time.Time) error - io.Closer - - capabilities() connCapabilities -} - -type closePacket struct { - payload []byte - addr net.Addr - info packetInfo -} - -type packetHandlerMap struct { - mutex sync.Mutex - handlers map[protocol.ConnectionID]packetHandler - resetTokens map[protocol.StatelessResetToken] /* stateless reset token */ packetHandler - - closed bool - closeChan chan struct{} - - enqueueClosePacket func(closePacket) - - deleteRetiredConnsAfter time.Duration - - logger utils.Logger -} - -var _ packetHandlerManager = &packetHandlerMap{} - -func newPacketHandlerMap(enqueueClosePacket func(closePacket), logger utils.Logger) *packetHandlerMap { - h := &packetHandlerMap{ - closeChan: make(chan struct{}), - handlers: make(map[protocol.ConnectionID]packetHandler), - resetTokens: make(map[protocol.StatelessResetToken]packetHandler), - deleteRetiredConnsAfter: protocol.RetiredConnectionIDDeleteTimeout, - enqueueClosePacket: enqueueClosePacket, - logger: logger, - } - if h.logger.Debug() { - go h.logUsage() - } - return h -} - -func (h *packetHandlerMap) logUsage() { - ticker := time.NewTicker(2 * time.Second) - var printedZero bool - for { - select { - case <-h.closeChan: - return - case <-ticker.C: - } - - h.mutex.Lock() - numHandlers := len(h.handlers) - numTokens := len(h.resetTokens) - h.mutex.Unlock() - // If the number tracked handlers and tokens is zero, only print it a single time. - hasZero := numHandlers == 0 && numTokens == 0 - if !hasZero || (hasZero && !printedZero) { - h.logger.Debugf("Tracking %d connection IDs and %d reset tokens.\n", numHandlers, numTokens) - printedZero = false - if hasZero { - printedZero = true - } - } - } -} - -func (h *packetHandlerMap) Get(id protocol.ConnectionID) (packetHandler, bool) { - h.mutex.Lock() - defer h.mutex.Unlock() - - handler, ok := h.handlers[id] - return handler, ok -} - -func (h *packetHandlerMap) Add(id protocol.ConnectionID, handler packetHandler) bool /* was added */ { - h.mutex.Lock() - defer h.mutex.Unlock() - - if _, ok := h.handlers[id]; ok { - h.logger.Debugf("Not adding connection ID %s, as it already exists.", id) - return false - } - h.handlers[id] = handler - h.logger.Debugf("Adding connection ID %s.", id) - return true -} - -func (h *packetHandlerMap) AddWithConnID(clientDestConnID, newConnID protocol.ConnectionID, handler packetHandler) bool { - h.mutex.Lock() - defer h.mutex.Unlock() - - if _, ok := h.handlers[clientDestConnID]; ok { - h.logger.Debugf("Not adding connection ID %s for a new connection, as it already exists.", clientDestConnID) - return false - } - h.handlers[clientDestConnID] = handler - h.handlers[newConnID] = handler - h.logger.Debugf("Adding connection IDs %s and %s for a new connection.", clientDestConnID, newConnID) - return true -} - -func (h *packetHandlerMap) Remove(id protocol.ConnectionID) { - h.mutex.Lock() - delete(h.handlers, id) - h.mutex.Unlock() - h.logger.Debugf("Removing connection ID %s.", id) -} - -func (h *packetHandlerMap) Retire(id protocol.ConnectionID) { - h.logger.Debugf("Retiring connection ID %s in %s.", id, h.deleteRetiredConnsAfter) - time.AfterFunc(h.deleteRetiredConnsAfter, func() { - h.mutex.Lock() - delete(h.handlers, id) - h.mutex.Unlock() - h.logger.Debugf("Removing connection ID %s after it has been retired.", id) - }) -} - -// ReplaceWithClosed is called when a connection is closed. -// Depending on which side closed the connection, we need to: -// * remote close: absorb delayed packets -// * local close: retransmit the CONNECTION_CLOSE packet, in case it was lost -func (h *packetHandlerMap) ReplaceWithClosed(ids []protocol.ConnectionID, connClosePacket []byte) { - var handler packetHandler - if connClosePacket != nil { - handler = newClosedLocalConn( - func(addr net.Addr, info packetInfo) { - h.enqueueClosePacket(closePacket{payload: connClosePacket, addr: addr, info: info}) - }, - h.logger, - ) - } else { - handler = newClosedRemoteConn() - } - - h.mutex.Lock() - for _, id := range ids { - h.handlers[id] = handler - } - h.mutex.Unlock() - h.logger.Debugf("Replacing connection for connection IDs %s with a closed connection.", ids) - - time.AfterFunc(h.deleteRetiredConnsAfter, func() { - h.mutex.Lock() - for _, id := range ids { - delete(h.handlers, id) - } - h.mutex.Unlock() - h.logger.Debugf("Removing connection IDs %s for a closed connection after it has been retired.", ids) - }) -} - -func (h *packetHandlerMap) AddResetToken(token protocol.StatelessResetToken, handler packetHandler) { - h.mutex.Lock() - h.resetTokens[token] = handler - h.mutex.Unlock() -} - -func (h *packetHandlerMap) RemoveResetToken(token protocol.StatelessResetToken) { - h.mutex.Lock() - delete(h.resetTokens, token) - h.mutex.Unlock() -} - -func (h *packetHandlerMap) GetByResetToken(token protocol.StatelessResetToken) (packetHandler, bool) { - h.mutex.Lock() - defer h.mutex.Unlock() - - handler, ok := h.resetTokens[token] - return handler, ok -} - -func (h *packetHandlerMap) Close(e error) { - h.mutex.Lock() - - if h.closed { - h.mutex.Unlock() - return - } - - close(h.closeChan) - - var wg sync.WaitGroup - for _, handler := range h.handlers { - wg.Add(1) - go func(handler packetHandler) { - handler.destroy(e) - wg.Done() - }(handler) - } - h.closed = true - h.mutex.Unlock() - wg.Wait() -} diff --git a/vendor/github.com/quic-go/quic-go/packet_packer.go b/vendor/github.com/quic-go/quic-go/packet_packer.go index e84a6c02..175d3c86 100644 --- a/vendor/github.com/quic-go/quic-go/packet_packer.go +++ b/vendor/github.com/quic-go/quic-go/packet_packer.go @@ -6,10 +6,10 @@ import ( "errors" "fmt" "math/rand/v2" - "time" "github.com/quic-go/quic-go/internal/ackhandler" "github.com/quic-go/quic-go/internal/handshake" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/wire" @@ -18,10 +18,10 @@ import ( var errNothingToPack = errors.New("nothing to pack") type packer interface { - PackCoalescedPacket(onlyAck bool, maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (*coalescedPacket, error) - PackAckOnlyPacket(maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) - AppendPacket(_ *packetBuffer, maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, error) - PackPTOProbePacket(_ protocol.EncryptionLevel, _ protocol.ByteCount, addPingIfEmpty bool, now time.Time, v protocol.Version) (*coalescedPacket, error) + PackCoalescedPacket(onlyAck bool, maxPacketSize protocol.ByteCount, now monotime.Time, v protocol.Version) (*coalescedPacket, error) + PackAckOnlyPacket(maxPacketSize protocol.ByteCount, now monotime.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) + AppendPacket(_ *packetBuffer, maxPacketSize protocol.ByteCount, now monotime.Time, v protocol.Version) (shortHeaderPacket, error) + PackPTOProbePacket(_ protocol.EncryptionLevel, _ protocol.ByteCount, addPingIfEmpty bool, now monotime.Time, v protocol.Version) (*coalescedPacket, error) PackConnectionClose(*qerr.TransportError, protocol.ByteCount, protocol.Version) (*coalescedPacket, error) PackApplicationClose(*qerr.ApplicationError, protocol.ByteCount, protocol.Version) (*coalescedPacket, error) PackPathProbePacket(protocol.ConnectionID, []ackhandler.Frame, protocol.Version) (shortHeaderPacket, *packetBuffer, error) @@ -108,11 +108,11 @@ type sealingManager interface { type frameSource interface { HasData() bool - Append([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount, time.Time, protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) + Append([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount, monotime.Time, protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) } type ackFrameSource interface { - GetAckFrame(_ protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame + GetAckFrame(_ protocol.EncryptionLevel, now monotime.Time, onlyIfQueued bool) *wire.AckFrame } type packetPacker struct { @@ -122,7 +122,7 @@ type packetPacker struct { perspective protocol.Perspective cryptoSetup sealingManager - initialStream *cryptoStream + initialStream *initialCryptoStream handshakeStream *cryptoStream token []byte @@ -142,7 +142,8 @@ var _ packer = &packetPacker{} func newPacketPacker( srcConnID protocol.ConnectionID, getDestConnID func() protocol.ConnectionID, - initialStream, handshakeStream *cryptoStream, + initialStream *initialCryptoStream, + handshakeStream *cryptoStream, packetNumberManager packetNumberManager, retransmissionQueue *retransmissionQueue, cryptoSetup sealingManager, @@ -329,7 +330,7 @@ func (p *packetPacker) initialPaddingLen(frames []ackhandler.Frame, currentSize, // PackCoalescedPacket packs a new packet. // It packs an Initial / Handshake if there is data to send in these packet number spaces. // It should only be called before the handshake is confirmed. -func (p *packetPacker) PackCoalescedPacket(onlyAck bool, maxSize protocol.ByteCount, now time.Time, v protocol.Version) (*coalescedPacket, error) { +func (p *packetPacker) PackCoalescedPacket(onlyAck bool, maxSize protocol.ByteCount, now monotime.Time, v protocol.Version) (*coalescedPacket, error) { var ( initialHdr, handshakeHdr, zeroRTTHdr *wire.ExtendedHeader initialPayload, handshakePayload, zeroRTTPayload, oneRTTPayload payload @@ -349,7 +350,6 @@ func (p *packetPacker) PackCoalescedPacket(onlyAck bool, maxSize protocol.ByteCo now, false, onlyAck, - true, v, ) if initialPayload.length > 0 { @@ -372,7 +372,6 @@ func (p *packetPacker) PackCoalescedPacket(onlyAck bool, maxSize protocol.ByteCo now, false, onlyAck, - size == 0, v, ) if handshakePayload.length > 0 { @@ -398,7 +397,7 @@ func (p *packetPacker) PackCoalescedPacket(onlyAck bool, maxSize protocol.ByteCo connID = p.getDestConnID() oneRTTPacketNumber, oneRTTPacketNumberLen = p.pnManager.PeekPacketNumber(protocol.Encryption1RTT) hdrLen := wire.ShortHeaderLen(connID, oneRTTPacketNumberLen) - oneRTTPayload = p.maybeGetShortHeaderPacket(oneRTTSealer, hdrLen, maxSize-size, onlyAck, size == 0, now, v) + oneRTTPayload = p.maybeGetShortHeaderPacket(oneRTTSealer, hdrLen, maxSize-size, onlyAck, now, v) if oneRTTPayload.length > 0 { size += p.shortHeaderPacketLength(connID, oneRTTPacketNumberLen, oneRTTPayload) + protocol.ByteCount(oneRTTSealer.Overhead()) } @@ -459,7 +458,7 @@ func (p *packetPacker) PackCoalescedPacket(onlyAck bool, maxSize protocol.ByteCo // PackAckOnlyPacket packs a packet containing only an ACK in the application data packet number space. // It should be called after the handshake is confirmed. -func (p *packetPacker) PackAckOnlyPacket(maxSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) { +func (p *packetPacker) PackAckOnlyPacket(maxSize protocol.ByteCount, now monotime.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) { buf := getPacketBuffer() packet, err := p.appendPacket(buf, true, maxSize, now, v) return packet, buf, err @@ -467,7 +466,7 @@ func (p *packetPacker) PackAckOnlyPacket(maxSize protocol.ByteCount, now time.Ti // AppendPacket packs a packet in the application data packet number space. // It should be called after the handshake is confirmed. -func (p *packetPacker) AppendPacket(buf *packetBuffer, maxSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, error) { +func (p *packetPacker) AppendPacket(buf *packetBuffer, maxSize protocol.ByteCount, now monotime.Time, v protocol.Version) (shortHeaderPacket, error) { return p.appendPacket(buf, false, maxSize, now, v) } @@ -475,7 +474,7 @@ func (p *packetPacker) appendPacket( buf *packetBuffer, onlyAck bool, maxPacketSize protocol.ByteCount, - now time.Time, + now monotime.Time, v protocol.Version, ) (shortHeaderPacket, error) { sealer, err := p.cryptoSetup.Get1RTTSealer() @@ -485,7 +484,7 @@ func (p *packetPacker) appendPacket( pn, pnLen := p.pnManager.PeekPacketNumber(protocol.Encryption1RTT) connID := p.getDestConnID() hdrLen := wire.ShortHeaderLen(connID, pnLen) - pl := p.maybeGetShortHeaderPacket(sealer, hdrLen, maxPacketSize, onlyAck, true, now, v) + pl := p.maybeGetShortHeaderPacket(sealer, hdrLen, maxPacketSize, onlyAck, now, v) if pl.length == 0 { return shortHeaderPacket{}, errNothingToPack } @@ -497,39 +496,38 @@ func (p *packetPacker) appendPacket( func (p *packetPacker) maybeGetCryptoPacket( maxPacketSize protocol.ByteCount, encLevel protocol.EncryptionLevel, - now time.Time, + now monotime.Time, addPingIfEmpty bool, - onlyAck, ackAllowed bool, + onlyAck bool, v protocol.Version, ) (*wire.ExtendedHeader, payload) { if onlyAck { if ack := p.acks.GetAckFrame(encLevel, now, true); ack != nil { - return p.getLongHeader(encLevel, v), payload{ - ack: ack, - length: ack.Length(v), - } + hdr := p.getLongHeader(encLevel, v) + maxPacketSize -= hdr.GetLength(v) + ack.Truncate(maxPacketSize, v) + return hdr, payload{ack: ack, length: ack.Length(v)} } - return nil, payload{} + return nil, payload{length: 0} } - var s *cryptoStream + var hasCryptoData func() bool + var popCryptoFrame func(maxLen protocol.ByteCount) *wire.CryptoFrame //nolint:exhaustive // Initial and Handshake are the only two encryption levels here. switch encLevel { case protocol.EncryptionInitial: - s = p.initialStream + hasCryptoData = p.initialStream.HasData + popCryptoFrame = p.initialStream.PopCryptoFrame case protocol.EncryptionHandshake: - s = p.handshakeStream + hasCryptoData = p.handshakeStream.HasData + popCryptoFrame = p.handshakeStream.PopCryptoFrame } - hasData := s.HasData() handler := p.retransmissionQueue.AckHandler(encLevel) hasRetransmission := p.retransmissionQueue.HasData(encLevel) - var ack *wire.AckFrame - if ackAllowed { - ack = p.acks.GetAckFrame(encLevel, now, !hasRetransmission && !hasData) - } + ack := p.acks.GetAckFrame(encLevel, now, !hasRetransmission && !hasCryptoData()) var pl payload - if !hasData && !hasRetransmission && ack == nil { + if !hasCryptoData() && !hasRetransmission && ack == nil { if !addPingIfEmpty { // nothing to send return nil, payload{} @@ -539,13 +537,15 @@ func (p *packetPacker) maybeGetCryptoPacket( pl.length += ping.Length(v) } + hdr := p.getLongHeader(encLevel, v) + maxPacketSize -= hdr.GetLength(v) + if ack != nil { + ack.Truncate(maxPacketSize, v) pl.ack = ack pl.length = ack.Length(v) maxPacketSize -= pl.length } - hdr := p.getLongHeader(encLevel, v) - maxPacketSize -= hdr.GetLength(v) if hasRetransmission { for { frame := p.retransmissionQueue.GetFrame(encLevel, maxPacketSize, v) @@ -560,15 +560,22 @@ func (p *packetPacker) maybeGetCryptoPacket( pl.length += frameLen maxPacketSize -= frameLen } - } else if s.HasData() { - cf := s.PopCryptoFrame(maxPacketSize) - pl.frames = append(pl.frames, ackhandler.Frame{Frame: cf, Handler: handler}) - pl.length += cf.Length(v) + return hdr, pl + } else { + for hasCryptoData() { + cf := popCryptoFrame(maxPacketSize) + if cf == nil { + break + } + pl.frames = append(pl.frames, ackhandler.Frame{Frame: cf, Handler: handler}) + pl.length += cf.Length(v) + maxPacketSize -= cf.Length(v) + } } return hdr, pl } -func (p *packetPacker) maybeGetAppDataPacketFor0RTT(sealer sealer, maxSize protocol.ByteCount, now time.Time, v protocol.Version) (*wire.ExtendedHeader, payload) { +func (p *packetPacker) maybeGetAppDataPacketFor0RTT(sealer sealer, maxSize protocol.ByteCount, now monotime.Time, v protocol.Version) (*wire.ExtendedHeader, payload) { if p.perspective != protocol.PerspectiveClient { return nil, payload{} } @@ -581,18 +588,18 @@ func (p *packetPacker) maybeGetAppDataPacketFor0RTT(sealer sealer, maxSize proto func (p *packetPacker) maybeGetShortHeaderPacket( sealer handshake.ShortHeaderSealer, hdrLen, maxPacketSize protocol.ByteCount, - onlyAck, ackAllowed bool, - now time.Time, + onlyAck bool, + now monotime.Time, v protocol.Version, ) payload { maxPayloadSize := maxPacketSize - hdrLen - protocol.ByteCount(sealer.Overhead()) - return p.maybeGetAppDataPacket(maxPayloadSize, onlyAck, ackAllowed, now, v) + return p.maybeGetAppDataPacket(maxPayloadSize, onlyAck, true, now, v) } func (p *packetPacker) maybeGetAppDataPacket( maxPayloadSize protocol.ByteCount, onlyAck, ackAllowed bool, - now time.Time, + now monotime.Time, v protocol.Version, ) payload { pl := p.composeNextPacket(maxPayloadSize, onlyAck, ackAllowed, now, v) @@ -620,11 +627,12 @@ func (p *packetPacker) maybeGetAppDataPacket( func (p *packetPacker) composeNextPacket( maxPayloadSize protocol.ByteCount, onlyAck, ackAllowed bool, - now time.Time, + now monotime.Time, v protocol.Version, ) payload { if onlyAck { if ack := p.acks.GetAckFrame(protocol.Encryption1RTT, now, true); ack != nil { + ack.Truncate(maxPayloadSize, v) return payload{ack: ack, length: ack.Length(v)} } return payload{} @@ -633,13 +641,12 @@ func (p *packetPacker) composeNextPacket( hasData := p.framer.HasData() hasRetransmission := p.retransmissionQueue.HasData(protocol.Encryption1RTT) - var hasAck bool var pl payload if ackAllowed { if ack := p.acks.GetAckFrame(protocol.Encryption1RTT, now, !hasRetransmission && !hasData); ack != nil { + ack.Truncate(maxPayloadSize, v) pl.ack = ack pl.length += ack.Length(v) - hasAck = true } } @@ -650,7 +657,7 @@ func (p *packetPacker) composeNextPacket( pl.frames = append(pl.frames, ackhandler.Frame{Frame: f}) pl.length += size p.datagramQueue.Pop() - } else if !hasAck { + } else if pl.ack == nil { // The DATAGRAM frame doesn't fit, and the packet doesn't contain an ACK. // Discard this frame. There's no point in retrying this in the next packet, // as it's unlikely that the available packet size will increase. @@ -660,7 +667,7 @@ func (p *packetPacker) composeNextPacket( } } - if hasAck && !hasData && !hasRetransmission { + if pl.ack != nil && !hasData && !hasRetransmission { return pl } @@ -706,7 +713,7 @@ func (p *packetPacker) PackPTOProbePacket( encLevel protocol.EncryptionLevel, maxPacketSize protocol.ByteCount, addPingIfEmpty bool, - now time.Time, + now monotime.Time, v protocol.Version, ) (*coalescedPacket, error) { if encLevel == protocol.Encryption1RTT { @@ -737,7 +744,6 @@ func (p *packetPacker) PackPTOProbePacket( now, addPingIfEmpty, false, - true, v, ) if pl.length == 0 { @@ -759,7 +765,7 @@ func (p *packetPacker) PackPTOProbePacket( return packet, nil } -func (p *packetPacker) packPTOProbePacket1RTT(maxPacketSize protocol.ByteCount, addPingIfEmpty bool, now time.Time, v protocol.Version) (*coalescedPacket, error) { +func (p *packetPacker) packPTOProbePacket1RTT(maxPacketSize protocol.ByteCount, addPingIfEmpty bool, now monotime.Time, v protocol.Version) (*coalescedPacket, error) { s, err := p.cryptoSetup.Get1RTTSealer() if err != nil { return nil, err diff --git a/vendor/github.com/quic-go/quic-go/packet_unpacker.go b/vendor/github.com/quic-go/quic-go/packet_unpacker.go index 2f607fbd..0729636e 100644 --- a/vendor/github.com/quic-go/quic-go/packet_unpacker.go +++ b/vendor/github.com/quic-go/quic-go/packet_unpacker.go @@ -2,9 +2,9 @@ package quic import ( "fmt" - "time" "github.com/quic-go/quic-go/internal/handshake" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/wire" @@ -106,7 +106,7 @@ func (u *packetUnpacker) UnpackLongHeader(hdr *wire.Header, data []byte) (*unpac }, nil } -func (u *packetUnpacker) UnpackShortHeader(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) { +func (u *packetUnpacker) UnpackShortHeader(rcvTime monotime.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) { opener, err := u.cs.Get1RTTOpener() if err != nil { return 0, 0, 0, nil, err @@ -144,7 +144,7 @@ func (u *packetUnpacker) unpackLongHeaderPacket(opener handshake.LongHeaderOpene return extHdr, decrypted, nil } -func (u *packetUnpacker) unpackShortHeaderPacket(opener handshake.ShortHeaderOpener, rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) { +func (u *packetUnpacker) unpackShortHeaderPacket(opener handshake.ShortHeaderOpener, rcvTime monotime.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) { l, pn, pnLen, kp, parseErr := u.unpackShortHeader(opener, data) // If the reserved bits are set incorrectly, we still need to continue unpacking. // This avoids a timing side-channel, which otherwise might allow an attacker diff --git a/vendor/github.com/quic-go/quic-go/path_manager.go b/vendor/github.com/quic-go/quic-go/path_manager.go index 34096654..dd188ea1 100644 --- a/vendor/github.com/quic-go/quic-go/path_manager.go +++ b/vendor/github.com/quic-go/quic-go/path_manager.go @@ -7,6 +7,7 @@ import ( "time" "github.com/quic-go/quic-go/internal/ackhandler" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" @@ -30,7 +31,7 @@ const pathTimeout = 5 * time.Second type path struct { id pathID addr net.Addr - lastPacketTime time.Time + lastPacketTime monotime.Time pathChallenge [8]byte validated bool rcvdNonProbing bool @@ -64,7 +65,7 @@ func newPathManager( // May return nil. func (pm *pathManager) HandlePacket( remoteAddr net.Addr, - t time.Time, + t monotime.Time, pathChallenge *wire.PathChallengeFrame, // may be nil if the packet didn't contain a PATH_CHALLENGE isNonProbing bool, ) (_ protocol.ConnectionID, _ []ackhandler.Frame, shouldSwitch bool) { diff --git a/vendor/github.com/quic-go/quic-go/path_manager_outgoing.go b/vendor/github.com/quic-go/quic-go/path_manager_outgoing.go index 595eda23..78f68eea 100644 --- a/vendor/github.com/quic-go/quic-go/path_manager_outgoing.go +++ b/vendor/github.com/quic-go/quic-go/path_manager_outgoing.go @@ -50,6 +50,7 @@ func (p *Path) Probe(ctx context.Context) error { p.validated.Store(true) return nil case <-timerChan: + nextProbeDur *= 2 // exponential backoff p.pathManager.enqueueProbe(p) case <-path.ProbeSent(): case <-p.abandon: @@ -61,7 +62,6 @@ func (p *Path) Probe(ctx context.Context) error { } timer = time.NewTimer(nextProbeDur) timerChan = timer.C - nextProbeDur *= 2 // exponential backoff } } @@ -128,6 +128,9 @@ type pathManagerOutgoing struct { pathToSwitchTo *pathOutgoing } +// newPathManagerOutgoing creates a new pathManagerOutgoing object. This +// function must be side-effect free as it may be called multiple times for a +// single connection. func newPathManagerOutgoing( getConnID func(pathID) (_ protocol.ConnectionID, ok bool), retireConnID func(pathID), diff --git a/vendor/github.com/quic-go/quic-go/qlog/event.go b/vendor/github.com/quic-go/quic-go/qlog/event.go new file mode 100644 index 00000000..83ca71f1 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/qlog/event.go @@ -0,0 +1,849 @@ +package qlog + +import ( + "fmt" + "net/netip" + "time" + + "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/internal/qerr" + "github.com/quic-go/quic-go/qlogwriter/jsontext" +) + +func milliseconds(dur time.Duration) float64 { return float64(dur.Nanoseconds()) / 1e6 } + +type encoderHelper struct { + enc *jsontext.Encoder + err error +} + +func (h *encoderHelper) WriteToken(t jsontext.Token) { + if h.err != nil { + return + } + h.err = h.enc.WriteToken(t) +} + +type versions []Version + +func (v versions) encode(enc *jsontext.Encoder) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginArray) + for _, e := range v { + h.WriteToken(jsontext.String(fmt.Sprintf("%x", uint32(e)))) + } + h.WriteToken(jsontext.EndArray) + return h.err +} + +type RawInfo struct { + Length int // full packet length, including header and AEAD authentication tag + PayloadLength int // length of the packet payload, excluding AEAD tag +} + +func (i RawInfo) encode(enc *jsontext.Encoder) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("length")) + h.WriteToken(jsontext.Uint(uint64(i.Length))) + if i.PayloadLength != 0 { + h.WriteToken(jsontext.String("payload_length")) + h.WriteToken(jsontext.Uint(uint64(i.PayloadLength))) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type PathEndpointInfo struct { + IPv4 netip.AddrPort + IPv6 netip.AddrPort +} + +func (p PathEndpointInfo) encode(enc *jsontext.Encoder) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + if p.IPv4.IsValid() { + h.WriteToken(jsontext.String("ip_v4")) + h.WriteToken(jsontext.String(p.IPv4.Addr().String())) + h.WriteToken(jsontext.String("port_v4")) + h.WriteToken(jsontext.Int(int64(p.IPv4.Port()))) + } + if p.IPv6.IsValid() { + h.WriteToken(jsontext.String("ip_v6")) + h.WriteToken(jsontext.String(p.IPv6.Addr().String())) + h.WriteToken(jsontext.String("port_v6")) + h.WriteToken(jsontext.Int(int64(p.IPv6.Port()))) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type StartedConnection struct { + Local PathEndpointInfo + Remote PathEndpointInfo +} + +func (e StartedConnection) Name() string { return "transport:connection_started" } + +func (e StartedConnection) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("local")) + if err := e.Local.encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.String("remote")) + if err := e.Remote.encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type VersionInformation struct { + ClientVersions, ServerVersions []Version + ChosenVersion Version +} + +func (e VersionInformation) Name() string { return "transport:version_information" } + +func (e VersionInformation) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + if len(e.ClientVersions) > 0 { + h.WriteToken(jsontext.String("client_versions")) + if err := versions(e.ClientVersions).encode(enc); err != nil { + return err + } + } + if len(e.ServerVersions) > 0 { + h.WriteToken(jsontext.String("server_versions")) + if err := versions(e.ServerVersions).encode(enc); err != nil { + return err + } + } + h.WriteToken(jsontext.String("chosen_version")) + h.WriteToken(jsontext.String(fmt.Sprintf("%x", uint32(e.ChosenVersion)))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +type ConnectionClosed struct { + Initiator Initiator + + ConnectionError *TransportErrorCode + ApplicationError *ApplicationErrorCode + + Reason string + + Trigger ConnectionCloseTrigger +} + +func (e ConnectionClosed) Name() string { return "transport:connection_closed" } + +func (e ConnectionClosed) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("initiator")) + h.WriteToken(jsontext.String(string(e.Initiator))) + if e.ConnectionError != nil { + h.WriteToken(jsontext.String("connection_error")) + if e.ConnectionError.IsCryptoError() { + h.WriteToken(jsontext.String(fmt.Sprintf("crypto_error_%#x", uint16(*e.ConnectionError)))) + } else { + switch *e.ConnectionError { + case qerr.NoError: + h.WriteToken(jsontext.String("no_error")) + case qerr.InternalError: + h.WriteToken(jsontext.String("internal_error")) + case qerr.ConnectionRefused: + h.WriteToken(jsontext.String("connection_refused")) + case qerr.FlowControlError: + h.WriteToken(jsontext.String("flow_control_error")) + case qerr.StreamLimitError: + h.WriteToken(jsontext.String("stream_limit_error")) + case qerr.StreamStateError: + h.WriteToken(jsontext.String("stream_state_error")) + case qerr.FinalSizeError: + h.WriteToken(jsontext.String("final_size_error")) + case qerr.FrameEncodingError: + h.WriteToken(jsontext.String("frame_encoding_error")) + case qerr.TransportParameterError: + h.WriteToken(jsontext.String("transport_parameter_error")) + case qerr.ConnectionIDLimitError: + h.WriteToken(jsontext.String("connection_id_limit_error")) + case qerr.ProtocolViolation: + h.WriteToken(jsontext.String("protocol_violation")) + case qerr.InvalidToken: + h.WriteToken(jsontext.String("invalid_token")) + case qerr.ApplicationErrorErrorCode: + h.WriteToken(jsontext.String("application_error")) + case qerr.CryptoBufferExceeded: + h.WriteToken(jsontext.String("crypto_buffer_exceeded")) + case qerr.KeyUpdateError: + h.WriteToken(jsontext.String("key_update_error")) + case qerr.AEADLimitReached: + h.WriteToken(jsontext.String("aead_limit_reached")) + case qerr.NoViablePathError: + h.WriteToken(jsontext.String("no_viable_path")) + default: + h.WriteToken(jsontext.String("unknown")) + h.WriteToken(jsontext.String("error_code")) + h.WriteToken(jsontext.Uint(uint64(*e.ConnectionError))) + } + } + } + if e.ApplicationError != nil { + h.WriteToken(jsontext.String("application_error")) + h.WriteToken(jsontext.String("unknown")) + h.WriteToken(jsontext.String("error_code")) + h.WriteToken(jsontext.Uint(uint64(*e.ApplicationError))) + } + if e.ConnectionError != nil || e.ApplicationError != nil { + h.WriteToken(jsontext.String("reason")) + h.WriteToken(jsontext.String(e.Reason)) + } + if e.Trigger != "" { + h.WriteToken(jsontext.String("trigger")) + h.WriteToken(jsontext.String(string(e.Trigger))) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type PacketSent struct { + Header PacketHeader + Raw RawInfo + DatagramID DatagramID + Frames []Frame + ECN ECN + IsCoalesced bool + Trigger string + SupportedVersions []Version +} + +func (e PacketSent) Name() string { return "transport:packet_sent" } + +func (e PacketSent) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("header")) + if err := e.Header.encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.String("raw")) + if err := e.Raw.encode(enc); err != nil { + return err + } + if e.DatagramID != 0 { + h.WriteToken(jsontext.String("datagram_id")) + h.WriteToken(jsontext.Uint(uint64(e.DatagramID))) + } + if len(e.Frames) > 0 { + h.WriteToken(jsontext.String("frames")) + if err := frames(e.Frames).encode(enc); err != nil { + return err + } + } + if e.IsCoalesced { + h.WriteToken(jsontext.String("is_coalesced")) + h.WriteToken(jsontext.True) + } + if e.ECN != ECNUnsupported { + h.WriteToken(jsontext.String("ecn")) + h.WriteToken(jsontext.String(string(e.ECN))) + } + if e.Trigger != "" { + h.WriteToken(jsontext.String("trigger")) + h.WriteToken(jsontext.String(e.Trigger)) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type PacketReceived struct { + Header PacketHeader + Raw RawInfo + DatagramID DatagramID + Frames []Frame + ECN ECN + IsCoalesced bool + Trigger string +} + +func (e PacketReceived) Name() string { return "transport:packet_received" } + +func (e PacketReceived) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("header")) + if err := e.Header.encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.String("raw")) + if err := e.Raw.encode(enc); err != nil { + return err + } + if e.DatagramID != 0 { + h.WriteToken(jsontext.String("datagram_id")) + h.WriteToken(jsontext.Uint(uint64(e.DatagramID))) + } + if len(e.Frames) > 0 { + h.WriteToken(jsontext.String("frames")) + if err := frames(e.Frames).encode(enc); err != nil { + return err + } + } + if e.IsCoalesced { + h.WriteToken(jsontext.String("is_coalesced")) + h.WriteToken(jsontext.True) + } + if e.ECN != ECNUnsupported { + h.WriteToken(jsontext.String("ecn")) + h.WriteToken(jsontext.String(string(e.ECN))) + } + if e.Trigger != "" { + h.WriteToken(jsontext.String("trigger")) + h.WriteToken(jsontext.String(e.Trigger)) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type VersionNegotiationReceived struct { + Header PacketHeaderVersionNegotiation + SupportedVersions []Version +} + +func (e VersionNegotiationReceived) Name() string { return "transport:packet_received" } + +func (e VersionNegotiationReceived) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("header")) + if err := e.Header.encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.String("supported_versions")) + if err := versions(e.SupportedVersions).encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type VersionNegotiationSent struct { + Header PacketHeaderVersionNegotiation + SupportedVersions []Version +} + +func (e VersionNegotiationSent) Name() string { return "transport:packet_sent" } + +func (e VersionNegotiationSent) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("header")) + if err := e.Header.encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.String("supported_versions")) + if err := versions(e.SupportedVersions).encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type PacketBuffered struct { + Header PacketHeader + Raw RawInfo + DatagramID DatagramID +} + +func (e PacketBuffered) Name() string { return "transport:packet_buffered" } + +func (e PacketBuffered) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("header")) + if err := e.Header.encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.String("raw")) + if err := e.Raw.encode(enc); err != nil { + return err + } + if e.DatagramID != 0 { + h.WriteToken(jsontext.String("datagram_id")) + h.WriteToken(jsontext.Uint(uint64(e.DatagramID))) + } + h.WriteToken(jsontext.String("trigger")) + h.WriteToken(jsontext.String("keys_unavailable")) + h.WriteToken(jsontext.EndObject) + return h.err +} + +// PacketDropped is the transport:packet_dropped event. +type PacketDropped struct { + Header PacketHeader + Raw RawInfo + DatagramID DatagramID + Trigger PacketDropReason +} + +func (e PacketDropped) Name() string { return "transport:packet_dropped" } + +func (e PacketDropped) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("header")) + if err := e.Header.encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.String("raw")) + if err := e.Raw.encode(enc); err != nil { + return err + } + if e.DatagramID != 0 { + h.WriteToken(jsontext.String("datagram_id")) + h.WriteToken(jsontext.Uint(uint64(e.DatagramID))) + } + h.WriteToken(jsontext.String("trigger")) + h.WriteToken(jsontext.String(string(e.Trigger))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +type MTUUpdated struct { + Value int + Done bool +} + +func (e MTUUpdated) Name() string { return "recovery:mtu_updated" } + +func (e MTUUpdated) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("mtu")) + h.WriteToken(jsontext.Uint(uint64(e.Value))) + h.WriteToken(jsontext.String("done")) + h.WriteToken(jsontext.Bool(e.Done)) + h.WriteToken(jsontext.EndObject) + return h.err +} + +// MetricsUpdated logs RTT and congestion metrics as defined in the +// recovery:metrics_updated event. +// The PTO count is logged via PTOCountUpdated. +type MetricsUpdated struct { + MinRTT time.Duration + SmoothedRTT time.Duration + LatestRTT time.Duration + RTTVariance time.Duration + CongestionWindow int + BytesInFlight int + PacketsInFlight int +} + +func (e MetricsUpdated) Name() string { return "recovery:metrics_updated" } + +func (e MetricsUpdated) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + if e.MinRTT != 0 { + h.WriteToken(jsontext.String("min_rtt")) + h.WriteToken(jsontext.Float(milliseconds(e.MinRTT))) + } + if e.SmoothedRTT != 0 { + h.WriteToken(jsontext.String("smoothed_rtt")) + h.WriteToken(jsontext.Float(milliseconds(e.SmoothedRTT))) + } + if e.LatestRTT != 0 { + h.WriteToken(jsontext.String("latest_rtt")) + h.WriteToken(jsontext.Float(milliseconds(e.LatestRTT))) + } + if e.RTTVariance != 0 { + h.WriteToken(jsontext.String("rtt_variance")) + h.WriteToken(jsontext.Float(milliseconds(e.RTTVariance))) + } + if e.CongestionWindow != 0 { + h.WriteToken(jsontext.String("congestion_window")) + h.WriteToken(jsontext.Uint(uint64(e.CongestionWindow))) + } + if e.BytesInFlight != 0 { + h.WriteToken(jsontext.String("bytes_in_flight")) + h.WriteToken(jsontext.Uint(uint64(e.BytesInFlight))) + } + if e.PacketsInFlight != 0 { + h.WriteToken(jsontext.String("packets_in_flight")) + h.WriteToken(jsontext.Uint(uint64(e.PacketsInFlight))) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +// PTOCountUpdated logs the pto_count value of the +// recovery:metrics_updated event. +type PTOCountUpdated struct { + PTOCount uint32 +} + +func (e PTOCountUpdated) Name() string { return "recovery:metrics_updated" } + +func (e PTOCountUpdated) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("pto_count")) + h.WriteToken(jsontext.Uint(uint64(e.PTOCount))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +type PacketLost struct { + Header PacketHeader + Trigger PacketLossReason +} + +func (e PacketLost) Name() string { return "recovery:packet_lost" } + +func (e PacketLost) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("header")) + if err := e.Header.encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.String("trigger")) + h.WriteToken(jsontext.String(string(e.Trigger))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +type SpuriousLoss struct { + EncryptionLevel protocol.EncryptionLevel + PacketNumber protocol.PacketNumber + PacketReordering uint64 + TimeReordering time.Duration +} + +func (e SpuriousLoss) Name() string { return "recovery:spurious_loss" } + +func (e SpuriousLoss) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("packet_number_space")) + h.WriteToken(jsontext.String(encLevelToPacketNumberSpace(e.EncryptionLevel))) + h.WriteToken(jsontext.String("packet_number")) + h.WriteToken(jsontext.Uint(uint64(e.PacketNumber))) + h.WriteToken(jsontext.String("reordering_packets")) + h.WriteToken(jsontext.Uint(e.PacketReordering)) + h.WriteToken(jsontext.String("reordering_time")) + h.WriteToken(jsontext.Float(milliseconds(e.TimeReordering))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +type KeyUpdated struct { + Trigger KeyUpdateTrigger + KeyType KeyType + KeyPhase KeyPhase // only set for 1-RTT keys + // we don't log the keys here, so we don't need `old` and `new`. +} + +func (e KeyUpdated) Name() string { return "security:key_updated" } + +func (e KeyUpdated) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("trigger")) + h.WriteToken(jsontext.String(string(e.Trigger))) + h.WriteToken(jsontext.String("key_type")) + h.WriteToken(jsontext.String(string(e.KeyType))) + if e.KeyType == KeyTypeClient1RTT || e.KeyType == KeyTypeServer1RTT { + h.WriteToken(jsontext.String("key_phase")) + h.WriteToken(jsontext.Uint(uint64(e.KeyPhase))) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type KeyDiscarded struct { + KeyType KeyType + KeyPhase KeyPhase // only set for 1-RTT keys +} + +func (e KeyDiscarded) Name() string { return "security:key_discarded" } + +func (e KeyDiscarded) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + if e.KeyType != KeyTypeClient1RTT && e.KeyType != KeyTypeServer1RTT { + h.WriteToken(jsontext.String("trigger")) + h.WriteToken(jsontext.String("tls")) + } + h.WriteToken(jsontext.String("key_type")) + h.WriteToken(jsontext.String(string(e.KeyType))) + if e.KeyType == KeyTypeClient1RTT || e.KeyType == KeyTypeServer1RTT { + h.WriteToken(jsontext.String("key_phase")) + h.WriteToken(jsontext.Uint(uint64(e.KeyPhase))) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type ParametersSet struct { + Restore bool + Initiator Initiator + SentBy protocol.Perspective + OriginalDestinationConnectionID protocol.ConnectionID + InitialSourceConnectionID protocol.ConnectionID + RetrySourceConnectionID *protocol.ConnectionID + StatelessResetToken *protocol.StatelessResetToken + DisableActiveMigration bool + MaxIdleTimeout time.Duration + MaxUDPPayloadSize protocol.ByteCount + AckDelayExponent uint8 + MaxAckDelay time.Duration + ActiveConnectionIDLimit uint64 + InitialMaxData protocol.ByteCount + InitialMaxStreamDataBidiLocal protocol.ByteCount + InitialMaxStreamDataBidiRemote protocol.ByteCount + InitialMaxStreamDataUni protocol.ByteCount + InitialMaxStreamsBidi int64 + InitialMaxStreamsUni int64 + PreferredAddress *PreferredAddress + MaxDatagramFrameSize protocol.ByteCount + EnableResetStreamAt bool +} + +func (e ParametersSet) Name() string { + if e.Restore { + return "transport:parameters_restored" + } + return "transport:parameters_set" +} + +func (e ParametersSet) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + if !e.Restore { + h.WriteToken(jsontext.String("initiator")) + h.WriteToken(jsontext.String(string(e.Initiator))) + if e.SentBy == protocol.PerspectiveServer { + h.WriteToken(jsontext.String("original_destination_connection_id")) + h.WriteToken(jsontext.String(e.OriginalDestinationConnectionID.String())) + if e.StatelessResetToken != nil { + h.WriteToken(jsontext.String("stateless_reset_token")) + h.WriteToken(jsontext.String(fmt.Sprintf("%x", e.StatelessResetToken[:]))) + } + if e.RetrySourceConnectionID != nil { + h.WriteToken(jsontext.String("retry_source_connection_id")) + h.WriteToken(jsontext.String((*e.RetrySourceConnectionID).String())) + } + } + h.WriteToken(jsontext.String("initial_source_connection_id")) + h.WriteToken(jsontext.String(e.InitialSourceConnectionID.String())) + } + h.WriteToken(jsontext.String("disable_active_migration")) + h.WriteToken(jsontext.Bool(e.DisableActiveMigration)) + if e.MaxIdleTimeout != 0 { + h.WriteToken(jsontext.String("max_idle_timeout")) + h.WriteToken(jsontext.Float(milliseconds(e.MaxIdleTimeout))) + } + if e.MaxUDPPayloadSize != 0 { + h.WriteToken(jsontext.String("max_udp_payload_size")) + h.WriteToken(jsontext.Int(int64(e.MaxUDPPayloadSize))) + } + if e.AckDelayExponent != 0 { + h.WriteToken(jsontext.String("ack_delay_exponent")) + h.WriteToken(jsontext.Uint(uint64(e.AckDelayExponent))) + } + if e.MaxAckDelay != 0 { + h.WriteToken(jsontext.String("max_ack_delay")) + h.WriteToken(jsontext.Float(milliseconds(e.MaxAckDelay))) + } + if e.ActiveConnectionIDLimit != 0 { + h.WriteToken(jsontext.String("active_connection_id_limit")) + h.WriteToken(jsontext.Uint(e.ActiveConnectionIDLimit)) + } + if e.InitialMaxData != 0 { + h.WriteToken(jsontext.String("initial_max_data")) + h.WriteToken(jsontext.Int(int64(e.InitialMaxData))) + } + if e.InitialMaxStreamDataBidiLocal != 0 { + h.WriteToken(jsontext.String("initial_max_stream_data_bidi_local")) + h.WriteToken(jsontext.Int(int64(e.InitialMaxStreamDataBidiLocal))) + } + if e.InitialMaxStreamDataBidiRemote != 0 { + h.WriteToken(jsontext.String("initial_max_stream_data_bidi_remote")) + h.WriteToken(jsontext.Int(int64(e.InitialMaxStreamDataBidiRemote))) + } + if e.InitialMaxStreamDataUni != 0 { + h.WriteToken(jsontext.String("initial_max_stream_data_uni")) + h.WriteToken(jsontext.Int(int64(e.InitialMaxStreamDataUni))) + } + if e.InitialMaxStreamsBidi != 0 { + h.WriteToken(jsontext.String("initial_max_streams_bidi")) + h.WriteToken(jsontext.Int(e.InitialMaxStreamsBidi)) + } + if e.InitialMaxStreamsUni != 0 { + h.WriteToken(jsontext.String("initial_max_streams_uni")) + h.WriteToken(jsontext.Int(e.InitialMaxStreamsUni)) + } + if e.PreferredAddress != nil { + h.WriteToken(jsontext.String("preferred_address")) + if err := e.PreferredAddress.encode(enc); err != nil { + return err + } + } + if e.MaxDatagramFrameSize != protocol.InvalidByteCount { + h.WriteToken(jsontext.String("max_datagram_frame_size")) + h.WriteToken(jsontext.Int(int64(e.MaxDatagramFrameSize))) + } + if e.EnableResetStreamAt { + h.WriteToken(jsontext.String("reset_stream_at")) + h.WriteToken(jsontext.True) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type PreferredAddress struct { + IPv4, IPv6 netip.AddrPort + ConnectionID protocol.ConnectionID + StatelessResetToken protocol.StatelessResetToken +} + +func (a PreferredAddress) encode(enc *jsontext.Encoder) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + if a.IPv4.IsValid() { + h.WriteToken(jsontext.String("ip_v4")) + h.WriteToken(jsontext.String(a.IPv4.Addr().String())) + h.WriteToken(jsontext.String("port_v4")) + h.WriteToken(jsontext.Uint(uint64(a.IPv4.Port()))) + } + if a.IPv6.IsValid() { + h.WriteToken(jsontext.String("ip_v6")) + h.WriteToken(jsontext.String(a.IPv6.Addr().String())) + h.WriteToken(jsontext.String("port_v6")) + h.WriteToken(jsontext.Uint(uint64(a.IPv6.Port()))) + } + h.WriteToken(jsontext.String("connection_id")) + h.WriteToken(jsontext.String(a.ConnectionID.String())) + h.WriteToken(jsontext.String("stateless_reset_token")) + h.WriteToken(jsontext.String(fmt.Sprintf("%x", a.StatelessResetToken))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +type LossTimerUpdated struct { + Type LossTimerUpdateType + TimerType TimerType + EncLevel EncryptionLevel + Time time.Time +} + +func (e LossTimerUpdated) Name() string { return "recovery:loss_timer_updated" } + +func (e LossTimerUpdated) Encode(enc *jsontext.Encoder, t time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("event_type")) + h.WriteToken(jsontext.String(string(e.Type))) + h.WriteToken(jsontext.String("timer_type")) + h.WriteToken(jsontext.String(string(e.TimerType))) + h.WriteToken(jsontext.String("packet_number_space")) + h.WriteToken(jsontext.String(encLevelToPacketNumberSpace(e.EncLevel))) + if e.Type == LossTimerUpdateTypeSet { + h.WriteToken(jsontext.String("delta")) + h.WriteToken(jsontext.Float(milliseconds(e.Time.Sub(t)))) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type eventLossTimerCanceled struct{} + +func (e eventLossTimerCanceled) Name() string { return "recovery:loss_timer_updated" } + +func (e eventLossTimerCanceled) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("event_type")) + h.WriteToken(jsontext.String("cancelled")) + h.WriteToken(jsontext.EndObject) + return h.err +} + +type CongestionStateUpdated struct { + State CongestionState +} + +func (e CongestionStateUpdated) Name() string { return "recovery:congestion_state_updated" } + +func (e CongestionStateUpdated) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("new")) + h.WriteToken(jsontext.String(e.State.String())) + h.WriteToken(jsontext.EndObject) + return h.err +} + +type ECNStateUpdated struct { + State ECNState + Trigger string +} + +func (e ECNStateUpdated) Name() string { return "recovery:ecn_state_updated" } + +func (e ECNStateUpdated) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("new")) + h.WriteToken(jsontext.String(string(e.State))) + if e.Trigger != "" { + h.WriteToken(jsontext.String("trigger")) + h.WriteToken(jsontext.String(e.Trigger)) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +type ALPNInformation struct { + ChosenALPN string +} + +func (e ALPNInformation) Name() string { return "transport:alpn_information" } + +func (e ALPNInformation) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("chosen_alpn")) + h.WriteToken(jsontext.String(e.ChosenALPN)) + h.WriteToken(jsontext.EndObject) + return h.err +} + +// DebugEvent is a generic event that can be used to log arbitrary messages. +type DebugEvent struct { + EventName string + Message string +} + +func (e DebugEvent) Name() string { + if e.EventName == "" { + return "transport:debug" + } + return fmt.Sprintf("transport:%s", e.EventName) +} + +func (e DebugEvent) Encode(enc *jsontext.Encoder, _ time.Time) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("message")) + h.WriteToken(jsontext.String(e.Message)) + h.WriteToken(jsontext.EndObject) + return h.err +} diff --git a/vendor/github.com/quic-go/quic-go/qlog/frame.go b/vendor/github.com/quic-go/quic-go/qlog/frame.go new file mode 100644 index 00000000..b66fedc9 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/qlog/frame.go @@ -0,0 +1,481 @@ +package qlog + +import ( + "encoding/hex" + + "github.com/quic-go/quic-go/internal/wire" + "github.com/quic-go/quic-go/qlogwriter/jsontext" +) + +type Frame struct { + Frame any +} + +type frames []Frame + +type ( + // An AckFrame is an ACK frame. + AckFrame = wire.AckFrame + // A ConnectionCloseFrame is a CONNECTION_CLOSE frame. + ConnectionCloseFrame = wire.ConnectionCloseFrame + // A DataBlockedFrame is a DATA_BLOCKED frame. + DataBlockedFrame = wire.DataBlockedFrame + // A HandshakeDoneFrame is a HANDSHAKE_DONE frame. + HandshakeDoneFrame = wire.HandshakeDoneFrame + // A MaxDataFrame is a MAX_DATA frame. + MaxDataFrame = wire.MaxDataFrame + // A MaxStreamDataFrame is a MAX_STREAM_DATA frame. + MaxStreamDataFrame = wire.MaxStreamDataFrame + // A MaxStreamsFrame is a MAX_STREAMS_FRAME. + MaxStreamsFrame = wire.MaxStreamsFrame + // A NewConnectionIDFrame is a NEW_CONNECTION_ID frame. + NewConnectionIDFrame = wire.NewConnectionIDFrame + // A NewTokenFrame is a NEW_TOKEN frame. + NewTokenFrame = wire.NewTokenFrame + // A PathChallengeFrame is a PATH_CHALLENGE frame. + PathChallengeFrame = wire.PathChallengeFrame + // A PathResponseFrame is a PATH_RESPONSE frame. + PathResponseFrame = wire.PathResponseFrame + // A PingFrame is a PING frame. + PingFrame = wire.PingFrame + // A ResetStreamFrame is a RESET_STREAM frame. + ResetStreamFrame = wire.ResetStreamFrame + // A RetireConnectionIDFrame is a RETIRE_CONNECTION_ID frame. + RetireConnectionIDFrame = wire.RetireConnectionIDFrame + // A StopSendingFrame is a STOP_SENDING frame. + StopSendingFrame = wire.StopSendingFrame + // A StreamsBlockedFrame is a STREAMS_BLOCKED frame. + StreamsBlockedFrame = wire.StreamsBlockedFrame + // A StreamDataBlockedFrame is a STREAM_DATA_BLOCKED frame. + StreamDataBlockedFrame = wire.StreamDataBlockedFrame + // An AckFrequencyFrame is an ACK_FREQUENCY frame. + AckFrequencyFrame = wire.AckFrequencyFrame + // An ImmediateAckFrame is an IMMEDIATE_ACK frame. + ImmediateAckFrame = wire.ImmediateAckFrame +) + +type AckRange = wire.AckRange + +// A CryptoFrame is a CRYPTO frame. +type CryptoFrame struct { + Offset int64 + Length int64 +} + +// A StreamFrame is a STREAM frame. +type StreamFrame struct { + StreamID StreamID + Offset int64 + Length int64 + Fin bool +} + +// A DatagramFrame is a DATAGRAM frame. +type DatagramFrame struct { + Length int64 +} + +func (fs frames) encode(enc *jsontext.Encoder) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginArray) + for _, f := range fs { + if err := f.Encode(enc); err != nil { + return err + } + } + h.WriteToken(jsontext.EndArray) + return h.err +} + +func (f Frame) Encode(enc *jsontext.Encoder) error { + switch frame := f.Frame.(type) { + case *PingFrame: + return encodePingFrame(enc, frame) + case *AckFrame: + return encodeAckFrame(enc, frame) + case *ResetStreamFrame: + return encodeResetStreamFrame(enc, frame) + case *StopSendingFrame: + return encodeStopSendingFrame(enc, frame) + case *CryptoFrame: + return encodeCryptoFrame(enc, frame) + case *NewTokenFrame: + return encodeNewTokenFrame(enc, frame) + case *StreamFrame: + return encodeStreamFrame(enc, frame) + case *MaxDataFrame: + return encodeMaxDataFrame(enc, frame) + case *MaxStreamDataFrame: + return encodeMaxStreamDataFrame(enc, frame) + case *MaxStreamsFrame: + return encodeMaxStreamsFrame(enc, frame) + case *DataBlockedFrame: + return encodeDataBlockedFrame(enc, frame) + case *StreamDataBlockedFrame: + return encodeStreamDataBlockedFrame(enc, frame) + case *StreamsBlockedFrame: + return encodeStreamsBlockedFrame(enc, frame) + case *NewConnectionIDFrame: + return encodeNewConnectionIDFrame(enc, frame) + case *RetireConnectionIDFrame: + return encodeRetireConnectionIDFrame(enc, frame) + case *PathChallengeFrame: + return encodePathChallengeFrame(enc, frame) + case *PathResponseFrame: + return encodePathResponseFrame(enc, frame) + case *ConnectionCloseFrame: + return encodeConnectionCloseFrame(enc, frame) + case *HandshakeDoneFrame: + return encodeHandshakeDoneFrame(enc, frame) + case *DatagramFrame: + return encodeDatagramFrame(enc, frame) + case *AckFrequencyFrame: + return encodeAckFrequencyFrame(enc, frame) + case *ImmediateAckFrame: + return encodeImmediateAckFrame(enc, frame) + default: + panic("unknown frame type") + } +} + +func encodePingFrame(enc *jsontext.Encoder, _ *PingFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("ping")) + h.WriteToken(jsontext.EndObject) + return h.err +} + +type ackRanges []wire.AckRange + +func (ars ackRanges) encode(enc *jsontext.Encoder) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginArray) + for _, r := range ars { + if err := ackRange(r).encode(enc); err != nil { + return err + } + } + h.WriteToken(jsontext.EndArray) + return h.err +} + +type ackRange wire.AckRange + +func (ar ackRange) encode(enc *jsontext.Encoder) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginArray) + h.WriteToken(jsontext.Int(int64(ar.Smallest))) + if ar.Smallest != ar.Largest { + h.WriteToken(jsontext.Int(int64(ar.Largest))) + } + h.WriteToken(jsontext.EndArray) + return h.err +} + +func encodeAckFrame(enc *jsontext.Encoder, f *AckFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("ack")) + if f.DelayTime > 0 { + h.WriteToken(jsontext.String("ack_delay")) + h.WriteToken(jsontext.Float(milliseconds(f.DelayTime))) + } + h.WriteToken(jsontext.String("acked_ranges")) + if err := ackRanges(f.AckRanges).encode(enc); err != nil { + return err + } + hasECN := f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0 + if hasECN { + h.WriteToken(jsontext.String("ect0")) + h.WriteToken(jsontext.Uint(f.ECT0)) + h.WriteToken(jsontext.String("ect1")) + h.WriteToken(jsontext.Uint(f.ECT1)) + h.WriteToken(jsontext.String("ce")) + h.WriteToken(jsontext.Uint(f.ECNCE)) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeResetStreamFrame(enc *jsontext.Encoder, f *ResetStreamFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + if f.ReliableSize > 0 { + h.WriteToken(jsontext.String("reset_stream_at")) + } else { + h.WriteToken(jsontext.String("reset_stream")) + } + h.WriteToken(jsontext.String("stream_id")) + h.WriteToken(jsontext.Int(int64(f.StreamID))) + h.WriteToken(jsontext.String("error_code")) + h.WriteToken(jsontext.Int(int64(f.ErrorCode))) + h.WriteToken(jsontext.String("final_size")) + h.WriteToken(jsontext.Int(int64(f.FinalSize))) + if f.ReliableSize > 0 { + h.WriteToken(jsontext.String("reliable_size")) + h.WriteToken(jsontext.Int(int64(f.ReliableSize))) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeStopSendingFrame(enc *jsontext.Encoder, f *StopSendingFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("stop_sending")) + h.WriteToken(jsontext.String("stream_id")) + h.WriteToken(jsontext.Int(int64(f.StreamID))) + h.WriteToken(jsontext.String("error_code")) + h.WriteToken(jsontext.Int(int64(f.ErrorCode))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeCryptoFrame(enc *jsontext.Encoder, f *CryptoFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("crypto")) + h.WriteToken(jsontext.String("offset")) + h.WriteToken(jsontext.Int(f.Offset)) + h.WriteToken(jsontext.String("length")) + h.WriteToken(jsontext.Int(f.Length)) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeNewTokenFrame(enc *jsontext.Encoder, f *NewTokenFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("new_token")) + h.WriteToken(jsontext.String("token")) + if err := (Token{Raw: f.Token}).encode(enc); err != nil { + return err + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeStreamFrame(enc *jsontext.Encoder, f *StreamFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("stream")) + h.WriteToken(jsontext.String("stream_id")) + h.WriteToken(jsontext.Int(int64(f.StreamID))) + h.WriteToken(jsontext.String("offset")) + h.WriteToken(jsontext.Int(f.Offset)) + h.WriteToken(jsontext.String("length")) + h.WriteToken(jsontext.Int(f.Length)) + if f.Fin { + h.WriteToken(jsontext.String("fin")) + h.WriteToken(jsontext.True) + } + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeMaxDataFrame(enc *jsontext.Encoder, f *MaxDataFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("max_data")) + h.WriteToken(jsontext.String("maximum")) + h.WriteToken(jsontext.Int(int64(f.MaximumData))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeMaxStreamDataFrame(enc *jsontext.Encoder, f *MaxStreamDataFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("max_stream_data")) + h.WriteToken(jsontext.String("stream_id")) + h.WriteToken(jsontext.Int(int64(f.StreamID))) + h.WriteToken(jsontext.String("maximum")) + h.WriteToken(jsontext.Int(int64(f.MaximumStreamData))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeMaxStreamsFrame(enc *jsontext.Encoder, f *MaxStreamsFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("max_streams")) + h.WriteToken(jsontext.String("stream_type")) + h.WriteToken(jsontext.String(streamType(f.Type).String())) + h.WriteToken(jsontext.String("maximum")) + h.WriteToken(jsontext.Int(int64(f.MaxStreamNum))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeDataBlockedFrame(enc *jsontext.Encoder, f *DataBlockedFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("data_blocked")) + h.WriteToken(jsontext.String("limit")) + h.WriteToken(jsontext.Int(int64(f.MaximumData))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeStreamDataBlockedFrame(enc *jsontext.Encoder, f *StreamDataBlockedFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("stream_data_blocked")) + h.WriteToken(jsontext.String("stream_id")) + h.WriteToken(jsontext.Int(int64(f.StreamID))) + h.WriteToken(jsontext.String("limit")) + h.WriteToken(jsontext.Int(int64(f.MaximumStreamData))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeStreamsBlockedFrame(enc *jsontext.Encoder, f *StreamsBlockedFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("streams_blocked")) + h.WriteToken(jsontext.String("stream_type")) + h.WriteToken(jsontext.String(streamType(f.Type).String())) + h.WriteToken(jsontext.String("limit")) + h.WriteToken(jsontext.Int(int64(f.StreamLimit))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeNewConnectionIDFrame(enc *jsontext.Encoder, f *NewConnectionIDFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("new_connection_id")) + h.WriteToken(jsontext.String("sequence_number")) + h.WriteToken(jsontext.Uint(f.SequenceNumber)) + h.WriteToken(jsontext.String("retire_prior_to")) + h.WriteToken(jsontext.Uint(f.RetirePriorTo)) + h.WriteToken(jsontext.String("length")) + h.WriteToken(jsontext.Int(int64(f.ConnectionID.Len()))) + h.WriteToken(jsontext.String("connection_id")) + h.WriteToken(jsontext.String(f.ConnectionID.String())) + h.WriteToken(jsontext.String("stateless_reset_token")) + h.WriteToken(jsontext.String(hex.EncodeToString(f.StatelessResetToken[:]))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeRetireConnectionIDFrame(enc *jsontext.Encoder, f *RetireConnectionIDFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("retire_connection_id")) + h.WriteToken(jsontext.String("sequence_number")) + h.WriteToken(jsontext.Uint(f.SequenceNumber)) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodePathChallengeFrame(enc *jsontext.Encoder, f *PathChallengeFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("path_challenge")) + h.WriteToken(jsontext.String("data")) + h.WriteToken(jsontext.String(hex.EncodeToString(f.Data[:]))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodePathResponseFrame(enc *jsontext.Encoder, f *PathResponseFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("path_response")) + h.WriteToken(jsontext.String("data")) + h.WriteToken(jsontext.String(hex.EncodeToString(f.Data[:]))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeConnectionCloseFrame(enc *jsontext.Encoder, f *ConnectionCloseFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("connection_close")) + h.WriteToken(jsontext.String("error_space")) + errorSpace := "transport" + if f.IsApplicationError { + errorSpace = "application" + } + h.WriteToken(jsontext.String(errorSpace)) + errName := transportError(f.ErrorCode).String() + if len(errName) > 0 { + h.WriteToken(jsontext.String("error_code")) + h.WriteToken(jsontext.String(errName)) + } else { + h.WriteToken(jsontext.String("error_code")) + h.WriteToken(jsontext.Uint(f.ErrorCode)) + } + h.WriteToken(jsontext.String("raw_error_code")) + h.WriteToken(jsontext.Uint(f.ErrorCode)) + h.WriteToken(jsontext.String("reason")) + h.WriteToken(jsontext.String(f.ReasonPhrase)) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeHandshakeDoneFrame(enc *jsontext.Encoder, _ *HandshakeDoneFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("handshake_done")) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeDatagramFrame(enc *jsontext.Encoder, f *DatagramFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("datagram")) + h.WriteToken(jsontext.String("length")) + h.WriteToken(jsontext.Int(f.Length)) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeAckFrequencyFrame(enc *jsontext.Encoder, f *AckFrequencyFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("ack_frequency")) + h.WriteToken(jsontext.String("sequence_number")) + h.WriteToken(jsontext.Uint(f.SequenceNumber)) + h.WriteToken(jsontext.String("ack_eliciting_threshold")) + h.WriteToken(jsontext.Uint(f.AckElicitingThreshold)) + h.WriteToken(jsontext.String("request_max_ack_delay")) + h.WriteToken(jsontext.Float(milliseconds(f.RequestMaxAckDelay))) + h.WriteToken(jsontext.String("reordering_threshold")) + h.WriteToken(jsontext.Int(int64(f.ReorderingThreshold))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +func encodeImmediateAckFrame(enc *jsontext.Encoder, _ *ImmediateAckFrame) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("frame_type")) + h.WriteToken(jsontext.String("immediate_ack")) + h.WriteToken(jsontext.EndObject) + return h.err +} diff --git a/vendor/github.com/quic-go/quic-go/qlog/packet_header.go b/vendor/github.com/quic-go/quic-go/qlog/packet_header.go new file mode 100644 index 00000000..149ebcb6 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/qlog/packet_header.go @@ -0,0 +1,96 @@ +package qlog + +import ( + "encoding/hex" + + "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/qlogwriter/jsontext" +) + +type Token struct { + Raw []byte +} + +func (t Token) encode(enc *jsontext.Encoder) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("data")) + h.WriteToken(jsontext.String(hex.EncodeToString(t.Raw))) + h.WriteToken(jsontext.EndObject) + return h.err +} + +// PacketHeader is a QUIC packet header. +type PacketHeader struct { + PacketType PacketType + KeyPhaseBit KeyPhaseBit + PacketNumber PacketNumber + Version Version + SrcConnectionID ConnectionID + DestConnectionID ConnectionID + Token *Token +} + +func (h PacketHeader) encode(enc *jsontext.Encoder) error { + helper := encoderHelper{enc: enc} + helper.WriteToken(jsontext.BeginObject) + helper.WriteToken(jsontext.String("packet_type")) + helper.WriteToken(jsontext.String(string(h.PacketType))) + if h.PacketType != PacketTypeRetry && h.PacketType != PacketTypeVersionNegotiation && h.PacketType != "" && + h.PacketNumber != protocol.InvalidPacketNumber { + helper.WriteToken(jsontext.String("packet_number")) + helper.WriteToken(jsontext.Int(int64(h.PacketNumber))) + } + if h.Version != 0 { + helper.WriteToken(jsontext.String("version")) + helper.WriteToken(jsontext.String(version(h.Version).String())) + } + if h.PacketType != PacketType1RTT { + helper.WriteToken(jsontext.String("scil")) + helper.WriteToken(jsontext.Int(int64(h.SrcConnectionID.Len()))) + if h.SrcConnectionID.Len() > 0 { + helper.WriteToken(jsontext.String("scid")) + helper.WriteToken(jsontext.String(h.SrcConnectionID.String())) + } + } + helper.WriteToken(jsontext.String("dcil")) + helper.WriteToken(jsontext.Int(int64(h.DestConnectionID.Len()))) + if h.DestConnectionID.Len() > 0 { + helper.WriteToken(jsontext.String("dcid")) + helper.WriteToken(jsontext.String(h.DestConnectionID.String())) + } + if h.KeyPhaseBit == KeyPhaseZero || h.KeyPhaseBit == KeyPhaseOne { + helper.WriteToken(jsontext.String("key_phase_bit")) + helper.WriteToken(jsontext.String(h.KeyPhaseBit.String())) + } + if h.Token != nil { + helper.WriteToken(jsontext.String("token")) + if err := h.Token.encode(enc); err != nil { + return err + } + } + helper.WriteToken(jsontext.EndObject) + return helper.err +} + +type PacketHeaderVersionNegotiation struct { + SrcConnectionID ArbitraryLenConnectionID + DestConnectionID ArbitraryLenConnectionID +} + +func (h PacketHeaderVersionNegotiation) encode(enc *jsontext.Encoder) error { + helper := encoderHelper{enc: enc} + helper.WriteToken(jsontext.BeginObject) + helper.WriteToken(jsontext.String("packet_type")) + helper.WriteToken(jsontext.String("version_negotiation")) + helper.WriteToken(jsontext.String("scil")) + helper.WriteToken(jsontext.Int(int64(h.SrcConnectionID.Len()))) + helper.WriteToken(jsontext.String("scid")) + helper.WriteToken(jsontext.String(h.SrcConnectionID.String())) + helper.WriteToken(jsontext.String("dcil")) + helper.WriteToken(jsontext.Int(int64(h.DestConnectionID.Len()))) + helper.WriteToken(jsontext.String("dcid")) + helper.WriteToken(jsontext.String(h.DestConnectionID.String())) + helper.WriteToken(jsontext.EndObject) + return helper.err +} diff --git a/vendor/github.com/quic-go/quic-go/qlog/qlog_dir.go b/vendor/github.com/quic-go/quic-go/qlog/qlog_dir.go new file mode 100644 index 00000000..83bb72b3 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/qlog/qlog_dir.go @@ -0,0 +1,61 @@ +package qlog + +import ( + "bufio" + "context" + "fmt" + "log" + "os" + "slices" + "strings" + + "github.com/quic-go/quic-go/internal/utils" + "github.com/quic-go/quic-go/qlogwriter" +) + +// EventSchema is the qlog event schema for QUIC +const EventSchema = "urn:ietf:params:qlog:events:quic-12" + +// DefaultConnectionTracer creates a qlog file in the qlog directory specified by the QLOGDIR environment variable. +// File names are _.sqlog. +// Returns nil if QLOGDIR is not set. +func DefaultConnectionTracer(_ context.Context, isClient bool, connID ConnectionID) qlogwriter.Trace { + return defaultConnectionTracerWithSchemas(isClient, connID, []string{EventSchema}) +} + +func DefaultConnectionTracerWithSchemas(_ context.Context, isClient bool, connID ConnectionID, eventSchemas []string) qlogwriter.Trace { + if !slices.Contains(eventSchemas, EventSchema) { + eventSchemas = append([]string{EventSchema}, eventSchemas...) + } + return defaultConnectionTracerWithSchemas(isClient, connID, eventSchemas) +} + +func defaultConnectionTracerWithSchemas(isClient bool, connID ConnectionID, eventSchemas []string) qlogwriter.Trace { + qlogDir := os.Getenv("QLOGDIR") + if qlogDir == "" { + return nil + } + if _, err := os.Stat(qlogDir); os.IsNotExist(err) { + if err := os.MkdirAll(qlogDir, 0o755); err != nil { + log.Fatalf("failed to create qlog dir %s: %v", qlogDir, err) + } + } + label := "server" + if isClient { + label = "client" + } + path := fmt.Sprintf("%s/%s_%s.sqlog", strings.TrimRight(qlogDir, "/"), connID, label) + f, err := os.Create(path) + if err != nil { + log.Printf("Failed to create qlog file %s: %s", path, err.Error()) + return nil + } + fileSeq := qlogwriter.NewConnectionFileSeq( + utils.NewBufferedWriteCloser(bufio.NewWriter(f), f), + isClient, + connID, + eventSchemas, + ) + go fileSeq.Run() + return fileSeq +} diff --git a/vendor/github.com/quic-go/quic-go/qlog/types.go b/vendor/github.com/quic-go/quic-go/qlog/types.go new file mode 100644 index 00000000..dfa4066d --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/qlog/types.go @@ -0,0 +1,304 @@ +package qlog + +import ( + "fmt" + "hash/crc32" + + "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/internal/qerr" +) + +type ( + ConnectionID = protocol.ConnectionID + ArbitraryLenConnectionID = protocol.ArbitraryLenConnectionID + Version = protocol.Version + PacketNumber = protocol.PacketNumber + EncryptionLevel = protocol.EncryptionLevel + KeyPhaseBit = protocol.KeyPhaseBit + KeyPhase = protocol.KeyPhase + StreamID = protocol.StreamID + TransportErrorCode = qerr.TransportErrorCode + ApplicationErrorCode = qerr.ApplicationErrorCode +) + +const ( + // KeyPhaseZero is key phase bit 0 + KeyPhaseZero = protocol.KeyPhaseZero + // KeyPhaseOne is key phase bit 1 + KeyPhaseOne = protocol.KeyPhaseOne +) + +// ECN represents the Explicit Congestion Notification value. +type ECN string + +const ( + // ECNUnsupported means that no ECN value was set / received + ECNUnsupported ECN = "" + // ECTNot is Not-ECT + ECTNot ECN = "Not-ECT" + // ECT0 is ECT(0) + ECT0 ECN = "ECT(0)" + // ECT1 is ECT(1) + ECT1 ECN = "ECT(1)" + // ECNCE is CE + ECNCE ECN = "CE" +) + +type Initiator string + +const ( + InitiatorLocal Initiator = "local" + InitiatorRemote Initiator = "remote" +) + +type streamType protocol.StreamType + +func (s streamType) String() string { + switch protocol.StreamType(s) { + case protocol.StreamTypeUni: + return "unidirectional" + case protocol.StreamTypeBidi: + return "bidirectional" + default: + return "unknown stream type" + } +} + +type version protocol.Version + +func (v version) String() string { + return fmt.Sprintf("%x", uint32(v)) +} + +func encLevelToPacketNumberSpace(encLevel protocol.EncryptionLevel) string { + switch encLevel { + case protocol.EncryptionInitial: + return "initial" + case protocol.EncryptionHandshake: + return "handshake" + case protocol.Encryption0RTT, protocol.Encryption1RTT: + return "application_data" + default: + return "unknown encryption level" + } +} + +// KeyType represents the type of cryptographic key used in QUIC connections. +type KeyType string + +const ( + // KeyTypeServerInitial represents the server's initial secret key. + KeyTypeServerInitial KeyType = "server_initial_secret" + // KeyTypeClientInitial represents the client's initial secret key. + KeyTypeClientInitial KeyType = "client_initial_secret" + // KeyTypeServerHandshake represents the server's handshake secret key. + KeyTypeServerHandshake KeyType = "server_handshake_secret" + // KeyTypeClientHandshake represents the client's handshake secret key. + KeyTypeClientHandshake KeyType = "client_handshake_secret" + // KeyTypeServer0RTT represents the server's 0-RTT secret key. + KeyTypeServer0RTT KeyType = "server_0rtt_secret" + // KeyTypeClient0RTT represents the client's 0-RTT secret key. + KeyTypeClient0RTT KeyType = "client_0rtt_secret" + // KeyTypeServer1RTT represents the server's 1-RTT secret key. + KeyTypeServer1RTT KeyType = "server_1rtt_secret" + // KeyTypeClient1RTT represents the client's 1-RTT secret key. + KeyTypeClient1RTT KeyType = "client_1rtt_secret" +) + +// KeyUpdateTrigger describes what caused a key update event. +type KeyUpdateTrigger string + +const ( + // KeyUpdateTLS indicates the key update was triggered by TLS. + KeyUpdateTLS KeyUpdateTrigger = "tls" + // KeyUpdateRemote indicates the key update was triggered by the remote peer. + KeyUpdateRemote KeyUpdateTrigger = "remote_update" + // KeyUpdateLocal indicates the key update was triggered locally. + KeyUpdateLocal KeyUpdateTrigger = "local_update" +) + +type transportError uint64 + +func (e transportError) String() string { + switch qerr.TransportErrorCode(e) { + case qerr.NoError: + return "no_error" + case qerr.InternalError: + return "internal_error" + case qerr.ConnectionRefused: + return "connection_refused" + case qerr.FlowControlError: + return "flow_control_error" + case qerr.StreamLimitError: + return "stream_limit_error" + case qerr.StreamStateError: + return "stream_state_error" + case qerr.FinalSizeError: + return "final_size_error" + case qerr.FrameEncodingError: + return "frame_encoding_error" + case qerr.TransportParameterError: + return "transport_parameter_error" + case qerr.ConnectionIDLimitError: + return "connection_id_limit_error" + case qerr.ProtocolViolation: + return "protocol_violation" + case qerr.InvalidToken: + return "invalid_token" + case qerr.ApplicationErrorErrorCode: + return "application_error" + case qerr.CryptoBufferExceeded: + return "crypto_buffer_exceeded" + case qerr.KeyUpdateError: + return "key_update_error" + case qerr.AEADLimitReached: + return "aead_limit_reached" + case qerr.NoViablePathError: + return "no_viable_path" + default: + return "" + } +} + +type PacketType string + +const ( + // PacketTypeInitial represents an Initial packet + PacketTypeInitial PacketType = "initial" + // PacketTypeHandshake represents a Handshake packet + PacketTypeHandshake PacketType = "handshake" + // PacketTypeRetry represents a Retry packet + PacketTypeRetry PacketType = "retry" + // PacketType0RTT represents a 0-RTT packet + PacketType0RTT PacketType = "0RTT" + // PacketTypeVersionNegotiation represents a Version Negotiation packet + PacketTypeVersionNegotiation PacketType = "version_negotiation" + // PacketTypeStatelessReset represents a Stateless Reset packet + PacketTypeStatelessReset PacketType = "stateless_reset" + // PacketType1RTT represents a 1-RTT packet + PacketType1RTT PacketType = "1RTT" + // // PacketTypeNotDetermined represents a packet type that could not be determined + // PacketTypeNotDetermined packetType = "" +) + +func EncryptionLevelToPacketType(l EncryptionLevel) PacketType { + switch l { + case protocol.EncryptionInitial: + return PacketTypeInitial + case protocol.EncryptionHandshake: + return PacketTypeHandshake + case protocol.Encryption0RTT: + return PacketType0RTT + case protocol.Encryption1RTT: + return PacketType1RTT + default: + panic(fmt.Sprintf("unknown encryption level: %d", l)) + } +} + +type PacketLossReason string + +const ( + // PacketLossReorderingThreshold is used when a packet is declared lost due to reordering threshold + PacketLossReorderingThreshold PacketLossReason = "reordering_threshold" + // PacketLossTimeThreshold is used when a packet is declared lost due to time threshold + PacketLossTimeThreshold PacketLossReason = "time_threshold" +) + +type PacketDropReason string + +const ( + // PacketDropKeyUnavailable is used when a packet is dropped because keys are unavailable + PacketDropKeyUnavailable PacketDropReason = "key_unavailable" + // PacketDropUnknownConnectionID is used when a packet is dropped because the connection ID is unknown + PacketDropUnknownConnectionID PacketDropReason = "unknown_connection_id" + // PacketDropHeaderParseError is used when a packet is dropped because header parsing failed + PacketDropHeaderParseError PacketDropReason = "header_parse_error" + // PacketDropPayloadDecryptError is used when a packet is dropped because decrypting the payload failed + PacketDropPayloadDecryptError PacketDropReason = "payload_decrypt_error" + // PacketDropProtocolViolation is used when a packet is dropped due to a protocol violation + PacketDropProtocolViolation PacketDropReason = "protocol_violation" + // PacketDropDOSPrevention is used when a packet is dropped to mitigate a DoS attack + PacketDropDOSPrevention PacketDropReason = "dos_prevention" + // PacketDropUnsupportedVersion is used when a packet is dropped because the version is not supported + PacketDropUnsupportedVersion PacketDropReason = "unsupported_version" + // PacketDropUnexpectedPacket is used when an unexpected packet is received + PacketDropUnexpectedPacket PacketDropReason = "unexpected_packet" + // PacketDropUnexpectedSourceConnectionID is used when a packet with an unexpected source connection ID is received + PacketDropUnexpectedSourceConnectionID PacketDropReason = "unexpected_source_connection_id" + // PacketDropUnexpectedVersion is used when a packet with an unexpected version is received + PacketDropUnexpectedVersion PacketDropReason = "unexpected_version" + // PacketDropDuplicate is used when a duplicate packet is received + PacketDropDuplicate PacketDropReason = "duplicate" +) + +type LossTimerUpdateType string + +const ( + LossTimerUpdateTypeSet LossTimerUpdateType = "set" + LossTimerUpdateTypeExpired LossTimerUpdateType = "expired" + LossTimerUpdateTypeCancelled LossTimerUpdateType = "cancelled" +) + +type TimerType string + +const ( + // TimerTypeACK represents an ACK timer + TimerTypeACK TimerType = "ack" + // TimerTypePTO represents a PTO (Probe Timeout) timer + TimerTypePTO TimerType = "pto" + // TimerTypePathProbe represents a path probe timer + TimerTypePathProbe TimerType = "path_probe" +) + +type CongestionState string + +const ( + // CongestionStateSlowStart is the slow start phase of Reno / Cubic + CongestionStateSlowStart CongestionState = "slow_start" + // CongestionStateCongestionAvoidance is the congestion avoidance phase of Reno / Cubic + CongestionStateCongestionAvoidance CongestionState = "congestion_avoidance" + // CongestionStateRecovery is the recovery phase of Reno / Cubic + CongestionStateRecovery CongestionState = "recovery" + // CongestionStateApplicationLimited means that the congestion controller is application limited + CongestionStateApplicationLimited CongestionState = "application_limited" +) + +func (s CongestionState) String() string { + return string(s) +} + +// ECNState is the state of the ECN state machine (see Appendix A.4 of RFC 9000) +type ECNState string + +const ( + // ECNStateTesting is the testing state + ECNStateTesting ECNState = "testing" + // ECNStateUnknown is the unknown state + ECNStateUnknown ECNState = "unknown" + // ECNStateFailed is the failed state + ECNStateFailed ECNState = "failed" + // ECNStateCapable is the capable state + ECNStateCapable ECNState = "capable" +) + +type ConnectionCloseTrigger string + +const ( + // IdleTimeout indicates the connection was closed due to idle timeout + ConnectionCloseTriggerIdleTimeout ConnectionCloseTrigger = "idle_timeout" + // Application indicates the connection was closed by the application + ConnectionCloseTriggerApplication ConnectionCloseTrigger = "application" + // VersionMismatch indicates the connection was closed due to a QUIC version mismatch + ConnectionCloseTriggerVersionMismatch ConnectionCloseTrigger = "version_mismatch" + // StatelessReset indicates the connection was closed due to receiving a stateless reset from the peer + ConnectionCloseTriggerStatelessReset ConnectionCloseTrigger = "stateless_reset" +) + +// DatagramID is a unique identifier for a datagram +type DatagramID uint32 + +// CalculateDatagramID computes a DatagramID for a given packet +func CalculateDatagramID(packet []byte) DatagramID { + return DatagramID(crc32.ChecksumIEEE(packet)) +} diff --git a/vendor/github.com/quic-go/quic-go/qlogwriter/jsontext/encoder.go b/vendor/github.com/quic-go/quic-go/qlogwriter/jsontext/encoder.go new file mode 100644 index 00000000..4f715bbd --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/qlogwriter/jsontext/encoder.go @@ -0,0 +1,324 @@ +// Package jsontext provides a fast JSON encoder providing only the necessary features +// for qlog encoding. No efforts are made to add any features beyond qlog's requirements. +// +// The API aims to be compatible with the standard library's encoding/json/jsontext package. +package jsontext + +import ( + "fmt" + "io" + "strconv" + "unsafe" +) + +type kind uint8 + +const ( + kindString kind = iota + kindInt + kindUint + kindFloat + kindBool + kindNull + kindObjectStart + kindObjectEnd + kindArrayStart + kindArrayEnd +) + +// Token represents a JSON token. +type Token struct { + kind kind + str string + i64 int64 + u64 uint64 + f64 float64 + b bool +} + +// String creates a string token. +func String(s string) Token { + return Token{kind: kindString, str: s} +} + +// Int creates an int token. +func Int(i int64) Token { + return Token{kind: kindInt, i64: i} +} + +// Uint creates a uint token. +func Uint(u uint64) Token { + return Token{kind: kindUint, u64: u} +} + +// Float creates a float token. +func Float(f float64) Token { + return Token{kind: kindFloat, f64: f} +} + +// Bool creates a bool token. +func Bool(b bool) Token { + return Token{kind: kindBool, b: b} +} + +// Null is a null token. +var Null Token = Token{kind: kindNull} + +// BeginObject is the begin object token. +var BeginObject Token = Token{kind: kindObjectStart} + +// EndObject is the end object token. +var EndObject Token = Token{kind: kindObjectEnd} + +// BeginArray is the begin array token. +var BeginArray Token = Token{kind: kindArrayStart} + +// EndArray is the end array token. +var EndArray Token = Token{kind: kindArrayEnd} + +// True is a true token. +var True Token = Bool(true) + +// False is a false token. +var False Token = Bool(false) + +var hexDigits = [16]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'} + +var ( + commaByte = []byte(",") + quoteByte = []byte(`"`) + colonByte = []byte(":") + trueByte = []byte("true") + falseByte = []byte("false") + nullByte = []byte("null") + openObjectByte = []byte("{") + closeObjectByte = []byte("}") + openArrayByte = []byte("[") + closeArrayByte = []byte("]") + newlineByte = []byte("\n") + escapeQuote = []byte(`\"`) + escapeBackslash = []byte(`\\`) + escapeBackspace = []byte(`\b`) + escapeFormfeed = []byte(`\f`) + escapeNewline = []byte(`\n`) + escapeCarriage = []byte(`\r`) + escapeTab = []byte(`\t`) + escapeUnicode = []byte(`\u00`) +) + +type context struct { + isObject bool + needsComma bool + expectKey bool +} + +// Encoder encodes JSON to an io.Writer. +type Encoder struct { + w io.Writer + buf [64]byte // scratch buffer for number formatting + stack []context +} + +// NewEncoder creates a new Encoder. +func NewEncoder(w io.Writer) *Encoder { + stack := make([]context, 0, 8) + stack = append(stack, context{isObject: false, needsComma: false, expectKey: false}) + return &Encoder{ + w: w, + stack: stack, + } +} + +// WriteToken writes a token to the encoder. +func (e *Encoder) WriteToken(t Token) error { + if len(e.stack) == 0 { + return fmt.Errorf("empty stack") + } + curr := &e.stack[len(e.stack)-1] + isClosing := t.kind == kindObjectEnd || t.kind == kindArrayEnd + if !isClosing && curr.needsComma { + if _, err := e.w.Write(commaByte); err != nil { + return err + } + curr.needsComma = false + } + var err error + switch t.kind { + case kindString: + data := stringToBytes(t.str) + needsEscape := false + for _, b := range data { + if b == '"' || b == '\\' || b < 0x20 { + needsEscape = true + break + } + } + if !needsEscape { + if _, err = e.w.Write(quoteByte); err != nil { + return err + } + if _, err = e.w.Write(data); err != nil { + return err + } + if _, err = e.w.Write(quoteByte); err != nil { + return err + } + } else { + if _, err = e.w.Write(quoteByte); err != nil { + return err + } + for i := 0; i < len(t.str); i++ { + c := t.str[i] + switch c { + case '"': + if _, err = e.w.Write(escapeQuote); err != nil { + return err + } + case '\\': + if _, err = e.w.Write(escapeBackslash); err != nil { + return err + } + case '\b': + if _, err = e.w.Write(escapeBackspace); err != nil { + return err + } + case '\f': + if _, err = e.w.Write(escapeFormfeed); err != nil { + return err + } + case '\n': + if _, err = e.w.Write(escapeNewline); err != nil { + return err + } + case '\r': + if _, err = e.w.Write(escapeCarriage); err != nil { + return err + } + case '\t': + if _, err = e.w.Write(escapeTab); err != nil { + return err + } + default: + if c < 0x20 { + if _, err = e.w.Write(escapeUnicode); err != nil { + return err + } + if _, err = e.w.Write([]byte{hexDigits[c>>4], hexDigits[c&0xf]}); err != nil { + return err + } + } else { + if _, err = e.w.Write([]byte{c}); err != nil { + return err + } + } + } + } + if _, err = e.w.Write(quoteByte); err != nil { + return err + } + } + if curr.isObject { + if curr.expectKey { + // key + if _, err = e.w.Write(colonByte); err != nil { + return err + } + curr.expectKey = false + return nil // do not call afterValue for keys + } else { + // value + e.afterValue() + } + } else { + e.afterValue() + } + case kindInt: + b := strconv.AppendInt(e.buf[:0], t.i64, 10) + if _, err = e.w.Write(b); err != nil { + return err + } + e.afterValue() + case kindUint: + b := strconv.AppendUint(e.buf[:0], t.u64, 10) + if _, err = e.w.Write(b); err != nil { + return err + } + e.afterValue() + case kindFloat: + b := strconv.AppendFloat(e.buf[:0], t.f64, 'g', -1, 64) + if _, err = e.w.Write(b); err != nil { + return err + } + e.afterValue() + case kindBool: + if t.b { + if _, err = e.w.Write(trueByte); err != nil { + return err + } + } else { + if _, err = e.w.Write(falseByte); err != nil { + return err + } + } + e.afterValue() + case kindNull: + if _, err = e.w.Write(nullByte); err != nil { + return err + } + e.afterValue() + case kindObjectStart: + if _, err = e.w.Write(openObjectByte); err != nil { + return err + } + e.stack = append(e.stack, context{isObject: true, needsComma: false, expectKey: true}) + return nil + case kindObjectEnd: + if _, err = e.w.Write(closeObjectByte); err != nil { + return err + } + e.stack = e.stack[:len(e.stack)-1] + e.afterValue() + if len(e.stack) == 1 { + if _, err = e.w.Write(newlineByte); err != nil { + return err + } + } + return nil + case kindArrayStart: + if _, err = e.w.Write(openArrayByte); err != nil { + return err + } + e.stack = append(e.stack, context{isObject: false, needsComma: false, expectKey: false}) + return nil + case kindArrayEnd: + if _, err = e.w.Write(closeArrayByte); err != nil { + return err + } + e.stack = e.stack[:len(e.stack)-1] + e.afterValue() + if len(e.stack) == 1 { + if _, err = e.w.Write(newlineByte); err != nil { + return err + } + } + return nil + default: + return fmt.Errorf("unknown token kind") + } + return err +} + +// afterValue updates the state after encoding a value +func (e *Encoder) afterValue() { + if len(e.stack) > 1 { + curr := &e.stack[len(e.stack)-1] + curr.needsComma = true + if curr.isObject { + curr.expectKey = true + } + } +} + +func stringToBytes(s string) []byte { + return unsafe.Slice(unsafe.StringData(s), len(s)) +} diff --git a/vendor/github.com/quic-go/quic-go/qlogwriter/trace.go b/vendor/github.com/quic-go/quic-go/qlogwriter/trace.go new file mode 100644 index 00000000..eebcbaad --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/qlogwriter/trace.go @@ -0,0 +1,124 @@ +package qlogwriter + +import ( + "runtime/debug" + "time" + + "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/qlogwriter/jsontext" +) + +type ConnectionID = protocol.ConnectionID + +// Setting of this only works when quic-go is used as a library. +// When building a binary from this repository, the version can be set using the following go build flag: +// -ldflags="-X github.com/quic-go/quic-go/qlogwriter.quicGoVersion=foobar" +var quicGoVersion = "(devel)" + +func init() { + if quicGoVersion != "(devel)" { // variable set by ldflags + return + } + info, ok := debug.ReadBuildInfo() + if !ok { // no build info available. This happens when quic-go is not used as a library. + return + } + for _, d := range info.Deps { + if d.Path == "github.com/quic-go/quic-go" { + quicGoVersion = d.Version + if d.Replace != nil { + if len(d.Replace.Version) > 0 { + quicGoVersion = d.Version + } else { + quicGoVersion += " (replaced)" + } + } + break + } + } +} + +type encoderHelper struct { + enc *jsontext.Encoder + err error +} + +func (h *encoderHelper) WriteToken(t jsontext.Token) { + if h.err != nil { + return + } + h.err = h.enc.WriteToken(t) +} + +type traceHeader struct { + VantagePointType string + GroupID *ConnectionID + ReferenceTime time.Time + EventSchemas []string +} + +func (l traceHeader) Encode(enc *jsontext.Encoder) error { + h := encoderHelper{enc: enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("file_schema")) + h.WriteToken(jsontext.String("urn:ietf:params:qlog:file:sequential")) + h.WriteToken(jsontext.String("serialization_format")) + h.WriteToken(jsontext.String("application/qlog+json-seq")) + h.WriteToken(jsontext.String("title")) + h.WriteToken(jsontext.String("quic-go qlog")) + h.WriteToken(jsontext.String("code_version")) + h.WriteToken(jsontext.String(quicGoVersion)) + + h.WriteToken(jsontext.String("trace")) + // trace + h.WriteToken(jsontext.BeginObject) + if len(l.EventSchemas) > 0 { + h.WriteToken(jsontext.String("event_schemas")) + h.WriteToken(jsontext.BeginArray) + for _, schema := range l.EventSchemas { + h.WriteToken(jsontext.String(schema)) + } + h.WriteToken(jsontext.EndArray) + } + + h.WriteToken(jsontext.String("vantage_point")) + // -- vantage_point + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("type")) + h.WriteToken(jsontext.String(l.VantagePointType)) + // -- end vantage_point + h.WriteToken(jsontext.EndObject) + + h.WriteToken(jsontext.String("common_fields")) + // -- common_fields + h.WriteToken(jsontext.BeginObject) + if l.GroupID != nil { + h.WriteToken(jsontext.String("group_id")) + h.WriteToken(jsontext.String(l.GroupID.String())) + } + h.WriteToken(jsontext.String("reference_time")) + // ---- reference_time + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("clock_type")) + h.WriteToken(jsontext.String("monotonic")) + h.WriteToken(jsontext.String("epoch")) + h.WriteToken(jsontext.String("unknown")) + h.WriteToken(jsontext.String("wall_clock_time")) + h.WriteToken(jsontext.String(l.ReferenceTime.Format(time.RFC3339Nano))) + // ---- end reference_time + h.WriteToken(jsontext.EndObject) + // -- end common_fields + h.WriteToken(jsontext.EndObject) + // end trace + h.WriteToken(jsontext.EndObject) + + // The following fields are not required by the qlog draft anymore, + // but qvis still requires them to be present. + h.WriteToken(jsontext.String("qlog_format")) + h.WriteToken(jsontext.String("JSON-SEQ")) + h.WriteToken(jsontext.String("qlog_version")) + h.WriteToken(jsontext.String("0.3")) + + h.WriteToken(jsontext.EndObject) + return h.err +} diff --git a/vendor/github.com/quic-go/quic-go/qlogwriter/writer.go b/vendor/github.com/quic-go/quic-go/qlogwriter/writer.go new file mode 100644 index 00000000..d728f596 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/qlogwriter/writer.go @@ -0,0 +1,229 @@ +package qlogwriter + +import ( + "bytes" + "fmt" + "io" + "log" + "slices" + "sync" + "time" + + "github.com/quic-go/quic-go/qlogwriter/jsontext" +) + +// Trace represents a qlog trace that can have multiple event producers. +// Each producer can record events to the trace independently. +// When the last producer is closed, the underlying trace is closed as well. +type Trace interface { + // AddProducer creates a new Recorder for this trace. + // Each Recorder can record events independently. + AddProducer() Recorder + + // SupportsSchemas returns true if the trace supports the given schema. + SupportsSchemas(schema string) bool +} + +// Recorder is used to record events to a qlog trace. +// It is safe for concurrent use by multiple goroutines. +type Recorder interface { + // RecordEvent records a single Event to the trace. + // It must not be called after Close. + RecordEvent(Event) + // Close signals that this producer is done recording events. + // When all producers are closed, the underlying trace is closed. + // It must not be called concurrently with RecordEvent. + io.Closer +} + +// Event represents a qlog event that can be encoded to JSON. +// Each event must provide its name and a method to encode itself using a jsontext.Encoder. +type Event interface { + // Name returns the name of the event, as it should appear in the qlog output + Name() string + // Encode writes the event's data to the provided jsontext.Encoder + Encode(encoder *jsontext.Encoder, eventTime time.Time) error +} + +// RecordSeparator is the record separator byte for the JSON-SEQ format +const RecordSeparator byte = 0x1e + +var recordSeparator = []byte{RecordSeparator} + +type event struct { + Time time.Time + Event Event +} + +const eventChanSize = 50 + +// FileSeq represents a qlog trace using the JSON-SEQ format, +// https://www.ietf.org/archive/id/draft-ietf-quic-qlog-main-schema-12.html#section-5 +// qlog event producers can be created by calling AddProducer. +// The underlying io.WriteCloser is closed when the last producer is removed. +type FileSeq struct { + w io.WriteCloser + enc *jsontext.Encoder + referenceTime time.Time + + runStopped chan struct{} + encodeErr error + events chan event + done chan struct{} + + mx sync.Mutex + producers int + closed bool + + eventSchemas []string +} + +var _ Trace = &FileSeq{} + +// NewFileSeq creates a new JSON-SEQ qlog trace to log transport events. +func NewFileSeq(w io.WriteCloser) *FileSeq { + return newFileSeq(w, "transport", nil, nil) +} + +// NewConnectionFileSeq creates a new qlog trace to log connection events. +func NewConnectionFileSeq(w io.WriteCloser, isClient bool, odcid ConnectionID, eventSchemas []string) *FileSeq { + pers := "server" + if isClient { + pers = "client" + } + return newFileSeq(w, pers, &odcid, eventSchemas) +} + +func newFileSeq(w io.WriteCloser, pers string, odcid *ConnectionID, eventSchemas []string) *FileSeq { + now := time.Now() + buf := &bytes.Buffer{} + enc := jsontext.NewEncoder(buf) + if _, err := buf.Write(recordSeparator); err != nil { + panic(fmt.Sprintf("qlog encoding into a bytes.Buffer failed: %s", err)) + } + if err := (&traceHeader{ + VantagePointType: pers, + GroupID: odcid, + ReferenceTime: now, + EventSchemas: eventSchemas, + }).Encode(enc); err != nil { + panic(fmt.Sprintf("qlog encoding into a bytes.Buffer failed: %s", err)) + } + _, encodeErr := w.Write(buf.Bytes()) + + return &FileSeq{ + w: w, + referenceTime: now, + enc: jsontext.NewEncoder(w), + runStopped: make(chan struct{}), + encodeErr: encodeErr, + events: make(chan event, eventChanSize), + done: make(chan struct{}), + eventSchemas: eventSchemas, + } +} + +func (t *FileSeq) SupportsSchemas(schema string) bool { + return slices.Contains(t.eventSchemas, schema) +} + +func (t *FileSeq) AddProducer() Recorder { + t.mx.Lock() + defer t.mx.Unlock() + if t.closed { + return nil + } + + t.producers++ + + return &Writer{t: t} +} + +func (t *FileSeq) record(eventTime time.Time, details Event) { + t.mx.Lock() + + if t.closed { + t.mx.Unlock() + return + } + t.mx.Unlock() + + t.events <- event{Time: eventTime, Event: details} +} + +func (t *FileSeq) Run() { + defer close(t.runStopped) + + for { + select { + case <-t.done: + for { + select { + case e := <-t.events: + t.encodeEvent(e) + default: + if t.encodeErr != nil { + log.Printf("exporting qlog failed: %s\n", t.encodeErr) + } + return + } + } + case e := <-t.events: + t.encodeEvent(e) + } + } +} + +func (t *FileSeq) encodeEvent(e event) { + if t.encodeErr != nil { + return + } + if _, err := t.w.Write(recordSeparator); err != nil { + t.encodeErr = err + return + } + h := encoderHelper{enc: t.enc} + h.WriteToken(jsontext.BeginObject) + h.WriteToken(jsontext.String("time")) + h.WriteToken(jsontext.Float(float64(e.Time.Sub(t.referenceTime).Nanoseconds()) / 1e6)) + h.WriteToken(jsontext.String("name")) + h.WriteToken(jsontext.String(e.Event.Name())) + h.WriteToken(jsontext.String("data")) + if err := e.Event.Encode(t.enc, e.Time); err != nil { + t.encodeErr = err + return + } + h.WriteToken(jsontext.EndObject) + if h.err != nil { + t.encodeErr = h.err + } +} + +func (t *FileSeq) removeProducer() { + t.mx.Lock() + t.producers-- + last := t.producers == 0 + if last { + t.closed = true + } + t.mx.Unlock() + + if last { + close(t.done) + <-t.runStopped // wait for Run to drain and exit + _ = t.w.Close() + } +} + +type Writer struct { + t *FileSeq +} + +func (w *Writer) Close() error { + w.t.removeProducer() + return nil +} + +func (w *Writer) RecordEvent(ev Event) { + w.t.record(time.Now(), ev) +} diff --git a/vendor/github.com/quic-go/quic-go/quicvarint/io.go b/vendor/github.com/quic-go/quic-go/quicvarint/io.go index 27def409..8ea10acd 100644 --- a/vendor/github.com/quic-go/quic-go/quicvarint/io.go +++ b/vendor/github.com/quic-go/quic-go/quicvarint/io.go @@ -13,6 +13,31 @@ type Reader interface { var _ Reader = &bytes.Reader{} +// A Peeker can peek bytes without consuming them. +type Peeker interface { + Peek(b []byte) (int, error) +} + +// Peek reads a number in the QUIC varint format without consuming bytes. +func Peek(p Peeker) (uint64, error) { + var b [8]byte + + // first peek 1 byte to determine the varint length + if _, err := p.Peek(b[:1]); err != nil { + return 0, err + } + + l := 1 << (b[0] >> 6) // 1, 2, 4, or 8 bytes + if l == 1 { + return uint64(b[0] & 0b00111111), nil + } + if _, err := p.Peek(b[:l]); err != nil { + return 0, err + } + val, _, err := Parse(b[:l]) + return val, err +} + type byteReader struct { io.Reader } @@ -31,7 +56,12 @@ func NewReader(r io.Reader) Reader { func (r *byteReader) ReadByte() (byte, error) { var b [1]byte - n, err := r.Read(b[:]) + var n int + var err error + for n == 0 && err == nil { + n, err = r.Read(b[:]) + } + if n == 1 && err == io.EOF { err = nil } @@ -53,7 +83,7 @@ type byteWriter struct { var _ Writer = &byteWriter{} // NewWriter returns a Writer for w. -// If r already implements both io.ByteWriter and io.Writer, NewWriter returns w. +// If w already implements both io.ByteWriter and io.Writer, NewWriter returns w. // Otherwise, w is wrapped to add the missing interfaces. func NewWriter(w io.Writer) Writer { if w, ok := w.(Writer); ok { diff --git a/vendor/github.com/quic-go/quic-go/quicvarint/varint.go b/vendor/github.com/quic-go/quic-go/quicvarint/varint.go index f095e298..52fb153c 100644 --- a/vendor/github.com/quic-go/quic-go/quicvarint/varint.go +++ b/vendor/github.com/quic-go/quic-go/quicvarint/varint.go @@ -1,6 +1,7 @@ package quicvarint import ( + "encoding/binary" "fmt" "io" ) @@ -19,6 +20,14 @@ const ( maxVarInt8 = 4611686018427387903 ) +type varintLengthError struct { + Num uint64 +} + +func (e *varintLengthError) Error() string { + return fmt.Sprintf("value doesn't fit into 62 bits: %d", e.Num) +} + // Read reads a number in the QUIC varint format from r. func Read(r io.ByteReader) (uint64, error) { firstByte, err := r.ReadByte() @@ -74,23 +83,30 @@ func Parse(b []byte) (uint64 /* value */, int /* bytes consumed */, error) { if len(b) == 0 { return 0, 0, io.EOF } - firstByte := b[0] - // the first two bits of the first byte encode the length - l := 1 << ((firstByte & 0xc0) >> 6) - if len(b) < l { - return 0, 0, io.ErrUnexpectedEOF + + first := b[0] + switch first >> 6 { + case 0: // 1-byte encoding: 00xxxxxx + return uint64(first & 0b00111111), 1, nil + case 1: // 2-byte encoding: 01xxxxxx + if len(b) < 2 { + return 0, 0, io.ErrUnexpectedEOF + } + return uint64(b[1]) | uint64(first&0b00111111)<<8, 2, nil + case 2: // 4-byte encoding: 10xxxxxx + if len(b) < 4 { + return 0, 0, io.ErrUnexpectedEOF + } + return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(first&0b00111111)<<24, 4, nil + case 3: // 8-byte encoding: 00xxxxxx + if len(b) < 8 { + return 0, 0, io.ErrUnexpectedEOF + } + // binary.BigEndian.Uint64 only reads the first 8 bytes. Passing the full slice avoids slicing overhead. + return binary.BigEndian.Uint64(b) & 0x3fffffffffffffff, 8, nil } - b0 := firstByte & (0xff - 0xc0) - if l == 1 { - return uint64(b0), 1, nil - } - if l == 2 { - return uint64(b[1]) + uint64(b0)<<8, 2, nil - } - if l == 4 { - return uint64(b[3]) + uint64(b[2])<<8 + uint64(b[1])<<16 + uint64(b0)<<24, 4, nil - } - return uint64(b[7]) + uint64(b[6])<<8 + uint64(b[5])<<16 + uint64(b[4])<<24 + uint64(b[3])<<32 + uint64(b[2])<<40 + uint64(b[1])<<48 + uint64(b0)<<56, 8, nil + + panic("unreachable") } // Append appends i in the QUIC varint format. @@ -110,7 +126,7 @@ func Append(b []byte, i uint64) []byte { uint8(i >> 24), uint8(i >> 16), uint8(i >> 8), uint8(i), }...) } - panic(fmt.Sprintf("%#x doesn't fit into 62 bits", i)) + panic(&varintLengthError{Num: i}) } // AppendWithLen append i in the QUIC varint format with the desired length. @@ -143,6 +159,8 @@ func AppendWithLen(b []byte, i uint64, length int) []byte { } // Len determines the number of bytes that will be needed to write the number i. +// +//gcassert:inline func Len(i uint64) int { if i <= maxVarInt1 { return 1 @@ -158,8 +176,5 @@ func Len(i uint64) int { } // Don't use a fmt.Sprintf here to format the error message. // The function would then exceed the inlining budget. - panic(struct { - message string - num uint64 - }{"value doesn't fit into 62 bits: ", i}) + panic(&varintLengthError{Num: i}) } diff --git a/vendor/github.com/quic-go/quic-go/receive_stream.go b/vendor/github.com/quic-go/quic-go/receive_stream.go index 192b92f7..10a8777f 100644 --- a/vendor/github.com/quic-go/quic-go/receive_stream.go +++ b/vendor/github.com/quic-go/quic-go/receive_stream.go @@ -8,21 +8,14 @@ import ( "github.com/quic-go/quic-go/internal/ackhandler" "github.com/quic-go/quic-go/internal/flowcontrol" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" - "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" ) -type receiveStreamI interface { - ReceiveStream - - handleStreamFrame(*wire.StreamFrame, time.Time) error - handleResetStreamFrame(*wire.ResetStreamFrame, time.Time) error - closeForShutdown(error) -} - -type receiveStream struct { +// A ReceiveStream is a unidirectional Receive Stream. +type ReceiveStream struct { mutex sync.Mutex streamID protocol.StreamID @@ -49,25 +42,27 @@ type receiveStream struct { cancelErr *StreamError closeForShutdownErr error + readPos protocol.ByteCount + reliableSize protocol.ByteCount + readChan chan struct{} readOnce chan struct{} // cap: 1, to protect against concurrent use of Read - deadline time.Time + deadline monotime.Time flowController flowcontrol.StreamFlowController } var ( - _ ReceiveStream = &receiveStream{} - _ receiveStreamI = &receiveStream{} - _ streamControlFrameGetter = &receiveStream{} + _ streamControlFrameGetter = &ReceiveStream{} + _ receiveStreamFrameHandler = &ReceiveStream{} ) func newReceiveStream( streamID protocol.StreamID, sender streamSender, flowController flowcontrol.StreamFlowController, -) *receiveStream { - return &receiveStream{ +) *ReceiveStream { + return &ReceiveStream{ streamID: streamID, sender: sender, flowController: flowController, @@ -78,12 +73,15 @@ func newReceiveStream( } } -func (s *receiveStream) StreamID() protocol.StreamID { +// StreamID returns the stream ID. +func (s *ReceiveStream) StreamID() protocol.StreamID { return s.streamID } -// Read implements io.Reader. It is not thread safe! -func (s *receiveStream) Read(p []byte) (int, error) { +// Read reads data from the stream. +// Read can be made to time out using [ReceiveStream.SetReadDeadline]. +// If the stream was canceled, the error is a [StreamError]. +func (s *ReceiveStream) Read(p []byte) (int, error) { // Concurrent use of Read is not permitted (and doesn't make any sense), // but sometimes people do it anyway. // Make sure that we only execute one call at any given time to avoid hard to debug failures. @@ -107,7 +105,7 @@ func (s *receiveStream) Read(p []byte) (int, error) { return n, err } -func (s *receiveStream) isNewlyCompleted() bool { +func (s *ReceiveStream) isNewlyCompleted() bool { if s.completed { return false } @@ -128,12 +126,12 @@ func (s *receiveStream) isNewlyCompleted() bool { return false } -func (s *receiveStream) readImpl(p []byte) (hasStreamWindowUpdate bool, hasConnWindowUpdate bool, _ int, _ error) { +func (s *ReceiveStream) readImpl(p []byte) (hasStreamWindowUpdate bool, hasConnWindowUpdate bool, _ int, _ error) { if s.currentFrameIsLast && s.currentFrame == nil { s.errorRead = true return false, false, 0, io.EOF } - if s.cancelledRemotely || s.cancelledLocally { + if s.cancelledLocally || s.isRemoteCancellationEffective() { s.errorRead = true return false, false, 0, s.cancelErr } @@ -142,7 +140,7 @@ func (s *receiveStream) readImpl(p []byte) (hasStreamWindowUpdate bool, hasConnW } var bytesRead int - var deadlineTimer *utils.Timer + var deadlineTimer *time.Timer for bytesRead < len(p) { if s.currentFrame == nil || s.readPosInFrame >= len(s.currentFrame) { s.dequeueNextFrame() @@ -156,21 +154,14 @@ func (s *receiveStream) readImpl(p []byte) (hasStreamWindowUpdate bool, hasConnW if s.closeForShutdownErr != nil { return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, s.closeForShutdownErr } - if s.cancelledRemotely || s.cancelledLocally { + if s.cancelledLocally || s.isRemoteCancellationEffective() { s.errorRead = true - return hasStreamWindowUpdate, hasConnWindowUpdate, 0, s.cancelErr + return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, s.cancelErr } deadline := s.deadline - if !deadline.IsZero() { - if !time.Now().Before(deadline) { - return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, errDeadline - } - if deadlineTimer == nil { - deadlineTimer = utils.NewTimer() - defer deadlineTimer.Stop() - } - deadlineTimer.Reset(deadline) + if !deadline.IsZero() && !monotime.Now().Before(deadline) { + return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, errDeadline } if s.currentFrame != nil || s.currentFrameIsLast { @@ -181,16 +172,19 @@ func (s *receiveStream) readImpl(p []byte) (hasStreamWindowUpdate bool, hasConnW if deadline.IsZero() { <-s.readChan } else { + if deadlineTimer == nil { + deadlineTimer = time.NewTimer(monotime.Until(deadline)) + defer deadlineTimer.Stop() + } else { + deadlineTimer.Reset(monotime.Until(deadline)) + } select { case <-s.readChan: - case <-deadlineTimer.Chan(): - deadlineTimer.SetRead() + case <-deadlineTimer.C: } } s.mutex.Lock() - if s.currentFrame == nil { - s.dequeueNextFrame() - } + s.dequeueNextFrame() } if bytesRead > len(p) { @@ -199,14 +193,11 @@ func (s *receiveStream) readImpl(p []byte) (hasStreamWindowUpdate bool, hasConnW if s.readPosInFrame > len(s.currentFrame) { return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, fmt.Errorf("BUG: readPosInFrame (%d) > frame.DataLen (%d) in stream.Read", s.readPosInFrame, len(s.currentFrame)) } - m := copy(p[bytesRead:], s.currentFrame[s.readPosInFrame:]) - s.readPosInFrame += m - bytesRead += m // when a RESET_STREAM was received, the flow controller was already - // informed about the final byteOffset for this stream - if !s.cancelledRemotely { + // informed about the final offset for this stream + if !s.isRemoteCancellationEffective() { hasStream, hasConn := s.flowController.AddBytesRead(protocol.ByteCount(m)) if hasStream { s.queuedMaxStreamData = true @@ -217,6 +208,14 @@ func (s *receiveStream) readImpl(p []byte) (hasStreamWindowUpdate bool, hasConnW } } + s.readPosInFrame += m + s.readPos += protocol.ByteCount(m) + bytesRead += m + + if s.isRemoteCancellationEffective() { + s.flowController.Abandon() + } + if s.readPosInFrame >= len(s.currentFrame) && s.currentFrameIsLast { s.currentFrame = nil if s.currentFrameDone != nil { @@ -226,21 +225,150 @@ func (s *receiveStream) readImpl(p []byte) (hasStreamWindowUpdate bool, hasConnW return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, io.EOF } } + if s.isRemoteCancellationEffective() { + s.errorRead = true + return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, s.cancelErr + } return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, nil } -func (s *receiveStream) dequeueNextFrame() { +// isRemoteCancellationEffective returns whether the stream was cancelled remotely +// and all reliable data has been read. +func (s *ReceiveStream) isRemoteCancellationEffective() bool { + return s.cancelledRemotely && s.readPos >= s.reliableSize +} + +// Peek fills b with stream data, without consuming the stream data. +// It blocks until len(b) bytes are available, or an error occurs. +// It respects the stream deadline set by SetReadDeadline. +// If the stream ends before len(b) bytes are available, +// it returns the number of bytes peeked along with io.EOF. +func (s *ReceiveStream) Peek(b []byte) (int, error) { + if len(b) == 0 { + return 0, nil + } + + // prevent concurrent use with Read + s.readOnce <- struct{}{} + defer func() { <-s.readOnce }() + + return s.peekImpl(b) +} + +func (s *ReceiveStream) peekImpl(b []byte) (int, error) { + s.mutex.Lock() + defer s.mutex.Unlock() + + var deadlineTimer *time.Timer + + for { + if s.currentFrameIsLast && s.currentFrame == nil { + return 0, io.EOF + } + if s.cancelledLocally || s.isRemoteCancellationEffective() { + return 0, s.cancelErr + } + if s.closeForShutdownErr != nil { + return 0, s.closeForShutdownErr + } + + deadline := s.deadline + if !deadline.IsZero() && !monotime.Now().Before(deadline) { + return 0, errDeadline + } + + if s.currentFrame == nil || s.readPosInFrame >= len(s.currentFrame) { + s.dequeueNextFrame() + } + + if s.currentFrame != nil && s.readPosInFrame < len(s.currentFrame) { + availableInCurrentFrame := len(s.currentFrame) - s.readPosInFrame + + if availableInCurrentFrame >= len(b) { + copy(b, s.currentFrame[s.readPosInFrame:]) + return len(b), nil + } + + offset := s.readPos + protocol.ByteCount(availableInCurrentFrame) + // First peek, then copy. + // This avoids copying data if there's not enough data in the queue. + if err := s.frameQueue.Peek(offset, b[availableInCurrentFrame:]); err == nil { + copy(b[:availableInCurrentFrame], s.currentFrame[s.readPosInFrame:]) + return len(b), nil + } + + if s.currentFrameIsLast { + copy(b[:availableInCurrentFrame], s.currentFrame[s.readPosInFrame:]) + return availableInCurrentFrame, io.EOF + } + + // If the stream was remotely cancelled and the request extends beyond the reliable size, + // return the data available with the cancel error (once it's all received). + if s.cancelledRemotely && s.readPos+protocol.ByteCount(len(b)) > s.reliableSize { + total := int(s.reliableSize - s.readPos) + needed := total - availableInCurrentFrame + // only return once all available data is contiguous + if needed <= 0 || s.frameQueue.Peek(offset, b[availableInCurrentFrame:total]) == nil { + copy(b[:availableInCurrentFrame], s.currentFrame[s.readPosInFrame:]) + return total, s.cancelErr + } + } + + // If the request extends beyond the stream's final offset, + // return the data available with EOF (once it's all received). + if s.readPos+protocol.ByteCount(len(b)) > s.finalOffset { + total := int(s.finalOffset - s.readPos) + needed := total - availableInCurrentFrame + // only return once all available data is contiguous + if needed <= 0 || s.frameQueue.Peek(offset, b[availableInCurrentFrame:total]) == nil { + copy(b[:availableInCurrentFrame], s.currentFrame[s.readPosInFrame:]) + return total, io.EOF + } + } + } + + if s.currentFrameIsLast || s.readPos >= s.finalOffset { + return 0, io.EOF + } + + s.mutex.Unlock() + if deadline.IsZero() { + <-s.readChan + } else { + if deadlineTimer == nil { + deadlineTimer = time.NewTimer(monotime.Until(deadline)) + defer deadlineTimer.Stop() + } else { + deadlineTimer.Reset(monotime.Until(deadline)) + } + select { + case <-s.readChan: + case <-deadlineTimer.C: + } + } + s.mutex.Lock() + if s.currentFrame == nil || s.readPosInFrame >= len(s.currentFrame) { + s.dequeueNextFrame() + } + } +} + +func (s *ReceiveStream) dequeueNextFrame() { var offset protocol.ByteCount // We're done with the last frame. Release the buffer. if s.currentFrameDone != nil { s.currentFrameDone() } offset, s.currentFrame, s.currentFrameDone = s.frameQueue.Pop() - s.currentFrameIsLast = offset+protocol.ByteCount(len(s.currentFrame)) >= s.finalOffset + s.currentFrameIsLast = offset+protocol.ByteCount(len(s.currentFrame)) >= s.finalOffset && !s.cancelledRemotely s.readPosInFrame = 0 } -func (s *receiveStream) CancelRead(errorCode StreamErrorCode) { +// CancelRead aborts receiving on this stream. +// It instructs the peer to stop transmitting stream data. +// Read will unblock immediately, and future Read calls will fail. +// When called multiple times or after reading the io.EOF it is a no-op. +func (s *ReceiveStream) CancelRead(errorCode StreamErrorCode) { s.mutex.Lock() queuedNewControlFrame := s.cancelReadImpl(errorCode) completed := s.isNewlyCompleted() @@ -255,7 +383,7 @@ func (s *receiveStream) CancelRead(errorCode StreamErrorCode) { } } -func (s *receiveStream) cancelReadImpl(errorCode qerr.StreamErrorCode) (queuedNewControlFrame bool) { +func (s *ReceiveStream) cancelReadImpl(errorCode qerr.StreamErrorCode) (queuedNewControlFrame bool) { if s.cancelledLocally { // duplicate call to CancelRead return false } @@ -272,7 +400,7 @@ func (s *receiveStream) cancelReadImpl(errorCode qerr.StreamErrorCode) (queuedNe return true } -func (s *receiveStream) handleStreamFrame(frame *wire.StreamFrame, now time.Time) error { +func (s *ReceiveStream) handleStreamFrame(frame *wire.StreamFrame, now monotime.Time) error { s.mutex.Lock() err := s.handleStreamFrameImpl(frame, now) completed := s.isNewlyCompleted() @@ -285,7 +413,7 @@ func (s *receiveStream) handleStreamFrame(frame *wire.StreamFrame, now time.Time return err } -func (s *receiveStream) handleStreamFrameImpl(frame *wire.StreamFrame, now time.Time) error { +func (s *ReceiveStream) handleStreamFrameImpl(frame *wire.StreamFrame, now monotime.Time) error { maxOffset := frame.Offset + frame.DataLen() if err := s.flowController.UpdateHighestReceived(maxOffset, frame.Fin, now); err != nil { return err @@ -303,7 +431,7 @@ func (s *receiveStream) handleStreamFrameImpl(frame *wire.StreamFrame, now time. return nil } -func (s *receiveStream) handleResetStreamFrame(frame *wire.ResetStreamFrame, now time.Time) error { +func (s *ReceiveStream) handleResetStreamFrame(frame *wire.ResetStreamFrame, now monotime.Time) error { s.mutex.Lock() err := s.handleResetStreamFrameImpl(frame, now) completed := s.isNewlyCompleted() @@ -315,7 +443,7 @@ func (s *receiveStream) handleResetStreamFrame(frame *wire.ResetStreamFrame, now return err } -func (s *receiveStream) handleResetStreamFrameImpl(frame *wire.ResetStreamFrame, now time.Time) error { +func (s *ReceiveStream) handleResetStreamFrameImpl(frame *wire.ResetStreamFrame, now monotime.Time) error { if s.closeForShutdownErr != nil { return nil } @@ -324,11 +452,19 @@ func (s *receiveStream) handleResetStreamFrameImpl(frame *wire.ResetStreamFrame, } s.finalOffset = frame.FinalSize + // senders are allowed to reduce the reliable size, but frames might have been reordered + if (!s.cancelledRemotely && s.reliableSize == 0) || frame.ReliableSize < s.reliableSize { + s.reliableSize = frame.ReliableSize + } + if s.readPos >= s.reliableSize { + // calling Abandon multiple times is a no-op + s.flowController.Abandon() + } // ignore duplicate RESET_STREAM frames for this stream (after checking their final offset) if s.cancelledRemotely { return nil } - s.flowController.Abandon() + // don't save the error if the RESET_STREAM frames was received after CancelRead was called if s.cancelledLocally { return nil @@ -339,7 +475,7 @@ func (s *receiveStream) handleResetStreamFrameImpl(frame *wire.ResetStreamFrame, return nil } -func (s *receiveStream) getControlFrame(now time.Time) (_ ackhandler.Frame, ok, hasMore bool) { +func (s *ReceiveStream) getControlFrame(now monotime.Time) (_ ackhandler.Frame, ok, hasMore bool) { s.mutex.Lock() defer s.mutex.Unlock() @@ -362,9 +498,12 @@ func (s *receiveStream) getControlFrame(now time.Time) (_ ackhandler.Frame, ok, }, true, false } -func (s *receiveStream) SetReadDeadline(t time.Time) error { +// SetReadDeadline sets the deadline for future Read calls and +// any currently-blocked Read call. +// A zero value for t means Read will not time out. +func (s *ReceiveStream) SetReadDeadline(t time.Time) error { s.mutex.Lock() - s.deadline = t + s.deadline = monotime.FromTime(t) s.mutex.Unlock() s.signalRead() return nil @@ -373,7 +512,7 @@ func (s *receiveStream) SetReadDeadline(t time.Time) error { // CloseForShutdown closes a stream abruptly. // It makes Read unblock (and return the error) immediately. // The peer will NOT be informed about this: the stream is closed without sending a FIN or RESET. -func (s *receiveStream) closeForShutdown(err error) { +func (s *ReceiveStream) closeForShutdown(err error) { s.mutex.Lock() s.closeForShutdownErr = err s.mutex.Unlock() @@ -381,7 +520,7 @@ func (s *receiveStream) closeForShutdown(err error) { } // signalRead performs a non-blocking send on the readChan -func (s *receiveStream) signalRead() { +func (s *ReceiveStream) signalRead() { select { case s.readChan <- struct{}{}: default: diff --git a/vendor/github.com/quic-go/quic-go/send_stream.go b/vendor/github.com/quic-go/quic-go/send_stream.go index a588cc8a..723f9d5f 100644 --- a/vendor/github.com/quic-go/quic-go/send_stream.go +++ b/vendor/github.com/quic-go/quic-go/send_stream.go @@ -8,22 +8,13 @@ import ( "github.com/quic-go/quic-go/internal/ackhandler" "github.com/quic-go/quic-go/internal/flowcontrol" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" - "github.com/quic-go/quic-go/internal/qerr" - "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" ) -type sendStreamI interface { - SendStream - handleStopSendingFrame(*wire.StopSendingFrame) - hasData() bool - popStreamFrame(protocol.ByteCount, protocol.Version) (_ ackhandler.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMore bool) - closeForShutdown(error) - updateSendWindow(protocol.ByteCount) -} - -type sendStream struct { +// A SendStream is a unidirectional Send Stream. +type SendStream struct { mutex sync.Mutex numOutstandingFrames int64 // outstanding STREAM and RESET_STREAM frames @@ -35,21 +26,25 @@ type sendStream struct { streamID protocol.StreamID sender streamSender - writeOffset protocol.ByteCount + // reliableSize is the portion of the stream that needs to be transmitted reliably, + // even if the stream is cancelled. + // This requires the peer to support RESET_STREAM_AT. + // This value should not be accessed directly, but only through the reliableOffset method. + // This method returns 0 if the peer doesn't support the RESET_STREAM_AT extension. + reliableSize protocol.ByteCount + writeOffset protocol.ByteCount - // finalError is the error that is returned by Write. - // It can either be a cancellation error or the shutdown error. - finalError error + shutdownErr error + resetErr *StreamError queuedResetStreamFrame *wire.ResetStreamFrame - finishedWriting bool // set once Close() is called - finSent bool // set when a STREAM_FRAME with FIN bit has been sent + supportsResetStreamAt bool + finishedWriting bool // set once Close() is called + finSent bool // set when a STREAM_FRAME with FIN bit has been sent // Set when the application knows about the cancellation. // This can happen because the application called CancelWrite, // or because Write returned the error (for remote cancellations). cancellationFlagged bool - cancelled bool // both local and remote cancellations - closedForShutdown bool // set by closeForShutdown completed bool // set when this stream has been reported to the streamSender as completed dataForWriting []byte // during a Write() call, this slice is the part of p that still needs to be sent out @@ -57,15 +52,15 @@ type sendStream struct { writeChan chan struct{} writeOnce chan struct{} - deadline time.Time + deadline monotime.Time flowController flowcontrol.StreamFlowController } var ( - _ SendStream = &sendStream{} - _ sendStreamI = &sendStream{} - _ streamControlFrameGetter = &sendStream{} + _ streamControlFrameGetter = &SendStream{} + _ outgoingStream = &SendStream{} + _ sendStreamFrameHandler = &SendStream{} ) func newSendStream( @@ -73,23 +68,29 @@ func newSendStream( streamID protocol.StreamID, sender streamSender, flowController flowcontrol.StreamFlowController, -) *sendStream { - s := &sendStream{ - streamID: streamID, - sender: sender, - flowController: flowController, - writeChan: make(chan struct{}, 1), - writeOnce: make(chan struct{}, 1), // cap: 1, to protect against concurrent use of Write + supportsResetStreamAt bool, +) *SendStream { + s := &SendStream{ + streamID: streamID, + sender: sender, + flowController: flowController, + writeChan: make(chan struct{}, 1), + writeOnce: make(chan struct{}, 1), // cap: 1, to protect against concurrent use of Write + supportsResetStreamAt: supportsResetStreamAt, } s.ctx, s.ctxCancel = context.WithCancelCause(ctx) return s } -func (s *sendStream) StreamID() protocol.StreamID { +// StreamID returns the stream ID. +func (s *SendStream) StreamID() StreamID { return s.streamID // same for receiveStream and sendStream } -func (s *sendStream) Write(p []byte) (int, error) { +// Write writes data to the stream. +// Write can be made to time out using [SendStream.SetWriteDeadline]. +// If the stream was canceled, the error is a [StreamError]. +func (s *SendStream) Write(p []byte) (int, error) { // Concurrent use of Write is not permitted (and doesn't make any sense), // but sometimes people do it anyway. // Make sure that we only execute one call at any given time to avoid hard to debug failures. @@ -103,20 +104,21 @@ func (s *sendStream) Write(p []byte) (int, error) { return n, err } -func (s *sendStream) write(p []byte) (bool /* is newly completed */, int, error) { +func (s *SendStream) write(p []byte) (bool /* is newly completed */, int, error) { s.mutex.Lock() defer s.mutex.Unlock() - if s.finalError != nil { - if s.cancelled { - s.cancellationFlagged = true - } - return s.isNewlyCompleted(), 0, s.finalError + if s.resetErr != nil { + s.cancellationFlagged = true + return s.isNewlyCompleted(), 0, s.resetErr + } + if s.shutdownErr != nil { + return false, 0, s.shutdownErr } if s.finishedWriting { return false, 0, fmt.Errorf("write on closed stream %d", s.streamID) } - if !s.deadline.IsZero() && !time.Now().Before(s.deadline) { + if !s.deadline.IsZero() && !monotime.Now().Before(s.deadline) { return false, 0, errDeadline } if len(p) == 0 { @@ -126,13 +128,13 @@ func (s *sendStream) write(p []byte) (bool /* is newly completed */, int, error) s.dataForWriting = p var ( - deadlineTimer *utils.Timer + deadlineTimer *time.Timer bytesWritten int notifiedSender bool ) for { var copied bool - var deadline time.Time + var deadline monotime.Time // As soon as dataForWriting becomes smaller than a certain size x, we copy all the data to a STREAM frame (s.nextFrame), // which can then be popped the next time we assemble a packet. // This allows us to return Write() when all data but x bytes have been sent out. @@ -159,17 +161,18 @@ func (s *sendStream) write(p []byte) (bool /* is newly completed */, int, error) bytesWritten = len(p) - len(s.dataForWriting) deadline = s.deadline if !deadline.IsZero() { - if !time.Now().Before(deadline) { + if !monotime.Now().Before(deadline) { s.dataForWriting = nil return false, bytesWritten, errDeadline } if deadlineTimer == nil { - deadlineTimer = utils.NewTimer() + deadlineTimer = time.NewTimer(monotime.Until(deadline)) defer deadlineTimer.Stop() + } else { + deadlineTimer.Reset(monotime.Until(deadline)) } - deadlineTimer.Reset(deadline) } - if s.dataForWriting == nil || s.finalError != nil { + if s.dataForWriting == nil || s.shutdownErr != nil || s.resetErr != nil { break } } @@ -188,8 +191,7 @@ func (s *sendStream) write(p []byte) (bool /* is newly completed */, int, error) } else { select { case <-s.writeChan: - case <-deadlineTimer.Chan(): - deadlineTimer.SetRead() + case <-deadlineTimer.C: } } s.mutex.Lock() @@ -198,16 +200,17 @@ func (s *sendStream) write(p []byte) (bool /* is newly completed */, int, error) if bytesWritten == len(p) { return false, bytesWritten, nil } - if s.finalError != nil { - if s.cancelled { - s.cancellationFlagged = true - } - return s.isNewlyCompleted(), bytesWritten, s.finalError + if s.shutdownErr != nil { + return false, bytesWritten, s.shutdownErr + } + if s.resetErr != nil { + s.cancellationFlagged = true + return s.isNewlyCompleted(), bytesWritten, s.resetErr } return false, bytesWritten, nil } -func (s *sendStream) canBufferStreamFrame() bool { +func (s *SendStream) canBufferStreamFrame() bool { var l protocol.ByteCount if s.nextFrame != nil { l = s.nextFrame.DataLen() @@ -217,7 +220,7 @@ func (s *sendStream) canBufferStreamFrame() bool { // popStreamFrame returns the next STREAM frame that is supposed to be sent on this stream // maxBytes is the maximum length this frame (including frame header) will have. -func (s *sendStream) popStreamFrame(maxBytes protocol.ByteCount, v protocol.Version) (_ ackhandler.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMore bool) { +func (s *SendStream) popStreamFrame(maxBytes protocol.ByteCount, v protocol.Version) (_ ackhandler.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMore bool) { s.mutex.Lock() f, blocked, hasMoreData := s.popNewOrRetransmittedStreamFrame(maxBytes, v) if f != nil { @@ -234,10 +237,16 @@ func (s *sendStream) popStreamFrame(maxBytes protocol.ByteCount, v protocol.Vers }, blocked, hasMoreData } -func (s *sendStream) popNewOrRetransmittedStreamFrame(maxBytes protocol.ByteCount, v protocol.Version) (_ *wire.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMoreData bool) { - if s.finalError != nil { +func (s *SendStream) popNewOrRetransmittedStreamFrame(maxBytes protocol.ByteCount, v protocol.Version) (_ *wire.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMoreData bool) { + if s.shutdownErr != nil { return nil, nil, false } + if s.resetErr != nil { + reliableOffset := s.reliableOffset() + if reliableOffset == 0 || (s.writeOffset >= reliableOffset && len(s.retransmissionQueue) == 0) { + return nil, nil, false + } + } if len(s.retransmissionQueue) > 0 { f, hasMoreRetransmissions := s.maybeGetRetransmission(maxBytes, v) @@ -264,12 +273,17 @@ func (s *sendStream) popNewOrRetransmittedStreamFrame(maxBytes protocol.ByteCoun return nil, nil, false } - sendWindow := s.flowController.SendWindowSize() - if sendWindow == 0 { + maxDataLen := s.flowController.SendWindowSize() + if maxDataLen == 0 { return nil, nil, true } - f, hasMoreData := s.popNewStreamFrame(maxBytes, sendWindow, v) + // if the stream is canceled, only data up to the reliable size needs to be sent + reliableOffset := s.reliableOffset() + if s.resetErr != nil && reliableOffset > 0 { + maxDataLen = min(maxDataLen, reliableOffset-s.writeOffset) + } + f, hasMoreData := s.popNewStreamFrame(maxBytes, maxDataLen, v) if f == nil { return nil, nil, hasMoreData } @@ -277,10 +291,13 @@ func (s *sendStream) popNewOrRetransmittedStreamFrame(maxBytes protocol.ByteCoun s.writeOffset += f.DataLen() s.flowController.AddBytesSent(f.DataLen()) } + if s.resetErr != nil && s.writeOffset >= reliableOffset { + hasMoreData = false + } var blocked *wire.StreamDataBlockedFrame // If the entire send window is used, the stream might have become blocked on stream-level flow control. // This is not guaranteed though, because the stream might also have been blocked on connection-level flow control. - if f.DataLen() == sendWindow && s.flowController.IsNewlyBlocked() { + if f.DataLen() == maxDataLen && s.flowController.IsNewlyBlocked() { blocked = &wire.StreamDataBlockedFrame{StreamID: s.streamID, MaximumStreamData: s.writeOffset} } f.Fin = s.finishedWriting && s.dataForWriting == nil && s.nextFrame == nil && !s.finSent @@ -290,9 +307,11 @@ func (s *sendStream) popNewOrRetransmittedStreamFrame(maxBytes protocol.ByteCoun return f, blocked, hasMoreData } -func (s *sendStream) popNewStreamFrame(maxBytes, sendWindow protocol.ByteCount, v protocol.Version) (*wire.StreamFrame, bool) { +// popNewStreamFrame returns a new STREAM frame to send for this stream +// hasMoreData says if there's more data to send, *not* taking into account the reliable size +func (s *SendStream) popNewStreamFrame(maxBytes, maxDataLen protocol.ByteCount, v protocol.Version) (_ *wire.StreamFrame, hasMoreData bool) { if s.nextFrame != nil { - maxDataLen := min(sendWindow, s.nextFrame.MaxDataLen(maxBytes, v)) + maxDataLen := min(maxDataLen, s.nextFrame.MaxDataLen(maxBytes, v)) if maxDataLen == 0 { return nil, true } @@ -319,7 +338,7 @@ func (s *sendStream) popNewStreamFrame(maxBytes, sendWindow protocol.ByteCount, f.DataLenPresent = true f.Data = f.Data[:0] - hasMoreData := s.popNewStreamFrameWithoutBuffer(f, maxBytes, sendWindow, v) + hasMoreData = s.popNewStreamFrameWithoutBuffer(f, maxBytes, maxDataLen, v) if len(f.Data) == 0 && !f.Fin { f.PutBack() return nil, hasMoreData @@ -327,7 +346,7 @@ func (s *sendStream) popNewStreamFrame(maxBytes, sendWindow protocol.ByteCount, return f, hasMoreData } -func (s *sendStream) popNewStreamFrameWithoutBuffer(f *wire.StreamFrame, maxBytes, sendWindow protocol.ByteCount, v protocol.Version) bool { +func (s *SendStream) popNewStreamFrameWithoutBuffer(f *wire.StreamFrame, maxBytes, sendWindow protocol.ByteCount, v protocol.Version) bool { maxDataLen := f.MaxDataLen(maxBytes, v) if maxDataLen == 0 { // a STREAM frame must have at least one byte of data return s.dataForWriting != nil || s.nextFrame != nil || s.finishedWriting @@ -337,7 +356,7 @@ func (s *sendStream) popNewStreamFrameWithoutBuffer(f *wire.StreamFrame, maxByte return s.dataForWriting != nil || s.nextFrame != nil || s.finishedWriting } -func (s *sendStream) maybeGetRetransmission(maxBytes protocol.ByteCount, v protocol.Version) (*wire.StreamFrame, bool /* has more retransmissions */) { +func (s *SendStream) maybeGetRetransmission(maxBytes protocol.ByteCount, v protocol.Version) (*wire.StreamFrame, bool /* has more retransmissions */) { f := s.retransmissionQueue[0] newFrame, needsSplit := f.MaybeSplitOffFrame(maxBytes, v) if needsSplit { @@ -347,14 +366,7 @@ func (s *sendStream) maybeGetRetransmission(maxBytes protocol.ByteCount, v proto return f, len(s.retransmissionQueue) > 0 } -func (s *sendStream) hasData() bool { - s.mutex.Lock() - hasData := len(s.dataForWriting) > 0 - s.mutex.Unlock() - return hasData -} - -func (s *sendStream) getDataForWriting(f *wire.StreamFrame, maxBytes protocol.ByteCount) { +func (s *SendStream) getDataForWriting(f *wire.StreamFrame, maxBytes protocol.ByteCount) { if protocol.ByteCount(len(s.dataForWriting)) <= maxBytes { f.Data = f.Data[:len(s.dataForWriting)] copy(f.Data, s.dataForWriting) @@ -370,10 +382,13 @@ func (s *sendStream) getDataForWriting(f *wire.StreamFrame, maxBytes protocol.By } } -func (s *sendStream) isNewlyCompleted() bool { +func (s *SendStream) isNewlyCompleted() bool { if s.completed { return false } + if s.nextFrame != nil && s.nextFrame.DataLen() > 0 { + return false + } // We need to keep the stream around until all frames have been sent and acknowledged. if s.numOutstandingFrames > 0 || len(s.retransmissionQueue) > 0 || s.queuedResetStreamFrame != nil { return false @@ -388,21 +403,25 @@ func (s *sendStream) isNewlyCompleted() bool { // 2. we received a STOP_SENDING, and // * the application consumed the error via Write, or // * the application called Close - if s.cancelled && (s.cancellationFlagged || s.finishedWriting) { + if s.resetErr != nil && (s.cancellationFlagged || s.finishedWriting) { s.completed = true return true } return false } -func (s *sendStream) Close() error { +// Close closes the write-direction of the stream. +// Future calls to Write are not permitted after calling Close. +// It must not be called concurrently with Write. +// It must not be called after calling CancelWrite. +func (s *SendStream) Close() error { s.mutex.Lock() - if s.closedForShutdown || s.finishedWriting { + if s.shutdownErr != nil || s.finishedWriting { s.mutex.Unlock() return nil } s.finishedWriting = true - cancelled := s.cancelled + cancelled := s.resetErr != nil if cancelled { s.cancellationFlagged = true } @@ -421,46 +440,98 @@ func (s *sendStream) Close() error { return nil } -func (s *sendStream) CancelWrite(errorCode StreamErrorCode) { - s.cancelWrite(errorCode, false) +// SetReliableBoundary marks the data written to this stream so far as reliable. +// It is valid to call this function multiple times, thereby increasing the reliable size. +// It only has an effect if the peer enabled support for the RESET_STREAM_AT extension, +// otherwise, it is a no-op. +func (s *SendStream) SetReliableBoundary() { + s.mutex.Lock() + defer s.mutex.Unlock() + + s.reliableSize = s.writeOffset + if s.nextFrame != nil { + s.reliableSize += s.nextFrame.DataLen() + } } -// cancelWrite cancels the stream -// It is possible to cancel a stream after it has been closed, both locally and remotely. -// This is useful to prevent the retransmission of outstanding stream data. -func (s *sendStream) cancelWrite(errorCode qerr.StreamErrorCode, remote bool) { - s.mutex.Lock() - if s.closedForShutdown { - s.mutex.Unlock() - return +// returnFramesToPool returns all queued frames to the sync.Pool +func (s *SendStream) returnFramesToPool() { + for _, f := range s.retransmissionQueue { + f.PutBack() } - if !remote { - s.cancellationFlagged = true - if s.cancelled { - completed := s.isNewlyCompleted() - s.mutex.Unlock() - // The user has called CancelWrite. If the previous cancellation was - // because of a STOP_SENDING, we don't need to flag the error to the - // user anymore. - if completed { - s.sender.onStreamCompleted(s.streamID) - } - return - } - } - if s.cancelled { - s.mutex.Unlock() - return - } - s.cancelled = true - s.finalError = &StreamError{StreamID: s.streamID, ErrorCode: errorCode, Remote: remote} - s.ctxCancel(s.finalError) - s.numOutstandingFrames = 0 + clear(s.retransmissionQueue) s.retransmissionQueue = nil + if s.nextFrame != nil { + s.nextFrame.PutBack() + s.nextFrame = nil + } +} + +// CancelWrite aborts sending on this stream. +// Data already written, but not yet delivered to the peer is not guaranteed to be delivered reliably. +// Write will unblock immediately, and future calls to Write will fail. +// When called multiple times it is a no-op. +// When called after Close, it aborts reliable delivery of outstanding stream data. +// Note that there is no guarantee if the peer will receive the FIN or the cancellation error first. +func (s *SendStream) CancelWrite(errorCode StreamErrorCode) { + s.mutex.Lock() + if s.shutdownErr != nil { + s.mutex.Unlock() + return + } + + s.cancellationFlagged = true + + if s.resetErr != nil { + completed := s.isNewlyCompleted() + s.mutex.Unlock() + // The user has called CancelWrite. If the previous cancellation was because of a + // STOP_SENDING, we don't need to flag the error to the user anymore. + if completed { + s.sender.onStreamCompleted(s.streamID) + } + return + } + s.resetErr = &StreamError{StreamID: s.streamID, ErrorCode: errorCode, Remote: false} + s.ctxCancel(s.resetErr) + + reliableOffset := s.reliableOffset() + if reliableOffset == 0 { + s.numOutstandingFrames = 0 + s.returnFramesToPool() + } s.queuedResetStreamFrame = &wire.ResetStreamFrame{ StreamID: s.streamID, - FinalSize: s.writeOffset, + FinalSize: max(s.writeOffset, reliableOffset), ErrorCode: errorCode, + // if the peer doesn't support the extension, the reliable offset will always be 0 + ReliableSize: reliableOffset, + } + if reliableOffset > 0 { + if s.nextFrame != nil { + if s.nextFrame.Offset >= reliableOffset { + s.nextFrame.PutBack() + s.nextFrame = nil + } else if s.nextFrame.Offset+s.nextFrame.DataLen() > reliableOffset { + s.nextFrame.Data = s.nextFrame.Data[:reliableOffset-s.nextFrame.Offset] + } + } + if len(s.retransmissionQueue) > 0 { + retransmissionQueue := make([]*wire.StreamFrame, 0, len(s.retransmissionQueue)) + for _, f := range s.retransmissionQueue { + if f.Offset >= reliableOffset { + f.PutBack() + continue + } + if f.Offset+f.DataLen() <= reliableOffset { + retransmissionQueue = append(retransmissionQueue, f) + } else { + f.Data = f.Data[:reliableOffset-f.Offset] + retransmissionQueue = append(retransmissionQueue, f) + } + } + s.retransmissionQueue = retransmissionQueue + } } s.mutex.Unlock() @@ -468,7 +539,13 @@ func (s *sendStream) cancelWrite(errorCode qerr.StreamErrorCode, remote bool) { s.sender.onHasStreamControlFrame(s.streamID, s) } -func (s *sendStream) updateSendWindow(limit protocol.ByteCount) { +func (s *SendStream) enableResetStreamAt() { + s.mutex.Lock() + s.supportsResetStreamAt = true + s.mutex.Unlock() +} + +func (s *SendStream) updateSendWindow(limit protocol.ByteCount) { updated := s.flowController.UpdateSendWindow(limit) if !updated { // duplicate or reordered MAX_STREAM_DATA frame return @@ -481,11 +558,39 @@ func (s *sendStream) updateSendWindow(limit protocol.ByteCount) { } } -func (s *sendStream) handleStopSendingFrame(frame *wire.StopSendingFrame) { - s.cancelWrite(frame.ErrorCode, true) +func (s *SendStream) handleStopSendingFrame(f *wire.StopSendingFrame) { + s.mutex.Lock() + if s.shutdownErr != nil { + s.mutex.Unlock() + return + } + + // If the stream was already cancelled (either locally, or due to a previous STOP_SENDING frame), + // there's nothing else to do. + if s.resetErr != nil && s.reliableOffset() == 0 { + s.mutex.Unlock() + return + } + // if the peer stopped reading from the stream, there's no need to transmit any data reliably + s.reliableSize = 0 + s.numOutstandingFrames = 0 + s.returnFramesToPool() + if s.resetErr == nil { + s.resetErr = &StreamError{StreamID: s.streamID, ErrorCode: f.ErrorCode, Remote: true} + s.ctxCancel(s.resetErr) + } + s.queuedResetStreamFrame = &wire.ResetStreamFrame{ + StreamID: s.streamID, + FinalSize: s.writeOffset, + ErrorCode: s.resetErr.ErrorCode, + } + s.mutex.Unlock() + + s.signalWrite() + s.sender.onHasStreamControlFrame(s.streamID, s) } -func (s *sendStream) getControlFrame(time.Time) (_ ackhandler.Frame, ok, hasMore bool) { +func (s *SendStream) getControlFrame(monotime.Time) (_ ackhandler.Frame, ok, hasMore bool) { s.mutex.Lock() defer s.mutex.Unlock() @@ -501,13 +606,30 @@ func (s *sendStream) getControlFrame(time.Time) (_ ackhandler.Frame, ok, hasMore return f, true, false } -func (s *sendStream) Context() context.Context { +func (s *SendStream) reliableOffset() protocol.ByteCount { + if !s.supportsResetStreamAt { + return 0 + } + return s.reliableSize +} + +// The Context is canceled as soon as the write-side of the stream is closed. +// This happens when Close() or CancelWrite() is called, or when the peer +// cancels the read-side of their stream. +// The cancellation cause is set to the error that caused the stream to +// close, or `context.Canceled` in case the stream is closed without error. +func (s *SendStream) Context() context.Context { return s.ctx } -func (s *sendStream) SetWriteDeadline(t time.Time) error { +// SetWriteDeadline sets the deadline for future Write calls +// and any currently-blocked Write call. +// Even if write times out, it may return n > 0, indicating that +// some data was successfully written. +// A zero value for t means Write will not time out. +func (s *SendStream) SetWriteDeadline(t time.Time) error { s.mutex.Lock() - s.deadline = t + s.deadline = monotime.FromTime(t) s.mutex.Unlock() s.signalWrite() return nil @@ -516,33 +638,34 @@ func (s *sendStream) SetWriteDeadline(t time.Time) error { // CloseForShutdown closes a stream abruptly. // It makes Write unblock (and return the error) immediately. // The peer will NOT be informed about this: the stream is closed without sending a FIN or RST. -func (s *sendStream) closeForShutdown(err error) { +func (s *SendStream) closeForShutdown(err error) { s.mutex.Lock() - s.closedForShutdown = true - if s.finalError == nil && !s.finishedWriting { - s.finalError = err + if s.shutdownErr == nil && !s.finishedWriting { + s.shutdownErr = err + s.returnFramesToPool() } s.mutex.Unlock() s.signalWrite() } // signalWrite performs a non-blocking send on the writeChan -func (s *sendStream) signalWrite() { +func (s *SendStream) signalWrite() { select { case s.writeChan <- struct{}{}: default: } } -type sendStreamAckHandler sendStream +type sendStreamAckHandler SendStream var _ ackhandler.FrameHandler = &sendStreamAckHandler{} func (s *sendStreamAckHandler) OnAcked(f wire.Frame) { sf := f.(*wire.StreamFrame) sf.PutBack() + s.mutex.Lock() - if s.cancelled { + if s.resetErr != nil && (*SendStream)(s).reliableOffset() == 0 { s.mutex.Unlock() return } @@ -550,7 +673,7 @@ func (s *sendStreamAckHandler) OnAcked(f wire.Frame) { if s.numOutstandingFrames < 0 { panic("numOutStandingFrames negative") } - completed := (*sendStream)(s).isNewlyCompleted() + completed := (*SendStream)(s).isNewlyCompleted() s.mutex.Unlock() if completed { @@ -561,32 +684,65 @@ func (s *sendStreamAckHandler) OnAcked(f wire.Frame) { func (s *sendStreamAckHandler) OnLost(f wire.Frame) { sf := f.(*wire.StreamFrame) s.mutex.Lock() - if s.cancelled { + // If the reliable size was 0 when the stream was cancelled, + // the number of outstanding frames was immediately set to 0, and the retransmission queue was dropped. + if s.resetErr != nil && (*SendStream)(s).reliableOffset() == 0 { + // Return the frame to pool since it won't be retransmitted + sf.PutBack() s.mutex.Unlock() return } - sf.DataLenPresent = true - s.retransmissionQueue = append(s.retransmissionQueue, sf) s.numOutstandingFrames-- if s.numOutstandingFrames < 0 { panic("numOutStandingFrames negative") } + + if s.resetErr != nil && (*SendStream)(s).reliableOffset() > 0 { + // If the stream was reset, and this frame is beyond the reliable offset, + // it doesn't need to be retransmitted. + if sf.Offset >= (*SendStream)(s).reliableOffset() { + sf.PutBack() + // If this frame was the last one tracked, losing it might cause the stream to be completed. + completed := (*SendStream)(s).isNewlyCompleted() + s.mutex.Unlock() + if completed { + s.sender.onStreamCompleted(s.streamID) + } + return + } + // If the payload of the frame extends beyond the reliable size, + // truncate the frame to the reliable size. + if sf.Offset+sf.DataLen() > (*SendStream)(s).reliableOffset() { + sf.Data = sf.Data[:(*SendStream)(s).reliableOffset()-sf.Offset] + } + } + + sf.DataLenPresent = true + s.retransmissionQueue = append(s.retransmissionQueue, sf) s.mutex.Unlock() - s.sender.onHasStreamData(s.streamID, (*sendStream)(s)) + s.sender.onHasStreamData(s.streamID, (*SendStream)(s)) } -type sendStreamResetStreamHandler sendStream +type sendStreamResetStreamHandler SendStream var _ ackhandler.FrameHandler = &sendStreamResetStreamHandler{} -func (s *sendStreamResetStreamHandler) OnAcked(wire.Frame) { +func (s *sendStreamResetStreamHandler) OnAcked(f wire.Frame) { + rsf := f.(*wire.ResetStreamFrame) s.mutex.Lock() + // If the peer sent a STOP_SENDING after we sent a RESET_STREAM_AT frame, + // we sent 1. reduced the reliable size to 0 and 2. sent a RESET_STREAM frame. + // In this case, we don't care about the acknowledgment of this frame. + if rsf.ReliableSize != (*SendStream)(s).reliableOffset() { + s.mutex.Unlock() + return + } s.numOutstandingFrames-- if s.numOutstandingFrames < 0 { panic("numOutStandingFrames negative") } - completed := (*sendStream)(s).isNewlyCompleted() + completed := (*SendStream)(s).isNewlyCompleted() s.mutex.Unlock() if completed { @@ -595,9 +751,17 @@ func (s *sendStreamResetStreamHandler) OnAcked(wire.Frame) { } func (s *sendStreamResetStreamHandler) OnLost(f wire.Frame) { + rsf := f.(*wire.ResetStreamFrame) s.mutex.Lock() - s.queuedResetStreamFrame = f.(*wire.ResetStreamFrame) + // If the peer sent a STOP_SENDING after we sent a RESET_STREAM_AT frame, + // we sent 1. reduced the reliable size to 0 and 2. sent a RESET_STREAM frame. + // In this case, the loss of the RESET_STREAM_AT frame can be ignored. + if rsf.ReliableSize != (*SendStream)(s).reliableOffset() { + s.mutex.Unlock() + return + } + s.queuedResetStreamFrame = rsf s.numOutstandingFrames-- s.mutex.Unlock() - s.sender.onHasStreamControlFrame(s.streamID, (*sendStream)(s)) + s.sender.onHasStreamControlFrame(s.streamID, (*SendStream)(s)) } diff --git a/vendor/github.com/quic-go/quic-go/server.go b/vendor/github.com/quic-go/quic-go/server.go index 3eb8e1d4..7bbf930d 100644 --- a/vendor/github.com/quic-go/quic-go/server.go +++ b/vendor/github.com/quic-go/quic-go/server.go @@ -10,11 +10,13 @@ import ( "time" "github.com/quic-go/quic-go/internal/handshake" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" + "github.com/quic-go/quic-go/qlogwriter" ) // ErrServerClosed is returned by the [Listener] or [EarlyListener]'s Accept method after a call to Close. @@ -32,26 +34,9 @@ type packetHandler interface { closeWithTransportError(qerr.TransportErrorCode) } -type packetHandlerManager interface { - Get(protocol.ConnectionID) (packetHandler, bool) - GetByResetToken(protocol.StatelessResetToken) (packetHandler, bool) - AddWithConnID(destConnID, newConnID protocol.ConnectionID, h packetHandler) bool - Close(error) - connRunner -} - -type quicConn interface { - EarlyConnection - earlyConnReady() <-chan struct{} - handlePacket(receivedPacket) - run() error - destroy(error) - closeWithTransportError(TransportErrorCode) -} - type zeroRTTQueue struct { packets []receivedPacket - expiration time.Time + expiration monotime.Time } type rejectedPacket struct { @@ -61,7 +46,7 @@ type rejectedPacket struct { // A Listener of QUIC type baseServer struct { - tr *Transport + tr *packetHandlerMap disableVersionNegotiation bool acceptEarlyConns bool @@ -79,17 +64,17 @@ type baseServer struct { receivedPackets chan receivedPacket - nextZeroRTTCleanup time.Time + nextZeroRTTCleanup monotime.Time zeroRTTQueues map[protocol.ConnectionID]*zeroRTTQueue // only initialized if acceptEarlyConns == true - connContext func(context.Context) context.Context + connContext func(context.Context, *ClientInfo) (context.Context, error) // set as a member, so they can be set in the tests newConn func( context.Context, context.CancelCauseFunc, sendConn, - *Transport, + connRunner, protocol.ConnectionID, /* original dest connection ID */ *protocol.ConnectionID, /* retry src connection ID */ protocol.ConnectionID, /* client dest connection ID */ @@ -101,10 +86,11 @@ type baseServer struct { *tls.Config, *handshake.TokenGenerator, bool, /* client address validated by an address validation token */ - *logging.ConnectionTracer, + time.Duration, + qlogwriter.Trace, utils.Logger, protocol.Version, - ) quicConn + ) *wrappedConn closeMx sync.Mutex // errorChan is closed when Close is called. This has two effects: @@ -127,9 +113,9 @@ type baseServer struct { verifySourceAddress func(net.Addr) bool - connQueue chan quicConn + connQueue chan *Conn - tracer *logging.Tracer + qlogger qlogwriter.Recorder logger utils.Logger } @@ -141,16 +127,14 @@ type Listener struct { } // Accept returns new connections. It should be called in a loop. -func (l *Listener) Accept(ctx context.Context) (Connection, error) { +func (l *Listener) Accept(ctx context.Context) (*Conn, error) { return l.baseServer.Accept(ctx) } // Close closes the listener. // Accept will return [ErrServerClosed] as soon as all connections in the accept queue have been accepted. // QUIC handshakes that are still in flight will be rejected with a CONNECTION_REFUSED error. -// The effect of closing the listener depends on how it was created: -// - if it was created using [Transport.Listen], already established connections will be unaffected -// - if it was created using the [Listen] convenience method, all established connection will be closed immediately +// Already established (accepted) connections will be unaffected. func (l *Listener) Close() error { return l.baseServer.Close() } @@ -171,11 +155,18 @@ type EarlyListener struct { } // Accept returns a new connections. It should be called in a loop. -func (l *EarlyListener) Accept(ctx context.Context) (EarlyConnection, error) { - return l.baseServer.accept(ctx) +func (l *EarlyListener) Accept(ctx context.Context) (*Conn, error) { + conn, err := l.baseServer.accept(ctx) + if err != nil { + return nil, err + } + return conn, nil } -// Close the server. All active connections will be closed. +// Close closes the listener. +// Accept will return [ErrServerClosed] as soon as all connections in the accept queue have been accepted. +// Early connections that are still in flight will be rejected with a CONNECTION_REFUSED error. +// Already established (accepted) connections will be unaffected. func (l *EarlyListener) Close() error { return l.baseServer.Close() } @@ -247,13 +238,13 @@ func ListenEarly(conn net.PacketConn, tlsConf *tls.Config, config *Config) (*Ear func newServer( conn rawConn, - tr *Transport, + tr *packetHandlerMap, connIDGenerator ConnectionIDGenerator, statelessResetter *statelessResetter, - connContext func(context.Context) context.Context, + connContext func(context.Context, *ClientInfo) (context.Context, error), tlsConf *tls.Config, config *Config, - tracer *logging.Tracer, + qlogger qlogwriter.Recorder, onClose func(), tokenGeneratorKey TokenGeneratorKey, maxTokenAge time.Duration, @@ -272,7 +263,7 @@ func newServer( verifySourceAddress: verifySourceAddress, connIDGenerator: connIDGenerator, statelessResetter: statelessResetter, - connQueue: make(chan quicConn, protocol.MaxAcceptQueueSize), + connQueue: make(chan *Conn, protocol.MaxAcceptQueueSize), errorChan: make(chan struct{}), stopAccepting: make(chan struct{}), running: make(chan struct{}), @@ -282,7 +273,7 @@ func newServer( connectionRefusedQueue: make(chan rejectedPacket, 4), retryQueue: make(chan rejectedPacket, 8), newConn: newConnection, - tracer: tracer, + qlogger: qlogger, logger: utils.DefaultLogger.WithPrefix("server"), acceptEarlyConns: acceptEarly, disableVersionNegotiation: disableVersionNegotiation, @@ -335,11 +326,11 @@ func (s *baseServer) runSendQueue() { // Accept returns connections that already completed the handshake. // It is only valid if acceptEarlyConns is false. -func (s *baseServer) Accept(ctx context.Context) (Connection, error) { +func (s *baseServer) Accept(ctx context.Context) (*Conn, error) { return s.accept(ctx) } -func (s *baseServer) accept(ctx context.Context) (quicConn, error) { +func (s *baseServer) accept(ctx context.Context) (*Conn, error) { select { case <-ctx.Done(): return nil, ctx.Err() @@ -357,11 +348,13 @@ func (s *baseServer) accept(ctx context.Context) (quicConn, error) { } func (s *baseServer) Close() error { - s.close(ErrServerClosed, true) + s.close(ErrServerClosed, false) return nil } -func (s *baseServer) close(e error, notifyOnClose bool) { +// close closes the server. The Transport mutex must not be held while calling this method. +// This method closes any handshaking connections which requires the tranpsort mutex. +func (s *baseServer) close(e error, transportClose bool) { s.closeMx.Lock() if s.closeErr != nil { s.closeMx.Unlock() @@ -372,12 +365,25 @@ func (s *baseServer) close(e error, notifyOnClose bool) { <-s.running s.closeMx.Unlock() - if notifyOnClose { + if !transportClose { s.onClose() } + // wait until all handshakes in flight have terminated s.handshakingCount.Wait() close(s.stopAccepting) + + if transportClose { + // if the transport is closing, drain the connQueue. All connections in the queue + // will be closed by the transport. + for { + select { + case <-s.connQueue: + default: + return + } + } + } } // Addr returns the server's network address @@ -392,8 +398,11 @@ func (s *baseServer) handlePacket(p receivedPacket) { return default: s.logger.Debugf("Dropping packet from %s (%d bytes). Server receive queue full.", p.remoteAddr, p.Size()) - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropDOSPrevention, + }) } } } @@ -405,8 +414,12 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st if wire.IsVersionNegotiationPacket(p.data) { s.logger.Debugf("Dropping Version Negotiation packet.") - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedPacket) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{PacketType: qlog.PacketTypeVersionNegotiation}, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } return false } @@ -418,24 +431,35 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st // drop the packet if we failed to parse the protocol version if err != nil { s.logger.Debugf("Dropping a packet with an unknown version") - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } return false } // send a Version Negotiation Packet if the client is speaking a different protocol version if !protocol.IsSupportedVersion(s.config.Versions, v) { if s.disableVersionNegotiation { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedVersion) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{Version: v}, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedVersion, + }) } return false } if p.Size() < protocol.MinUnknownVersionPacketSize { s.logger.Debugf("Dropping a packet with an unsupported version number %d that is too small (%d bytes)", v, p.Size()) - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{Version: v}, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } return false } @@ -444,8 +468,15 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st if wire.Is0RTTPacket(p.data) { if !s.acceptEarlyConns { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropUnexpectedPacket) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketType0RTT, + PacketNumber: protocol.InvalidPacketNumber, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } return false } @@ -456,16 +487,27 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st // The header will then be parsed again. hdr, _, _, err := wire.ParsePacket(p.data) if err != nil { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropHeaderParseError, + }) } s.logger.Debugf("Error parsing packet: %s", err) return false } if hdr.Type == protocol.PacketTypeInitial && p.Size() < protocol.MinInitialPacketSize { s.logger.Debugf("Dropping a packet that is too small to be a valid Initial (%d bytes)", p.Size()) - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeInitial, + PacketNumber: protocol.InvalidPacketNumber, + Version: v, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } return false } @@ -475,8 +517,27 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st // There's little point in sending a Stateless Reset, since the client // might not have received the token yet. s.logger.Debugf("Dropping long header packet of type %s (%d bytes)", hdr.Type, len(p.data)) - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropUnexpectedPacket) + if s.qlogger != nil { + var pt qlog.PacketType + switch hdr.Type { + case protocol.PacketTypeInitial: + pt = qlog.PacketTypeInitial + case protocol.PacketTypeHandshake: + pt = qlog.PacketTypeHandshake + case protocol.PacketType0RTT: + pt = qlog.PacketType0RTT + case protocol.PacketTypeRetry: + pt = qlog.PacketTypeRetry + } + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: pt, + PacketNumber: protocol.InvalidPacketNumber, + Version: v, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } return false } @@ -494,22 +555,40 @@ func (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer st func (s *baseServer) handle0RTTPacket(p receivedPacket) bool { connID, err := wire.ParseConnectionID(p.data, 0) if err != nil { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropHeaderParseError) + if s.qlogger != nil { + v, _ := wire.ParseVersion(p.data) + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketType0RTT, + PacketNumber: protocol.InvalidPacketNumber, + Version: v, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropHeaderParseError, + }) } return false } // check again if we might have a connection now - if handler, ok := s.tr.connRunner().Get(connID); ok { + if handler, ok := s.tr.Get(connID); ok { handler.handlePacket(p) return true } if q, ok := s.zeroRTTQueues[connID]; ok { if len(q.packets) >= protocol.Max0RTTQueueLen { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention) + if s.qlogger != nil { + v, _ := wire.ParseVersion(p.data) + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketType0RTT, + PacketNumber: protocol.InvalidPacketNumber, + Version: v, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropDOSPrevention, + }) } return false } @@ -518,8 +597,17 @@ func (s *baseServer) handle0RTTPacket(p receivedPacket) bool { } if len(s.zeroRTTQueues) >= protocol.Max0RTTQueues { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention) + if s.qlogger != nil { + v, _ := wire.ParseVersion(p.data) + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketType0RTT, + PacketNumber: protocol.InvalidPacketNumber, + Version: v, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropDOSPrevention, + }) } return false } @@ -534,10 +622,10 @@ func (s *baseServer) handle0RTTPacket(p receivedPacket) bool { return true } -func (s *baseServer) cleanupZeroRTTQueues(now time.Time) { +func (s *baseServer) cleanupZeroRTTQueues(now monotime.Time) { // Iterate over all queues to find those that are expired. // This is ok since we're placing a pretty low limit on the number of queues. - var nextCleanup time.Time + var nextCleanup monotime.Time for connID, q := range s.zeroRTTQueues { if q.expiration.After(now) { if nextCleanup.IsZero() || nextCleanup.After(q.expiration) { @@ -546,8 +634,17 @@ func (s *baseServer) cleanupZeroRTTQueues(now time.Time) { continue } for _, p := range q.packets { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention) + if s.qlogger != nil { + v, _ := wire.ParseVersion(p.data) + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketType0RTT, + PacketNumber: protocol.InvalidPacketNumber, + Version: v, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropDOSPrevention, + }) } p.buffer.Release() } @@ -581,8 +678,16 @@ func (s *baseServer) validateToken(token *handshake.Token, addr net.Addr) bool { func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error { if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeInitial, + PacketNumber: protocol.InvalidPacketNumber, + Version: hdr.Version, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } p.buffer.Release() return errors.New("too short connection ID") @@ -591,7 +696,7 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error // The server queues packets for a while, and we might already have established a connection by now. // This results in a second check in the connection map. // That's ok since it's not the hot path (it's only taken by some Initial and 0-RTT packets). - if handler, ok := s.tr.connRunner().Get(hdr.DestConnectionID); ok { + if handler, ok := s.tr.Get(hdr.DestConnectionID); ok { handler.handlePacket(p) return nil } @@ -647,31 +752,39 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error return nil } + // restore RTT from token + var rtt time.Duration + if token != nil && !token.IsRetryToken { + rtt = token.RTT + } + config := s.config + clientInfo := &ClientInfo{ + RemoteAddr: p.remoteAddr, + AddrVerified: clientAddrVerified, + } if s.config.GetConfigForClient != nil { - conf, err := s.config.GetConfigForClient(&ClientInfo{ - RemoteAddr: p.remoteAddr, - AddrVerified: clientAddrVerified, - }) + conf, err := s.config.GetConfigForClient(clientInfo) if err != nil { s.logger.Debugf("Rejecting new connection due to GetConfigForClient callback") - delete(s.zeroRTTQueues, hdr.DestConnectionID) - select { - case s.connectionRefusedQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: - default: - // drop packet if we can't send out the CONNECTION_REFUSED fast enough - p.buffer.Release() - } + s.refuseNewConn(p, hdr) return nil } config = populateConfig(conf) } - var conn quicConn + var conn *wrappedConn var cancel context.CancelCauseFunc ctx, cancel1 := context.WithCancelCause(context.Background()) if s.connContext != nil { - ctx = s.connContext(ctx) + var err error + ctx, err = s.connContext(ctx, clientInfo) + if err != nil { + cancel1(err) + s.logger.Debugf("Rejecting new connection due to ConnContext callback: %s", err) + s.refuseNewConn(p, hdr) + return nil + } if ctx == nil { panic("quic: ConnContext returned nil") } @@ -687,15 +800,14 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error } else { cancel = cancel1 } - ctx = context.WithValue(ctx, ConnectionTracingKey, nextConnTracingID()) - var tracer *logging.ConnectionTracer + var qlogTrace qlogwriter.Trace if config.Tracer != nil { // Use the same connection ID that is passed to the client's GetLogWriter callback. connID := hdr.DestConnectionID if origDestConnID.Len() > 0 { connID = origDestConnID } - tracer = config.Tracer(ctx, protocol.PerspectiveServer, connID) + qlogTrace = config.Tracer(ctx, false, connID) } connID, err := s.connIDGenerator.GenerateConnectionID() if err != nil { @@ -718,7 +830,8 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error s.tlsConf, s.tokenGenerator, clientAddrVerified, - tracer, + rtt, + qlogTrace, s.logger, hdr.Version, ) @@ -727,9 +840,9 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error // This is very unlikely: Even if an attacker chooses a connection ID that's already in use, // under normal circumstances the packet would just be routed to that connection. // The only time this collision will occur if we receive the two Initial packets at the same time. - if added := s.tr.connRunner().AddWithConnID(hdr.DestConnectionID, connID, conn); !added { + if added := s.tr.AddWithConnID(hdr.DestConnectionID, connID, conn); !added { delete(s.zeroRTTQueues, hdr.DestConnectionID) - conn.closeWithTransportError(qerr.ConnectionRefused) + conn.closeWithTransportError(ConnectionRefused) return nil } // Pass queued 0-RTT to the newly established connection. @@ -749,7 +862,17 @@ func (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error return nil } -func (s *baseServer) handleNewConn(conn quicConn) { +func (s *baseServer) refuseNewConn(p receivedPacket, hdr *wire.Header) { + delete(s.zeroRTTQueues, hdr.DestConnectionID) + select { + case s.connectionRefusedQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}: + default: + // drop packet if we can't send out the CONNECTION_REFUSED fast enough + p.buffer.Release() + } +} + +func (s *baseServer) handleNewConn(conn *wrappedConn) { if s.acceptEarlyConns { // wait until the early connection is ready, the handshake fails, or the server is closed select { @@ -773,7 +896,7 @@ func (s *baseServer) handleNewConn(conn quicConn) { } select { - case s.connQueue <- conn: + case s.connQueue <- conn.Conn: default: conn.closeWithTransportError(ConnectionRefused) } @@ -819,8 +942,20 @@ func (s *baseServer) sendRetryPacket(p rejectedPacket) error { // append the Retry integrity tag tag := handshake.GetRetryIntegrityTag(buf.Data, hdr.DestConnectionID, hdr.Version) buf.Data = append(buf.Data, tag[:]...) - if s.tracer != nil && s.tracer.SentPacket != nil { - s.tracer.SentPacket(p.remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketSent{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeRetry, + SrcConnectionID: replyHdr.SrcConnectionID, + DestConnectionID: replyHdr.DestConnectionID, + Version: replyHdr.Version, + Token: &qlog.Token{Raw: token}, + }, + Raw: qlog.RawInfo{ + Length: len(buf.Data), + PayloadLength: int(replyHdr.Length), + }, + }) } _, err = s.conn.WritePacket(buf.Data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported) return err @@ -838,22 +973,37 @@ func (s *baseServer) maybeSendInvalidToken(p rejectedPacket) { // Only send INVALID_TOKEN if we can unprotect the packet. // This makes sure that we won't send it for packets that were corrupted. if err != nil { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropHeaderParseError) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeInitial, + PacketNumber: protocol.InvalidPacketNumber, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropHeaderParseError, + }) } return } hdrLen := extHdr.ParsedLen() if _, err := opener.Open(data[hdrLen:hdrLen], data[hdrLen:], extHdr.PacketNumber, data[:hdrLen]); err != nil { - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropPayloadDecryptError) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeInitial, + PacketNumber: protocol.InvalidPacketNumber, + Version: hdr.Version, + }, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropPayloadDecryptError, + }) } return } if s.logger.Debug() { s.logger.Debugf("Client sent an invalid retry token. Sending INVALID_TOKEN to %s.", p.remoteAddr) } - if err := s.sendError(p.remoteAddr, hdr, sealer, qerr.InvalidToken, p.info); err != nil { + if err := s.sendError(p.remoteAddr, hdr, sealer, InvalidToken, p.info); err != nil { s.logger.Debugf("Error sending INVALID_TOKEN error: %s", err) } } @@ -861,7 +1011,7 @@ func (s *baseServer) maybeSendInvalidToken(p rejectedPacket) { func (s *baseServer) sendConnectionRefused(p rejectedPacket) { defer p.buffer.Release() sealer, _ := handshake.NewInitialAEAD(p.hdr.DestConnectionID, protocol.PerspectiveServer, p.hdr.Version) - if err := s.sendError(p.remoteAddr, p.hdr, sealer, qerr.ConnectionRefused, p.info); err != nil { + if err := s.sendError(p.remoteAddr, p.hdr, sealer, ConnectionRefused, p.info); err != nil { s.logger.Debugf("Error sending CONNECTION_REFUSED error: %s", err) } } @@ -904,8 +1054,21 @@ func (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer han replyHdr.Log(s.logger) wire.LogFrame(s.logger, ccf, true) - if s.tracer != nil && s.tracer.SentPacket != nil { - s.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(b.Data)), []logging.Frame{ccf}) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketSent{ + Header: qlog.PacketHeader{ + PacketType: qlog.PacketTypeInitial, + SrcConnectionID: replyHdr.SrcConnectionID, + DestConnectionID: replyHdr.DestConnectionID, + PacketNumber: replyHdr.PacketNumber, + Version: replyHdr.Version, + }, + Raw: qlog.RawInfo{ + Length: len(b.Data), + PayloadLength: int(replyHdr.Length), + }, + Frames: []qlog.Frame{{Frame: ccf}}, + }) } _, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB(), 0, protocol.ECNUnsupported) return err @@ -933,8 +1096,11 @@ func (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) { _, src, dest, err := wire.ParseArbitraryLenConnectionIDs(p.data) if err != nil { // should never happen s.logger.Debugf("Dropping a packet with an unknown version for which we failed to parse connection IDs") - if s.tracer != nil && s.tracer.DroppedPacket != nil { - s.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnexpectedPacket, + }) } return } @@ -942,8 +1108,14 @@ func (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) { s.logger.Debugf("Client offered version %s, sending Version Negotiation", v) data := wire.ComposeVersionNegotiation(dest, src, s.config.Versions) - if s.tracer != nil && s.tracer.SentVersionNegotiationPacket != nil { - s.tracer.SentVersionNegotiationPacket(p.remoteAddr, src, dest, s.config.Versions) + if s.qlogger != nil { + s.qlogger.RecordEvent(qlog.VersionNegotiationSent{ + Header: qlog.PacketHeaderVersionNegotiation{ + SrcConnectionID: src, + DestConnectionID: dest, + }, + SupportedVersions: s.config.Versions, + }) } if _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported); err != nil { s.logger.Debugf("Error sending Version Negotiation: %s", err) diff --git a/vendor/github.com/quic-go/quic-go/sni.go b/vendor/github.com/quic-go/quic-go/sni.go new file mode 100644 index 00000000..f63023f9 --- /dev/null +++ b/vendor/github.com/quic-go/quic-go/sni.go @@ -0,0 +1,136 @@ +package quic + +import ( + "encoding/binary" + "errors" + "io" +) + +const ( + extTypeSNI = 0 + extTypeECH = 0xfe0d +) + +// findSNIAndECH parses the given byte slice as a ClientHello, and locates: +// - the position and length of the Server Name Indication (SNI) extension, +// - the position of the Encrypted Client Hello (ECH) extension. +// If no SNI extension is found, it returns -1 for the SNI position. +// If no ECH extension is found, it returns -1 for the ECH position. +func findSNIAndECH(data []byte) (sniPos, sniLen, echPos int, err error) { + if len(data) < 4 { + return 0, 0, 0, io.ErrUnexpectedEOF + } + if data[0] != 1 { + return 0, 0, 0, errors.New("not a ClientHello") + } + handshakeLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) + if len(data) != 4+handshakeLen { + return 0, 0, 0, io.ErrUnexpectedEOF + } + + parsePos := 4 + // Skip protocol version (2 bytes) + if parsePos+2 > len(data) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + parsePos += 2 + // skip random (32 bytes) + if parsePos+32 > len(data) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + parsePos += 32 + // session ID + if parsePos+1 > len(data) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + sessionIDLen := int(data[parsePos]) + parsePos++ + if parsePos+sessionIDLen > len(data) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + parsePos += sessionIDLen + // cipher suites + if parsePos+2 > len(data) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + cipherSuitesLen := int(binary.BigEndian.Uint16(data[parsePos:])) + parsePos += 2 + if parsePos+cipherSuitesLen > len(data) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + parsePos += cipherSuitesLen + // compression methods + if parsePos+1 > len(data) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + compressionMethodsLen := int(data[parsePos]) + parsePos++ + if parsePos+compressionMethodsLen > len(data) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + parsePos += compressionMethodsLen + + // extensions + if parsePos+2 > len(data) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + extensionsLen := int(binary.BigEndian.Uint16(data[parsePos:])) + parsePos += 2 + if parsePos+extensionsLen > len(data) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + extensionsStart := parsePos + extensions := data[extensionsStart : extensionsStart+extensionsLen] + + // parse extensions + var extPos int + sniPos = -1 + echPos = -1 + for extPos+4 <= extensionsLen { + extType := binary.BigEndian.Uint16(extensions[extPos:]) + extLen := int(binary.BigEndian.Uint16(extensions[extPos+2:])) + if extPos+4+extLen > extensionsLen { + return 0, 0, 0, io.ErrUnexpectedEOF + } + switch extType { + case extTypeSNI: + if sniPos != -1 { + return 0, 0, 0, errors.New("multiple SNI extensions") + } + sniData := extensions[extPos+4 : extPos+4+extLen] + if len(sniData) < 2 { + return 0, 0, 0, io.ErrUnexpectedEOF + } + nameListLen := int(binary.BigEndian.Uint16(sniData)) + if len(sniData) != 2+nameListLen { + return 0, 0, 0, io.ErrUnexpectedEOF + } + listPos := 2 + for listPos+3 <= nameListLen+2 { + nameType := sniData[listPos] + sniLen = int(binary.BigEndian.Uint16(sniData[listPos+1:])) + if listPos+3+sniLen > len(sniData) { + return 0, 0, 0, io.ErrUnexpectedEOF + } + if nameType == 0 { // host_name + sniPos = extensionsStart + extPos + 4 + listPos + 3 + break // stop after first host_name + } + listPos += 3 + sniLen + } + if sniPos == 0 { + return 0, 0, 0, errors.New("SNI host_name not found") + } + case extTypeECH: + if echPos != -1 { + return 0, 0, 0, errors.New("multiple ECH extensions") + } + echPos = extensionsStart + extPos + } + extPos += 4 + extLen + if sniPos != -1 && echPos != -1 { + break + } + } + return sniPos, sniLen, echPos, nil +} diff --git a/vendor/github.com/quic-go/quic-go/stream.go b/vendor/github.com/quic-go/quic-go/stream.go index 9cd2695d..7248f76e 100644 --- a/vendor/github.com/quic-go/quic-go/stream.go +++ b/vendor/github.com/quic-go/quic-go/stream.go @@ -9,6 +9,7 @@ import ( "github.com/quic-go/quic-go/internal/ackhandler" "github.com/quic-go/quic-go/internal/flowcontrol" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/wire" ) @@ -25,7 +26,7 @@ var errDeadline net.Error = &deadlineError{} // The streamSender is notified by the stream about various events. type streamSender interface { onHasConnectionData() - onHasStreamData(protocol.StreamID, sendStreamI) + onHasStreamData(protocol.StreamID, *SendStream) onHasStreamControlFrame(protocol.StreamID, streamControlFrameGetter) // must be called without holding the mutex that is acquired by closeForShutdown onStreamCompleted(protocol.StreamID) @@ -39,7 +40,7 @@ type uniStreamSender struct { onHasStreamControlFrameImpl func(protocol.StreamID, streamControlFrameGetter) } -func (s *uniStreamSender) onHasStreamData(id protocol.StreamID, str sendStreamI) { +func (s *uniStreamSender) onHasStreamData(id protocol.StreamID, str *SendStream) { s.streamSender.onHasStreamData(id, str) } func (s *uniStreamSender) onStreamCompleted(protocol.StreamID) { s.onStreamCompletedImpl() } @@ -49,30 +50,9 @@ func (s *uniStreamSender) onHasStreamControlFrame(id protocol.StreamID, str stre var _ streamSender = &uniStreamSender{} -type streamI interface { - Stream - closeForShutdown(error) - // for receiving - handleStreamFrame(*wire.StreamFrame, time.Time) error - handleResetStreamFrame(*wire.ResetStreamFrame, time.Time) error - // for sending - hasData() bool - handleStopSendingFrame(*wire.StopSendingFrame) - popStreamFrame(protocol.ByteCount, protocol.Version) (_ ackhandler.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMore bool) - updateSendWindow(protocol.ByteCount) -} - -var ( - _ receiveStreamI = (streamI)(nil) - _ sendStreamI = (streamI)(nil) -) - -// A Stream assembles the data from StreamFrames and provides a super-convenient Read-Interface -// -// Read() and Write() may be called concurrently, but multiple calls to Read() or Write() individually must be synchronized manually. -type stream struct { - receiveStream - sendStream +type Stream struct { + receiveStr *ReceiveStream + sendStr *SendStream completedMutex sync.Mutex sender streamSender @@ -81,8 +61,9 @@ type stream struct { } var ( - _ Stream = &stream{} - _ streamControlFrameGetter = &receiveStream{} + _ outgoingStream = &Stream{} + _ sendStreamFrameHandler = &Stream{} + _ receiveStreamFrameHandler = &Stream{} ) // newStream creates a new Stream @@ -91,8 +72,9 @@ func newStream( streamID protocol.StreamID, sender streamSender, flowController flowcontrol.StreamFlowController, -) *stream { - s := &stream{sender: sender} + supportsResetStreamAt bool, +) *Stream { + s := &Stream{sender: sender} senderForSendStream := &uniStreamSender{ streamSender: sender, onStreamCompletedImpl: func() { @@ -105,7 +87,7 @@ func newStream( sender.onHasStreamControlFrame(streamID, s) }, } - s.sendStream = *newSendStream(ctx, streamID, senderForSendStream, flowController) + s.sendStr = newSendStream(ctx, streamID, senderForSendStream, flowController, supportsResetStreamAt) senderForReceiveStream := &uniStreamSender{ streamSender: sender, onStreamCompletedImpl: func() { @@ -118,45 +100,134 @@ func newStream( sender.onHasStreamControlFrame(streamID, s) }, } - s.receiveStream = *newReceiveStream(streamID, senderForReceiveStream, flowController) + s.receiveStr = newReceiveStream(streamID, senderForReceiveStream, flowController) return s } -// need to define StreamID() here, since both receiveStream and readStream have a StreamID() -func (s *stream) StreamID() protocol.StreamID { +// StreamID returns the stream ID. +func (s *Stream) StreamID() protocol.StreamID { // the result is same for receiveStream and sendStream - return s.sendStream.StreamID() + return s.sendStr.StreamID() } -func (s *stream) Close() error { - return s.sendStream.Close() +// Read reads data from the stream. +// Read can be made to time out using [Stream.SetReadDeadline] and [Stream.SetDeadline]. +// If the stream was canceled, the error is a [StreamError]. +func (s *Stream) Read(p []byte) (int, error) { + return s.receiveStr.Read(p) } -func (s *stream) getControlFrame(now time.Time) (_ ackhandler.Frame, ok, hasMore bool) { - f, ok, _ := s.sendStream.getControlFrame(now) +// Peek fills b with stream data, without consuming the stream data. +// It blocks until len(b) bytes are available, or an error occurs. +// It respects the stream deadline set by SetReadDeadline. +// If the stream ends before len(b) bytes are available, +// it returns the number of bytes peeked along with io.EOF. +func (s *Stream) Peek(b []byte) (int, error) { + return s.receiveStr.Peek(b) +} + +// Write writes data to the stream. +// Write can be made to time out using [Stream.SetWriteDeadline] or [Stream.SetDeadline]. +// If the stream was canceled, the error is a [StreamError]. +func (s *Stream) Write(p []byte) (int, error) { + return s.sendStr.Write(p) +} + +// SetReliableBoundary marks the data written to this stream so far as reliable. +// It is valid to call this function multiple times, thereby increasing the reliable size. +// It only has an effect if the peer enabled support for the RESET_STREAM_AT extension, +// otherwise, it is a no-op. +func (s *Stream) SetReliableBoundary() { + s.sendStr.SetReliableBoundary() +} + +// CancelWrite aborts sending on this stream. +// See [SendStream.CancelWrite] for more details. +func (s *Stream) CancelWrite(errorCode StreamErrorCode) { + s.sendStr.CancelWrite(errorCode) +} + +// CancelRead aborts receiving on this stream. +// See [ReceiveStream.CancelRead] for more details. +func (s *Stream) CancelRead(errorCode StreamErrorCode) { + s.receiveStr.CancelRead(errorCode) +} + +// The Context is canceled as soon as the write-side of the stream is closed. +// See [SendStream.Context] for more details. +func (s *Stream) Context() context.Context { + return s.sendStr.Context() +} + +// Close closes the send-direction of the stream. +// It does not close the receive-direction of the stream. +func (s *Stream) Close() error { + return s.sendStr.Close() +} + +func (s *Stream) handleResetStreamFrame(frame *wire.ResetStreamFrame, rcvTime monotime.Time) error { + return s.receiveStr.handleResetStreamFrame(frame, rcvTime) +} + +func (s *Stream) handleStreamFrame(frame *wire.StreamFrame, rcvTime monotime.Time) error { + return s.receiveStr.handleStreamFrame(frame, rcvTime) +} + +func (s *Stream) handleStopSendingFrame(frame *wire.StopSendingFrame) { + s.sendStr.handleStopSendingFrame(frame) +} + +func (s *Stream) updateSendWindow(limit protocol.ByteCount) { + s.sendStr.updateSendWindow(limit) +} + +func (s *Stream) enableResetStreamAt() { + s.sendStr.enableResetStreamAt() +} + +func (s *Stream) popStreamFrame(maxBytes protocol.ByteCount, v protocol.Version) (_ ackhandler.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMore bool) { + return s.sendStr.popStreamFrame(maxBytes, v) +} + +func (s *Stream) getControlFrame(now monotime.Time) (_ ackhandler.Frame, ok, hasMore bool) { + f, ok, _ := s.sendStr.getControlFrame(now) if ok { return f, true, true } - return s.receiveStream.getControlFrame(now) + return s.receiveStr.getControlFrame(now) } -func (s *stream) SetDeadline(t time.Time) error { - _ = s.SetReadDeadline(t) // SetReadDeadline never errors - _ = s.SetWriteDeadline(t) // SetWriteDeadline never errors +// SetReadDeadline sets the deadline for future Read calls. +// See [ReceiveStream.SetReadDeadline] for more details. +func (s *Stream) SetReadDeadline(t time.Time) error { + return s.receiveStr.SetReadDeadline(t) +} + +// SetWriteDeadline sets the deadline for future Write calls. +// See [SendStream.SetWriteDeadline] for more details. +func (s *Stream) SetWriteDeadline(t time.Time) error { + return s.sendStr.SetWriteDeadline(t) +} + +// SetDeadline sets the read and write deadlines associated with the stream. +// It is equivalent to calling both SetReadDeadline and SetWriteDeadline. +func (s *Stream) SetDeadline(t time.Time) error { + _ = s.receiveStr.SetReadDeadline(t) // SetReadDeadline never errors + _ = s.sendStr.SetWriteDeadline(t) // SetWriteDeadline never errors return nil } // CloseForShutdown closes a stream abruptly. // It makes Read and Write unblock (and return the error) immediately. // The peer will NOT be informed about this: the stream is closed without sending a FIN or RST. -func (s *stream) closeForShutdown(err error) { - s.sendStream.closeForShutdown(err) - s.receiveStream.closeForShutdown(err) +func (s *Stream) closeForShutdown(err error) { + s.sendStr.closeForShutdown(err) + s.receiveStr.closeForShutdown(err) } // checkIfCompleted is called from the uniStreamSender, when one of the stream halves is completed. // It makes sure that the onStreamCompleted callback is only called if both receive and send side have completed. -func (s *stream) checkIfCompleted() { +func (s *Stream) checkIfCompleted() { if s.sendStreamCompleted && s.receiveStreamCompleted { s.sender.onStreamCompleted(s.StreamID()) } diff --git a/vendor/github.com/quic-go/quic-go/streams_map.go b/vendor/github.com/quic-go/quic-go/streams_map.go index 510b3e59..92023ac2 100644 --- a/vendor/github.com/quic-go/quic-go/streams_map.go +++ b/vendor/github.com/quic-go/quic-go/streams_map.go @@ -6,33 +6,13 @@ import ( "sync" "github.com/quic-go/quic-go/internal/flowcontrol" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/wire" ) -type streamError struct { - message string - nums []protocol.StreamNum -} - -func (e streamError) Error() string { - return e.message -} - -func convertStreamError(err error, stype protocol.StreamType, pers protocol.Perspective) error { - strError, ok := err.(streamError) - if !ok { - return err - } - ids := make([]interface{}, len(strError.nums)) - for i, num := range strError.nums { - ids[i] = num.StreamID(stype, pers) - } - return fmt.Errorf(strError.Error(), ids...) -} - -// StreamLimitReachedError is returned from Connection.OpenStream and Connection.OpenUniStream +// StreamLimitReachedError is returned from Conn.OpenStream and Conn.OpenUniStream // when it is not possible to open a new stream because the number of opens streams reached // the peer's stream limit. type StreamLimitReachedError struct{} @@ -50,16 +30,15 @@ type streamsMap struct { queueControlFrame func(wire.Frame) newFlowController func(protocol.StreamID) flowcontrol.StreamFlowController - mutex sync.Mutex - outgoingBidiStreams *outgoingStreamsMap[streamI] - outgoingUniStreams *outgoingStreamsMap[sendStreamI] - incomingBidiStreams *incomingStreamsMap[streamI] - incomingUniStreams *incomingStreamsMap[receiveStreamI] - reset bool + mutex sync.Mutex + outgoingBidiStreams *outgoingStreamsMap[*Stream] + outgoingUniStreams *outgoingStreamsMap[*SendStream] + incomingBidiStreams *incomingStreamsMap[*Stream] + incomingUniStreams *incomingStreamsMap[*ReceiveStream] + reset bool + supportsResetStreamAt bool } -var _ streamManager = &streamsMap{} - func newStreamsMap( ctx context.Context, sender streamSender, @@ -85,41 +64,41 @@ func newStreamsMap( func (m *streamsMap) initMaps() { m.outgoingBidiStreams = newOutgoingStreamsMap( protocol.StreamTypeBidi, - func(num protocol.StreamNum) streamI { - id := num.StreamID(protocol.StreamTypeBidi, m.perspective) - return newStream(m.ctx, id, m.sender, m.newFlowController(id)) + func(id protocol.StreamID) *Stream { + return newStream(m.ctx, id, m.sender, m.newFlowController(id), m.supportsResetStreamAt) }, m.queueControlFrame, + m.perspective, ) m.incomingBidiStreams = newIncomingStreamsMap( protocol.StreamTypeBidi, - func(num protocol.StreamNum) streamI { - id := num.StreamID(protocol.StreamTypeBidi, m.perspective.Opposite()) - return newStream(m.ctx, id, m.sender, m.newFlowController(id)) + func(id protocol.StreamID) *Stream { + return newStream(m.ctx, id, m.sender, m.newFlowController(id), m.supportsResetStreamAt) }, m.maxIncomingBidiStreams, m.queueControlFrame, + m.perspective, ) m.outgoingUniStreams = newOutgoingStreamsMap( protocol.StreamTypeUni, - func(num protocol.StreamNum) sendStreamI { - id := num.StreamID(protocol.StreamTypeUni, m.perspective) - return newSendStream(m.ctx, id, m.sender, m.newFlowController(id)) + func(id protocol.StreamID) *SendStream { + return newSendStream(m.ctx, id, m.sender, m.newFlowController(id), m.supportsResetStreamAt) }, m.queueControlFrame, + m.perspective, ) m.incomingUniStreams = newIncomingStreamsMap( protocol.StreamTypeUni, - func(num protocol.StreamNum) receiveStreamI { - id := num.StreamID(protocol.StreamTypeUni, m.perspective.Opposite()) + func(id protocol.StreamID) *ReceiveStream { return newReceiveStream(id, m.sender, m.newFlowController(id)) }, m.maxIncomingUniStreams, m.queueControlFrame, + m.perspective, ) } -func (m *streamsMap) OpenStream() (Stream, error) { +func (m *streamsMap) OpenStream() (*Stream, error) { m.mutex.Lock() reset := m.reset mm := m.outgoingBidiStreams @@ -127,11 +106,10 @@ func (m *streamsMap) OpenStream() (Stream, error) { if reset { return nil, Err0RTTRejected } - str, err := mm.OpenStream() - return str, convertStreamError(err, protocol.StreamTypeBidi, m.perspective) + return mm.OpenStream() } -func (m *streamsMap) OpenStreamSync(ctx context.Context) (Stream, error) { +func (m *streamsMap) OpenStreamSync(ctx context.Context) (*Stream, error) { m.mutex.Lock() reset := m.reset mm := m.outgoingBidiStreams @@ -139,11 +117,10 @@ func (m *streamsMap) OpenStreamSync(ctx context.Context) (Stream, error) { if reset { return nil, Err0RTTRejected } - str, err := mm.OpenStreamSync(ctx) - return str, convertStreamError(err, protocol.StreamTypeBidi, m.perspective) + return mm.OpenStreamSync(ctx) } -func (m *streamsMap) OpenUniStream() (SendStream, error) { +func (m *streamsMap) OpenUniStream() (*SendStream, error) { m.mutex.Lock() reset := m.reset mm := m.outgoingUniStreams @@ -151,11 +128,10 @@ func (m *streamsMap) OpenUniStream() (SendStream, error) { if reset { return nil, Err0RTTRejected } - str, err := mm.OpenStream() - return str, convertStreamError(err, protocol.StreamTypeBidi, m.perspective) + return mm.OpenStream() } -func (m *streamsMap) OpenUniStreamSync(ctx context.Context) (SendStream, error) { +func (m *streamsMap) OpenUniStreamSync(ctx context.Context) (*SendStream, error) { m.mutex.Lock() reset := m.reset mm := m.outgoingUniStreams @@ -163,11 +139,10 @@ func (m *streamsMap) OpenUniStreamSync(ctx context.Context) (SendStream, error) if reset { return nil, Err0RTTRejected } - str, err := mm.OpenStreamSync(ctx) - return str, convertStreamError(err, protocol.StreamTypeUni, m.perspective) + return mm.OpenStreamSync(ctx) } -func (m *streamsMap) AcceptStream(ctx context.Context) (Stream, error) { +func (m *streamsMap) AcceptStream(ctx context.Context) (*Stream, error) { m.mutex.Lock() reset := m.reset mm := m.incomingBidiStreams @@ -175,11 +150,10 @@ func (m *streamsMap) AcceptStream(ctx context.Context) (Stream, error) { if reset { return nil, Err0RTTRejected } - str, err := mm.AcceptStream(ctx) - return str, convertStreamError(err, protocol.StreamTypeBidi, m.perspective.Opposite()) + return mm.AcceptStream(ctx) } -func (m *streamsMap) AcceptUniStream(ctx context.Context) (ReceiveStream, error) { +func (m *streamsMap) AcceptUniStream(ctx context.Context) (*ReceiveStream, error) { m.mutex.Lock() reset := m.reset mm := m.incomingUniStreams @@ -187,91 +161,21 @@ func (m *streamsMap) AcceptUniStream(ctx context.Context) (ReceiveStream, error) if reset { return nil, Err0RTTRejected } - str, err := mm.AcceptStream(ctx) - return str, convertStreamError(err, protocol.StreamTypeUni, m.perspective.Opposite()) + return mm.AcceptStream(ctx) } func (m *streamsMap) DeleteStream(id protocol.StreamID) error { - num := id.StreamNum() switch id.Type() { case protocol.StreamTypeUni: if id.InitiatedBy() == m.perspective { - return convertStreamError(m.outgoingUniStreams.DeleteStream(num), protocol.StreamTypeUni, m.perspective) + return m.outgoingUniStreams.DeleteStream(id) } - return convertStreamError(m.incomingUniStreams.DeleteStream(num), protocol.StreamTypeUni, m.perspective.Opposite()) + return m.incomingUniStreams.DeleteStream(id) case protocol.StreamTypeBidi: if id.InitiatedBy() == m.perspective { - return convertStreamError(m.outgoingBidiStreams.DeleteStream(num), protocol.StreamTypeBidi, m.perspective) + return m.outgoingBidiStreams.DeleteStream(id) } - return convertStreamError(m.incomingBidiStreams.DeleteStream(num), protocol.StreamTypeBidi, m.perspective.Opposite()) - } - panic("") -} - -func (m *streamsMap) GetOrOpenReceiveStream(id protocol.StreamID) (receiveStreamI, error) { - str, err := m.getOrOpenReceiveStream(id) - if err != nil { - return nil, &qerr.TransportError{ - ErrorCode: qerr.StreamStateError, - ErrorMessage: err.Error(), - } - } - return str, nil -} - -func (m *streamsMap) getOrOpenReceiveStream(id protocol.StreamID) (receiveStreamI, error) { - num := id.StreamNum() - switch id.Type() { - case protocol.StreamTypeUni: - if id.InitiatedBy() == m.perspective { - // an outgoing unidirectional stream is a send stream, not a receive stream - return nil, fmt.Errorf("peer attempted to open receive stream %d", id) - } - str, err := m.incomingUniStreams.GetOrOpenStream(num) - return str, convertStreamError(err, protocol.StreamTypeUni, m.perspective) - case protocol.StreamTypeBidi: - var str receiveStreamI - var err error - if id.InitiatedBy() == m.perspective { - str, err = m.outgoingBidiStreams.GetStream(num) - } else { - str, err = m.incomingBidiStreams.GetOrOpenStream(num) - } - return str, convertStreamError(err, protocol.StreamTypeBidi, id.InitiatedBy()) - } - panic("") -} - -func (m *streamsMap) GetOrOpenSendStream(id protocol.StreamID) (sendStreamI, error) { - str, err := m.getOrOpenSendStream(id) - if err != nil { - return nil, &qerr.TransportError{ - ErrorCode: qerr.StreamStateError, - ErrorMessage: err.Error(), - } - } - return str, nil -} - -func (m *streamsMap) getOrOpenSendStream(id protocol.StreamID) (sendStreamI, error) { - num := id.StreamNum() - switch id.Type() { - case protocol.StreamTypeUni: - if id.InitiatedBy() == m.perspective { - str, err := m.outgoingUniStreams.GetStream(num) - return str, convertStreamError(err, protocol.StreamTypeUni, m.perspective) - } - // an incoming unidirectional stream is a receive stream, not a send stream - return nil, fmt.Errorf("peer attempted to open send stream %d", id) - case protocol.StreamTypeBidi: - var str sendStreamI - var err error - if id.InitiatedBy() == m.perspective { - str, err = m.outgoingBidiStreams.GetStream(num) - } else { - str, err = m.incomingBidiStreams.GetOrOpenStream(num) - } - return str, convertStreamError(err, protocol.StreamTypeBidi, id.InitiatedBy()) + return m.incomingBidiStreams.DeleteStream(id) } panic("") } @@ -279,17 +183,148 @@ func (m *streamsMap) getOrOpenSendStream(id protocol.StreamID) (sendStreamI, err func (m *streamsMap) HandleMaxStreamsFrame(f *wire.MaxStreamsFrame) { switch f.Type { case protocol.StreamTypeUni: - m.outgoingUniStreams.SetMaxStream(f.MaxStreamNum) + m.outgoingUniStreams.SetMaxStream(f.MaxStreamNum.StreamID(protocol.StreamTypeUni, m.perspective)) case protocol.StreamTypeBidi: - m.outgoingBidiStreams.SetMaxStream(f.MaxStreamNum) + m.outgoingBidiStreams.SetMaxStream(f.MaxStreamNum.StreamID(protocol.StreamTypeBidi, m.perspective)) } } -func (m *streamsMap) UpdateLimits(p *wire.TransportParameters) { +type sendStreamFrameHandler interface { + updateSendWindow(protocol.ByteCount) + handleStopSendingFrame(*wire.StopSendingFrame) +} + +func (m *streamsMap) getSendStream(id protocol.StreamID) (sendStreamFrameHandler, error) { + switch id.Type() { + case protocol.StreamTypeUni: + if id.InitiatedBy() != m.perspective { + // an outgoing unidirectional stream is a send stream, not a receive stream + return nil, &qerr.TransportError{ + ErrorCode: qerr.StreamStateError, + ErrorMessage: fmt.Sprintf("invalid frame for send stream %d", id), + } + } + str, err := m.outgoingUniStreams.GetStream(id) + if str == nil || err != nil { + return nil, err + } + return str, nil + case protocol.StreamTypeBidi: + if id.InitiatedBy() == m.perspective { + str, err := m.outgoingBidiStreams.GetStream(id) + if str == nil || err != nil { + return nil, err + } + return str, nil + } + str, err := m.incomingBidiStreams.GetOrOpenStream(id) + if str == nil || err != nil { + return nil, err + } + return str, nil + } + panic("unreachable") +} + +func (m *streamsMap) HandleMaxStreamDataFrame(f *wire.MaxStreamDataFrame) error { + str, err := m.getSendStream(f.StreamID) + if err != nil { + return err + } + if str == nil { // stream already deleted + return nil + } + str.updateSendWindow(f.MaximumStreamData) + return nil +} + +func (m *streamsMap) HandleStopSendingFrame(f *wire.StopSendingFrame) error { + str, err := m.getSendStream(f.StreamID) + if err != nil { + return err + } + if str == nil { // stream already deleted + return nil + } + str.handleStopSendingFrame(f) + return nil +} + +type receiveStreamFrameHandler interface { + handleResetStreamFrame(*wire.ResetStreamFrame, monotime.Time) error + handleStreamFrame(*wire.StreamFrame, monotime.Time) error +} + +func (m *streamsMap) getReceiveStream(id protocol.StreamID) (receiveStreamFrameHandler, error) { + switch id.Type() { + case protocol.StreamTypeUni: + // an outgoing unidirectional stream is a send stream, not a receive stream + if id.InitiatedBy() == m.perspective { + return nil, &qerr.TransportError{ + ErrorCode: qerr.StreamStateError, + ErrorMessage: fmt.Sprintf("invalid frame for receive stream %d", id), + } + } + str, err := m.incomingUniStreams.GetOrOpenStream(id) + if err != nil || str == nil { + return nil, err + } + return str, nil + case protocol.StreamTypeBidi: + var str *Stream + var err error + if id.InitiatedBy() == m.perspective { + str, err = m.outgoingBidiStreams.GetStream(id) + } else { + str, err = m.incomingBidiStreams.GetOrOpenStream(id) + } + if str == nil || err != nil { + return nil, err + } + return str, nil + } + panic("unreachable") +} + +func (m *streamsMap) HandleStreamDataBlockedFrame(f *wire.StreamDataBlockedFrame) error { + if _, err := m.getReceiveStream(f.StreamID); err != nil { + return err + } + // We don't need to do anything in response to a STREAM_DATA_BLOCKED frame, + // but we need to make sure that the stream ID is valid. + return nil // we don't need to do anything in response to a STREAM_DATA_BLOCKED frame +} + +func (m *streamsMap) HandleResetStreamFrame(f *wire.ResetStreamFrame, rcvTime monotime.Time) error { + str, err := m.getReceiveStream(f.StreamID) + if err != nil { + return err + } + if str == nil { // stream already deleted + return nil + } + return str.handleResetStreamFrame(f, rcvTime) +} + +func (m *streamsMap) HandleStreamFrame(f *wire.StreamFrame, rcvTime monotime.Time) error { + str, err := m.getReceiveStream(f.StreamID) + if err != nil { + return err + } + if str == nil { // stream already deleted + return nil + } + return str.handleStreamFrame(f, rcvTime) +} + +func (m *streamsMap) HandleTransportParameters(p *wire.TransportParameters) { + m.supportsResetStreamAt = p.EnableResetStreamAt + m.outgoingBidiStreams.EnableResetStreamAt() + m.outgoingUniStreams.EnableResetStreamAt() m.outgoingBidiStreams.UpdateSendWindow(p.InitialMaxStreamDataBidiRemote) - m.outgoingBidiStreams.SetMaxStream(p.MaxBidiStreamNum) + m.outgoingBidiStreams.SetMaxStream(p.MaxBidiStreamNum.StreamID(protocol.StreamTypeBidi, m.perspective)) m.outgoingUniStreams.UpdateSendWindow(p.InitialMaxStreamDataUni) - m.outgoingUniStreams.SetMaxStream(p.MaxUniStreamNum) + m.outgoingUniStreams.SetMaxStream(p.MaxUniStreamNum.StreamID(protocol.StreamTypeUni, m.perspective)) } func (m *streamsMap) CloseWithError(err error) { diff --git a/vendor/github.com/quic-go/quic-go/streams_map_incoming.go b/vendor/github.com/quic-go/quic-go/streams_map_incoming.go index 18ec6f99..c714eaf1 100644 --- a/vendor/github.com/quic-go/quic-go/streams_map_incoming.go +++ b/vendor/github.com/quic-go/quic-go/streams_map_incoming.go @@ -2,9 +2,11 @@ package quic import ( "context" + "fmt" "sync" "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/wire" ) @@ -24,14 +26,14 @@ type incomingStreamsMap[T incomingStream] struct { newStreamChan chan struct{} streamType protocol.StreamType - streams map[protocol.StreamNum]incomingStreamEntry[T] + streams map[protocol.StreamID]incomingStreamEntry[T] - nextStreamToAccept protocol.StreamNum // the next stream that will be returned by AcceptStream() - nextStreamToOpen protocol.StreamNum // the highest stream that the peer opened - maxStream protocol.StreamNum // the highest stream that the peer is allowed to open - maxNumStreams uint64 // maximum number of streams + nextStreamToAccept protocol.StreamID // the next stream that will be returned by AcceptStream() + nextStreamToOpen protocol.StreamID // the highest stream that the peer opened + maxStream protocol.StreamID // the highest stream that the peer is allowed to open + maxNumStreams uint64 // maximum number of streams - newStream func(protocol.StreamNum) T + newStream func(protocol.StreamID) T queueMaxStreamID func(*wire.MaxStreamsFrame) closeErr error @@ -39,19 +41,31 @@ type incomingStreamsMap[T incomingStream] struct { func newIncomingStreamsMap[T incomingStream]( streamType protocol.StreamType, - newStream func(protocol.StreamNum) T, + newStream func(protocol.StreamID) T, maxStreams uint64, queueControlFrame func(wire.Frame), + pers protocol.Perspective, ) *incomingStreamsMap[T] { + var nextStreamToAccept protocol.StreamID + switch { + case streamType == protocol.StreamTypeBidi && pers == protocol.PerspectiveServer: + nextStreamToAccept = protocol.FirstIncomingBidiStreamServer + case streamType == protocol.StreamTypeBidi && pers == protocol.PerspectiveClient: + nextStreamToAccept = protocol.FirstIncomingBidiStreamClient + case streamType == protocol.StreamTypeUni && pers == protocol.PerspectiveServer: + nextStreamToAccept = protocol.FirstIncomingUniStreamServer + case streamType == protocol.StreamTypeUni && pers == protocol.PerspectiveClient: + nextStreamToAccept = protocol.FirstIncomingUniStreamClient + } return &incomingStreamsMap[T]{ newStreamChan: make(chan struct{}, 1), streamType: streamType, - streams: make(map[protocol.StreamNum]incomingStreamEntry[T]), - maxStream: protocol.StreamNum(maxStreams), + streams: make(map[protocol.StreamID]incomingStreamEntry[T]), + maxStream: protocol.StreamNum(maxStreams).StreamID(streamType, pers.Opposite()), maxNumStreams: maxStreams, newStream: newStream, - nextStreamToOpen: 1, - nextStreamToAccept: 1, + nextStreamToOpen: nextStreamToAccept, + nextStreamToAccept: nextStreamToAccept, queueMaxStreamID: func(f *wire.MaxStreamsFrame) { queueControlFrame(f) }, } } @@ -65,16 +79,16 @@ func (m *incomingStreamsMap[T]) AcceptStream(ctx context.Context) (T, error) { m.mutex.Lock() - var num protocol.StreamNum + var id protocol.StreamID var entry incomingStreamEntry[T] for { - num = m.nextStreamToAccept + id = m.nextStreamToAccept if m.closeErr != nil { m.mutex.Unlock() return *new(T), m.closeErr } var ok bool - entry, ok = m.streams[num] + entry, ok = m.streams[id] if ok { break } @@ -86,10 +100,10 @@ func (m *incomingStreamsMap[T]) AcceptStream(ctx context.Context) (T, error) { } m.mutex.Lock() } - m.nextStreamToAccept++ + m.nextStreamToAccept += 4 // If this stream was completed before being accepted, we can delete it now. if entry.shouldDelete { - if err := m.deleteStream(num); err != nil { + if err := m.deleteStream(id); err != nil { m.mutex.Unlock() return *new(T), err } @@ -98,22 +112,22 @@ func (m *incomingStreamsMap[T]) AcceptStream(ctx context.Context) (T, error) { return entry.stream, nil } -func (m *incomingStreamsMap[T]) GetOrOpenStream(num protocol.StreamNum) (T, error) { +func (m *incomingStreamsMap[T]) GetOrOpenStream(id protocol.StreamID) (T, error) { m.mutex.RLock() - if num > m.maxStream { + if id > m.maxStream { m.mutex.RUnlock() - return *new(T), streamError{ - message: "peer tried to open stream %d (current limit: %d)", - nums: []protocol.StreamNum{num, m.maxStream}, + return *new(T), &qerr.TransportError{ + ErrorCode: qerr.StreamLimitError, + ErrorMessage: fmt.Sprintf("peer tried to open stream %d (current limit: %d)", id, m.maxStream), } } // if the num is smaller than the highest we accepted // * this stream exists in the map, and we can return it, or // * this stream was already closed, then we can return the nil - if num < m.nextStreamToOpen { + if id < m.nextStreamToOpen { var s T // If the stream was already queued for deletion, and is just waiting to be accepted, don't return it. - if entry, ok := m.streams[num]; ok && !entry.shouldDelete { + if entry, ok := m.streams[id]; ok && !entry.shouldDelete { s = entry.stream } m.mutex.RUnlock() @@ -125,59 +139,59 @@ func (m *incomingStreamsMap[T]) GetOrOpenStream(num protocol.StreamNum) (T, erro // no need to check the two error conditions from above again // * maxStream can only increase, so if the id was valid before, it definitely is valid now // * highestStream is only modified by this function - for newNum := m.nextStreamToOpen; newNum <= num; newNum++ { + for newNum := m.nextStreamToOpen; newNum <= id; newNum += 4 { m.streams[newNum] = incomingStreamEntry[T]{stream: m.newStream(newNum)} select { case m.newStreamChan <- struct{}{}: default: } } - m.nextStreamToOpen = num + 1 - entry := m.streams[num] + m.nextStreamToOpen = id + 4 + entry := m.streams[id] m.mutex.Unlock() return entry.stream, nil } -func (m *incomingStreamsMap[T]) DeleteStream(num protocol.StreamNum) error { +func (m *incomingStreamsMap[T]) DeleteStream(id protocol.StreamID) error { m.mutex.Lock() defer m.mutex.Unlock() - return m.deleteStream(num) + if err := m.deleteStream(id); err != nil { + return &qerr.TransportError{ + ErrorCode: qerr.StreamStateError, + ErrorMessage: err.Error(), + } + } + return nil } -func (m *incomingStreamsMap[T]) deleteStream(num protocol.StreamNum) error { - if _, ok := m.streams[num]; !ok { - return streamError{ - message: "tried to delete unknown incoming stream %d", - nums: []protocol.StreamNum{num}, - } +func (m *incomingStreamsMap[T]) deleteStream(id protocol.StreamID) error { + if _, ok := m.streams[id]; !ok { + return fmt.Errorf("tried to delete unknown incoming stream %d", id) } // Don't delete this stream yet, if it was not yet accepted. // Just save it to streamsToDelete map, to make sure it is deleted as soon as it gets accepted. - if num >= m.nextStreamToAccept { - entry, ok := m.streams[num] + if id >= m.nextStreamToAccept { + entry, ok := m.streams[id] if ok && entry.shouldDelete { - return streamError{ - message: "tried to delete incoming stream %d multiple times", - nums: []protocol.StreamNum{num}, - } + return fmt.Errorf("tried to delete incoming stream %d multiple times", id) } entry.shouldDelete = true - m.streams[num] = entry // can't assign to struct in map, so we need to reassign + m.streams[id] = entry // can't assign to struct in map, so we need to reassign return nil } - delete(m.streams, num) + delete(m.streams, id) // queue a MAX_STREAM_ID frame, giving the peer the option to open a new stream if m.maxNumStreams > uint64(len(m.streams)) { - maxStream := m.nextStreamToOpen + protocol.StreamNum(m.maxNumStreams-uint64(len(m.streams))) - 1 - // Never send a value larger than protocol.MaxStreamCount. - if maxStream <= protocol.MaxStreamCount { + maxStream := m.nextStreamToOpen + 4*protocol.StreamID(m.maxNumStreams-uint64(len(m.streams))-1) + // never send a value larger than the maximum value for a stream number + if maxStream <= protocol.MaxStreamID { m.maxStream = maxStream m.queueMaxStreamID(&wire.MaxStreamsFrame{ Type: m.streamType, - MaxStreamNum: m.maxStream, + MaxStreamNum: m.maxStream.StreamNum(), }) } } diff --git a/vendor/github.com/quic-go/quic-go/streams_map_outgoing.go b/vendor/github.com/quic-go/quic-go/streams_map_outgoing.go index d4c18259..7d7975a5 100644 --- a/vendor/github.com/quic-go/quic-go/streams_map_outgoing.go +++ b/vendor/github.com/quic-go/quic-go/streams_map_outgoing.go @@ -2,15 +2,18 @@ package quic import ( "context" + "fmt" "slices" "sync" "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/internal/qerr" "github.com/quic-go/quic-go/internal/wire" ) type outgoingStream interface { updateSendWindow(protocol.ByteCount) + enableResetStreamAt() closeForShutdown(error) } @@ -18,15 +21,15 @@ type outgoingStreamsMap[T outgoingStream] struct { mutex sync.RWMutex streamType protocol.StreamType - streams map[protocol.StreamNum]T + streams map[protocol.StreamID]T openQueue []chan struct{} - nextStream protocol.StreamNum // stream ID of the stream returned by OpenStream(Sync) - maxStream protocol.StreamNum // the maximum stream ID we're allowed to open - blockedSent bool // was a STREAMS_BLOCKED sent for the current maxStream + nextStream protocol.StreamID // stream ID of the stream returned by OpenStream(Sync) + maxStream protocol.StreamID // the maximum stream ID we're allowed to open + blockedSent bool // was a STREAMS_BLOCKED sent for the current maxStream - newStream func(protocol.StreamNum) T + newStream func(protocol.StreamID) T queueStreamIDBlocked func(*wire.StreamsBlockedFrame) closeErr error @@ -34,14 +37,26 @@ type outgoingStreamsMap[T outgoingStream] struct { func newOutgoingStreamsMap[T outgoingStream]( streamType protocol.StreamType, - newStream func(protocol.StreamNum) T, + newStream func(protocol.StreamID) T, queueControlFrame func(wire.Frame), + pers protocol.Perspective, ) *outgoingStreamsMap[T] { + var nextStream protocol.StreamID + switch { + case streamType == protocol.StreamTypeBidi && pers == protocol.PerspectiveServer: + nextStream = protocol.FirstOutgoingBidiStreamServer + case streamType == protocol.StreamTypeBidi && pers == protocol.PerspectiveClient: + nextStream = protocol.FirstOutgoingBidiStreamClient + case streamType == protocol.StreamTypeUni && pers == protocol.PerspectiveServer: + nextStream = protocol.FirstOutgoingUniStreamServer + case streamType == protocol.StreamTypeUni && pers == protocol.PerspectiveClient: + nextStream = protocol.FirstOutgoingUniStreamClient + } return &outgoingStreamsMap[T]{ streamType: streamType, - streams: make(map[protocol.StreamNum]T), + streams: make(map[protocol.StreamID]T), maxStream: protocol.InvalidStreamNum, - nextStream: 1, + nextStream: nextStream, newStream: newStream, queueStreamIDBlocked: func(f *wire.StreamsBlockedFrame) { queueControlFrame(f) }, } @@ -114,7 +129,7 @@ func (m *outgoingStreamsMap[T]) OpenStreamSync(ctx context.Context) (T, error) { func (m *outgoingStreamsMap[T]) openStream() T { s := m.newStream(m.nextStream) m.streams[m.nextStream] = s - m.nextStream++ + m.nextStream += 4 return s } @@ -125,55 +140,55 @@ func (m *outgoingStreamsMap[T]) maybeSendBlockedFrame() { return } - var streamNum protocol.StreamNum - if m.maxStream != protocol.InvalidStreamNum { - streamNum = m.maxStream + var streamLimit protocol.StreamNum + if m.maxStream != protocol.InvalidStreamID { + streamLimit = m.maxStream.StreamNum() } m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ Type: m.streamType, - StreamLimit: streamNum, + StreamLimit: streamLimit, }) m.blockedSent = true } -func (m *outgoingStreamsMap[T]) GetStream(num protocol.StreamNum) (T, error) { +func (m *outgoingStreamsMap[T]) GetStream(id protocol.StreamID) (T, error) { m.mutex.RLock() - if num >= m.nextStream { + if id >= m.nextStream { m.mutex.RUnlock() - return *new(T), streamError{ - message: "peer attempted to open stream %d", - nums: []protocol.StreamNum{num}, + return *new(T), &qerr.TransportError{ + ErrorCode: qerr.StreamStateError, + ErrorMessage: fmt.Sprintf("peer attempted to open stream %d", id), } } - s := m.streams[num] + s := m.streams[id] m.mutex.RUnlock() return s, nil } -func (m *outgoingStreamsMap[T]) DeleteStream(num protocol.StreamNum) error { +func (m *outgoingStreamsMap[T]) DeleteStream(id protocol.StreamID) error { m.mutex.Lock() defer m.mutex.Unlock() - if _, ok := m.streams[num]; !ok { - return streamError{ - message: "tried to delete unknown outgoing stream %d", - nums: []protocol.StreamNum{num}, + if _, ok := m.streams[id]; !ok { + return &qerr.TransportError{ + ErrorCode: qerr.StreamStateError, + ErrorMessage: fmt.Sprintf("tried to delete unknown outgoing stream %d", id), } } - delete(m.streams, num) + delete(m.streams, id) return nil } -func (m *outgoingStreamsMap[T]) SetMaxStream(num protocol.StreamNum) { +func (m *outgoingStreamsMap[T]) SetMaxStream(id protocol.StreamID) { m.mutex.Lock() defer m.mutex.Unlock() - if num <= m.maxStream { + if id <= m.maxStream { return } - m.maxStream = num + m.maxStream = id m.blockedSent = false - if m.maxStream < m.nextStream-1+protocol.StreamNum(len(m.openQueue)) { + if m.maxStream < m.nextStream-4+4*protocol.StreamID(len(m.openQueue)) { m.maybeSendBlockedFrame() } m.maybeUnblockOpenSync() @@ -190,6 +205,14 @@ func (m *outgoingStreamsMap[T]) UpdateSendWindow(limit protocol.ByteCount) { m.mutex.Unlock() } +func (m *outgoingStreamsMap[T]) EnableResetStreamAt() { + m.mutex.Lock() + for _, str := range m.streams { + str.enableResetStreamAt() + } + m.mutex.Unlock() +} + // unblockOpenSync unblocks the next OpenStreamSync go-routine to open a new stream func (m *outgoingStreamsMap[T]) maybeUnblockOpenSync() { if len(m.openQueue) == 0 { diff --git a/vendor/github.com/quic-go/quic-go/sys_conn.go b/vendor/github.com/quic-go/quic-go/sys_conn.go index 8159a146..ce35de88 100644 --- a/vendor/github.com/quic-go/quic-go/sys_conn.go +++ b/vendor/github.com/quic-go/quic-go/sys_conn.go @@ -1,6 +1,7 @@ package quic import ( + "io" "log" "net" "os" @@ -9,10 +10,35 @@ import ( "syscall" "time" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" ) +type connCapabilities struct { + // This connection has the Don't Fragment (DF) bit set. + // This means it makes to run DPLPMTUD. + DF bool + // GSO (Generic Segmentation Offload) supported + GSO bool + // ECN (Explicit Congestion Notifications) supported + ECN bool +} + +// rawConn is a connection that allow reading of a receivedPackeh. +type rawConn interface { + ReadPacket() (receivedPacket, error) + // WritePacket writes a packet on the wire. + // gsoSize is the size of a single packet, or 0 to disable GSO. + // It is invalid to set gsoSize if capabilities.GSO is not set. + WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16, ecn protocol.ECN) (int, error) + LocalAddr() net.Addr + SetReadDeadline(time.Time) error + io.Closer + + capabilities() connCapabilities +} + // OOBCapablePacketConn is a connection that allows the reading of ECN bits from the IP header. // If the PacketConn passed to the [Transport] satisfies this interface, quic-go will use it. // In this case, ReadMsgUDP() will be used instead of ReadFrom() to read packets. @@ -98,7 +124,7 @@ func (c *basicConn) ReadPacket() (receivedPacket, error) { } return receivedPacket{ remoteAddr: addr, - rcvTime: time.Now(), + rcvTime: monotime.Now(), data: buffer.Data[:n], buffer: buffer, }, nil diff --git a/vendor/github.com/quic-go/quic-go/sys_conn_helper_darwin.go b/vendor/github.com/quic-go/quic-go/sys_conn_helper_darwin.go index 545502dd..a04bfb3c 100644 --- a/vendor/github.com/quic-go/quic-go/sys_conn_helper_darwin.go +++ b/vendor/github.com/quic-go/quic-go/sys_conn_helper_darwin.go @@ -30,7 +30,7 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) { if len(body) != 12 { return netip.Addr{}, 0, false } - return netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.LittleEndian.Uint32(body), true + return netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.NativeEndian.Uint32(body), true } func isGSOEnabled(syscall.RawConn) bool { return false } diff --git a/vendor/github.com/quic-go/quic-go/sys_conn_helper_linux.go b/vendor/github.com/quic-go/quic-go/sys_conn_helper_linux.go index eec12719..9a890cbe 100644 --- a/vendor/github.com/quic-go/quic-go/sys_conn_helper_linux.go +++ b/vendor/github.com/quic-go/quic-go/sys_conn_helper_linux.go @@ -58,7 +58,7 @@ func parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) { if len(body) != 12 { return netip.Addr{}, 0, false } - return netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.LittleEndian.Uint32(body), true + return netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.NativeEndian.Uint32(body), true } // isGSOEnabled tests if the kernel supports GSO. diff --git a/vendor/github.com/quic-go/quic-go/sys_conn_oob.go b/vendor/github.com/quic-go/quic-go/sys_conn_oob.go index 5ed1b656..0aa69cda 100644 --- a/vendor/github.com/quic-go/quic-go/sys_conn_oob.go +++ b/vendor/github.com/quic-go/quic-go/sys_conn_oob.go @@ -12,13 +12,13 @@ import ( "strconv" "sync" "syscall" - "time" "unsafe" "golang.org/x/net/ipv4" "golang.org/x/net/ipv6" "golang.org/x/sys/unix" + "github.com/quic-go/quic-go/internal/monotime" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" ) @@ -185,7 +185,7 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { data := msg.OOB[:msg.NN] p := receivedPacket{ remoteAddr: msg.Addr, - rcvTime: time.Now(), + rcvTime: monotime.Now(), data: msg.Buffers[0][:msg.N], buffer: buffer, } @@ -197,6 +197,9 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { if hdr.Level == unix.IPPROTO_IP { switch hdr.Type { case msgTypeIPTOS: + if len(body) != 1 { + return receivedPacket{}, errors.New("invalid IPTOS size") + } p.ecn = protocol.ParseECNHeaderBits(body[0] & ecnMask) case ipv4PKTINFO: ip, ifIndex, ok := parseIPv4PktInfo(body) @@ -214,7 +217,11 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { if hdr.Level == unix.IPPROTO_IPV6 { switch hdr.Type { case unix.IPV6_TCLASS: - p.ecn = protocol.ParseECNHeaderBits(body[0] & ecnMask) + if len(body) != 4 { + return receivedPacket{}, errors.New("invalid IPV6_TCLASS size") + } + bits := uint8(binary.NativeEndian.Uint32(body)) & ecnMask + p.ecn = protocol.ParseECNHeaderBits(bits) case unix.IPV6_PKTINFO: // struct in6_pktinfo { // struct in6_addr ipi6_addr; /* src/dst IPv6 address */ @@ -222,7 +229,7 @@ func (c *oobConn) ReadPacket() (receivedPacket, error) { // }; if len(body) == 20 { p.info.addr = netip.AddrFrom16(*(*[16]byte)(body[:16])).Unmap() - p.info.ifIndex = binary.LittleEndian.Uint32(body[16:]) + p.info.ifIndex = binary.NativeEndian.Uint32(body[16:]) } else { invalidCmsgOnceV6.Do(func() { log.Printf("Received invalid IPv6 packet info control message: %+x. "+ @@ -326,6 +333,6 @@ func appendIPv6ECNMsg(b []byte, val protocol.ECN) []byte { // UnixRights uses the private `data` method, but I *think* this achieves the same goal. offset := startLen + unix.CmsgSpace(0) - b[offset] = val.ToHeaderBits() + binary.NativeEndian.PutUint32(b[offset:offset+dataLen], uint32(val.ToHeaderBits())) return b } diff --git a/vendor/github.com/quic-go/quic-go/tools.go b/vendor/github.com/quic-go/quic-go/tools.go deleted file mode 100644 index d00ce748..00000000 --- a/vendor/github.com/quic-go/quic-go/tools.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build tools - -package quic - -import ( - _ "github.com/onsi/ginkgo/v2/ginkgo" - _ "go.uber.org/mock/mockgen" -) diff --git a/vendor/github.com/quic-go/quic-go/transport.go b/vendor/github.com/quic-go/quic-go/transport.go index a7775fb1..740c9b53 100644 --- a/vendor/github.com/quic-go/quic-go/transport.go +++ b/vendor/github.com/quic-go/quic-go/transport.go @@ -14,7 +14,8 @@ import ( "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" "github.com/quic-go/quic-go/internal/wire" - "github.com/quic-go/quic-go/logging" + "github.com/quic-go/quic-go/qlog" + "github.com/quic-go/quic-go/qlogwriter" ) // ErrTransportClosed is returned by the [Transport]'s Listen or Dial method after it was closed. @@ -38,12 +39,14 @@ func (e *errTransportClosed) Is(target error) bool { return ok } -type transportID uint64 - -var transportIDCounter atomic.Uint64 - var errListenerAlreadySet = errors.New("listener already set") +type closePacket struct { + payload []byte + addr net.Addr + info packetInfo +} + // The Transport is the central point to manage incoming and outgoing QUIC connections. // QUIC demultiplexes connections based on their QUIC Connection IDs, not based on the 4-tuple. // This means that a single UDP socket can be used for listening for incoming connections, as well as @@ -115,29 +118,29 @@ type Transport struct { // implementation of this callback (negating its return value). VerifySourceAddress func(net.Addr) bool - // ConnContext is called when the server accepts a new connection. + // ConnContext is called when the server accepts a new connection. To reject a connection return + // a non-nil error. // The context is closed when the connection is closed, or when the handshake fails for any reason. // The context returned from the callback is used to derive every other context used during the // lifetime of the connection: // * the context passed to crypto/tls (and used on the tls.ClientHelloInfo) - // * the context used in Config.Tracer - // * the context returned from Connection.Context + // * the context used in Config.QlogTrace + // * the context returned from Conn.Context // * the context returned from SendStream.Context // It is not used for dialed connections. - ConnContext func(context.Context) context.Context + ConnContext func(context.Context, *ClientInfo) (context.Context, error) // A Tracer traces events that don't belong to a single QUIC connection. - // Tracer.Close is called when the transport is closed. - Tracer *logging.Tracer + // Recorder.Close is called when the transport is closed. + Tracer qlogwriter.Recorder - handlerMap packetHandlerManager + mutex sync.Mutex + handlers map[protocol.ConnectionID]packetHandler + resetTokens map[protocol.StatelessResetToken]packetHandler - mutex sync.Mutex initOnce sync.Once initErr error - // Set in init. - transportID transportID // If no ConnectionIDGenerator is set, this is the ConnectionIDLength. connIDLen int // Set in init. @@ -212,7 +215,7 @@ func (t *Transport) createServer(tlsConf *tls.Config, conf *Config, allow0RTT bo } s := newServer( t.conn, - t, + (*packetHandlerMap)(t), t.connIDGenerator, t.statelessResetter, t.ConnContext, @@ -231,16 +234,16 @@ func (t *Transport) createServer(tlsConf *tls.Config, conf *Config, allow0RTT bo } // Dial dials a new connection to a remote host (not using 0-RTT). -func (t *Transport) Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (Connection, error) { +func (t *Transport) Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (*Conn, error) { return t.dial(ctx, addr, "", tlsConf, conf, false) } // DialEarly dials a new connection, attempting to use 0-RTT if possible. -func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (EarlyConnection, error) { +func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (*Conn, error) { return t.dial(ctx, addr, "", tlsConf, conf, true) } -func (t *Transport) dial(ctx context.Context, addr net.Addr, host string, tlsConf *tls.Config, conf *Config, use0RTT bool) (EarlyConnection, error) { +func (t *Transport) dial(ctx context.Context, addr net.Addr, host string, tlsConf *tls.Config, conf *Config, use0RTT bool) (*Conn, error) { if err := t.init(t.isSingleUse); err != nil { return nil, err } @@ -270,7 +273,7 @@ func (t *Transport) doDial( hasNegotiatedVersion bool, use0RTT bool, version protocol.Version, -) (quicConn, error) { +) (*Conn, error) { srcConnID, err := t.connIDGenerator.GenerateConnectionID() if err != nil { return nil, err @@ -280,21 +283,15 @@ func (t *Transport) doDial( return nil, err } - tracingID := nextConnTracingID() - ctx = context.WithValue(ctx, ConnectionTracingKey, tracingID) - t.mutex.Lock() if t.closeErr != nil { t.mutex.Unlock() return nil, t.closeErr } - var tracer *logging.ConnectionTracer + var qlogTrace qlogwriter.Trace if config.Tracer != nil { - tracer = config.Tracer(ctx, protocol.PerspectiveClient, destConnID) - } - if tracer != nil && tracer.StartedConnection != nil { - tracer.StartedConnection(sendConn.LocalAddr(), sendConn.RemoteAddr(), srcConnID, destConnID) + qlogTrace = config.Tracer(ctx, true, destConnID) } logger := utils.DefaultLogger.WithPrefix("client") @@ -303,7 +300,7 @@ func (t *Transport) doDial( conn := newClientConnection( context.WithoutCancel(ctx), sendConn, - t, + (*packetHandlerMap)(t), destConnID, srcConnID, t.connIDGenerator, @@ -313,17 +310,18 @@ func (t *Transport) doDial( initialPacketNumber, use0RTT, hasNegotiatedVersion, - tracer, + qlogTrace, logger, version, ) - t.handlerMap.Add(srcConnID, conn) + t.handlers[srcConnID] = conn t.mutex.Unlock() // The error channel needs to be buffered, as the run loop will continue running // after doDial returns (if the handshake is successful). + // Similarly, the recreateChan needs to be buffered; in case a different case is selected. errChan := make(chan error, 1) - recreateChan := make(chan errCloseForRecreating) + recreateChan := make(chan errCloseForRecreating, 1) go func() { err := conn.run() var recreateErr *errCloseForRecreating @@ -347,7 +345,7 @@ func (t *Transport) doDial( select { case <-ctx.Done(): conn.destroy(nil) - // wait until the Go routine that called Connection.run() returns + // wait until the Go routine that called Conn.run() returns select { case <-errChan: case <-recreateChan: @@ -367,16 +365,15 @@ func (t *Transport) doDial( return nil, err case <-earlyConnChan: // ready to send 0-RTT data - return conn, nil + return conn.Conn, nil case <-conn.HandshakeComplete(): // handshake successfully completed - return conn, nil + return conn.Conn, nil } } func (t *Transport) init(allowZeroLengthConnIDs bool) error { t.initOnce.Do(func() { - t.transportID = transportID(transportIDCounter.Add(1)) var conn rawConn if c, ok := t.Conn.(rawConn); ok { conn = c @@ -391,9 +388,8 @@ func (t *Transport) init(allowZeroLengthConnIDs bool) error { t.logger = utils.DefaultLogger // TODO: make this configurable t.conn = conn - if t.handlerMap == nil { // allows mocking the handlerMap in tests - t.handlerMap = newPacketHandlerMap(t.enqueueClosePacket, t.logger) - } + t.handlers = make(map[protocol.ConnectionID]packetHandler) + t.resetTokens = make(map[protocol.StatelessResetToken]packetHandler) t.listening = make(chan struct{}) t.closeQueue = make(chan closePacket, 4) @@ -420,18 +416,19 @@ func (t *Transport) init(allowZeroLengthConnIDs bool) error { } t.statelessResetter = newStatelessResetter(t.StatelessResetKey) - go t.listen(conn) + go func() { + defer close(t.listening) + t.listen(conn) + + if t.createdConn { + conn.Close() + } + }() go t.runSendQueue() }) return t.initErr } -func (t *Transport) connRunner() packetHandlerManager { - return t.handlerMap -} - -func (t *Transport) id() transportID { return t.transportID } - // WriteTo sends a packet on the underlying connection. func (t *Transport) WriteTo(b []byte, addr net.Addr) (int, error) { if err := t.init(false); err != nil { @@ -440,15 +437,6 @@ func (t *Transport) WriteTo(b []byte, addr net.Addr) (int, error) { return t.conn.WritePacket(b, addr, nil, 0, protocol.ECNUnsupported) } -func (t *Transport) enqueueClosePacket(p closePacket) { - select { - case t.closeQueue <- p: - default: - // Oops, we're backlogged. - // Just drop the packet, sending CONNECTION_CLOSE copies is best effort anyway. - } -} - func (t *Transport) runSendQueue() { for { select { @@ -463,8 +451,12 @@ func (t *Transport) runSendQueue() { } // Close stops listening for UDP datagrams on the Transport.Conn. -// If any listener was started, it will be closed as well. -// It is invalid to start new listeners or connections after that. +// It abruptly terminates all existing connections, without sending a CONNECTION_CLOSE +// to the peers. It is the application's responsibility to cleanly terminate existing +// connections prior to calling Close. +// +// If a server was started, it will be closed as well. +// It is not possible to start any new server or dial new connections after that. func (t *Transport) Close() error { // avoid race condition if the transport is currently being initialized t.init(false) @@ -486,48 +478,57 @@ func (t *Transport) Close() error { func (t *Transport) closeServer() { t.mutex.Lock() + defer t.mutex.Unlock() + t.server = nil if t.isSingleUse { t.closeErr = ErrServerClosed } - t.mutex.Unlock() - if t.createdConn { - t.Conn.Close() - } - if t.isSingleUse { - t.conn.SetReadDeadline(time.Now()) - defer func() { t.conn.SetReadDeadline(time.Time{}) }() - <-t.listening // wait until listening returns + + if len(t.handlers) == 0 { + t.maybeStopListening() } } func (t *Transport) close(e error) { t.mutex.Lock() - defer t.mutex.Unlock() if t.closeErr != nil { + t.mutex.Unlock() return } e = &errTransportClosed{err: e} - if t.handlerMap != nil { - t.handlerMap.Close(e) + t.closeErr = e + server := t.server + t.server = nil + if server != nil { + t.mutex.Unlock() + server.close(e, true) + t.mutex.Lock() } - if t.server != nil { - t.server.close(e, false) + + // Close existing connections + var wg sync.WaitGroup + for _, handler := range t.handlers { + wg.Add(1) + go func(handler packetHandler) { + handler.destroy(e) + wg.Done() + }(handler) } - if t.Tracer != nil && t.Tracer.Close != nil { + t.mutex.Unlock() // closing connections requires releasing transport mutex + wg.Wait() + + if t.Tracer != nil { t.Tracer.Close() } - t.closeErr = e } // only print warnings about the UDP receive buffer size once var setBufferWarningOnce sync.Once func (t *Transport) listen(conn rawConn) { - defer close(t.listening) - for { p, err := conn.ReadPacket() //nolint:staticcheck // SA1019 ignore this! @@ -556,6 +557,12 @@ func (t *Transport) listen(conn rawConn) { } } +func (t *Transport) maybeStopListening() { + if t.isSingleUse && t.closeErr != nil { + t.conn.SetReadDeadline(time.Now()) + } +} + func (t *Transport) handlePacket(p receivedPacket) { if len(p.data) == 0 { return @@ -567,15 +574,18 @@ func (t *Transport) handlePacket(p receivedPacket) { connID, err := wire.ParseConnectionID(p.data, t.connIDLen) if err != nil { t.logger.Debugf("error parsing connection ID on packet from %s: %s", p.remoteAddr, err) - if t.Tracer != nil && t.Tracer.DroppedPacket != nil { - t.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError) + if t.Tracer != nil { + t.Tracer.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropHeaderParseError, + }) } p.buffer.MaybeRelease() return } // If there's a connection associated with the connection ID, pass the packet there. - if handler, ok := t.handlerMap.Get(connID); ok { + if handler, ok := (*packetHandlerMap)(t).Get(connID); ok { handler.handlePacket(p) return } @@ -591,8 +601,12 @@ func (t *Transport) handlePacket(p receivedPacket) { } if !wire.IsLongHeaderPacket(p.data[0]) { if statelessResetQueued := t.maybeSendStatelessReset(p); !statelessResetQueued { - if t.Tracer != nil && t.Tracer.DroppedPacket != nil { - t.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnknownConnectionID) + if t.Tracer != nil { + t.Tracer.RecordEvent(qlog.PacketDropped{ + Header: qlog.PacketHeader{PacketType: qlog.PacketType1RTT}, + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnknownConnectionID, + }) } p.buffer.Release() } @@ -603,8 +617,11 @@ func (t *Transport) handlePacket(p receivedPacket) { defer t.mutex.Unlock() if t.server == nil { // no server set t.logger.Debugf("received a packet with an unexpected connection ID %s", connID) - if t.Tracer != nil && t.Tracer.DroppedPacket != nil { - t.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnknownConnectionID) + if t.Tracer != nil { + t.Tracer.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropUnknownConnectionID, + }) } p.buffer.MaybeRelease() return @@ -660,8 +677,12 @@ func (t *Transport) maybeHandleStatelessReset(data []byte) bool { return false } - token := *(*protocol.StatelessResetToken)(data[len(data)-16:]) - if conn, ok := t.handlerMap.GetByResetToken(token); ok { + token := protocol.StatelessResetToken(data[len(data)-16:]) + t.mutex.Lock() + conn, ok := t.resetTokens[token] + t.mutex.Unlock() + + if ok { t.logger.Debugf("Received a stateless reset with token %#x. Closing connection.", token) go conn.destroy(&StatelessResetError{}) return true @@ -678,8 +699,11 @@ func (t *Transport) handleNonQUICPacket(p receivedPacket) { select { case t.nonQUICPackets <- p: default: - if t.Tracer != nil && t.Tracer.DroppedPacket != nil { - t.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention) + if t.Tracer != nil { + t.Tracer.RecordEvent(qlog.PacketDropped{ + Raw: qlog.RawInfo{Length: int(p.Size())}, + Trigger: qlog.PacketDropDOSPrevention, + }) } } } @@ -726,3 +750,103 @@ func setTLSConfigServerName(tlsConf *tls.Config, addr net.Addr, host string) { } tlsConf.ServerName = h } + +type packetHandlerMap Transport + +var _ connRunner = &packetHandlerMap{} + +func (h *packetHandlerMap) Add(id protocol.ConnectionID, handler packetHandler) bool /* was added */ { + h.mutex.Lock() + defer h.mutex.Unlock() + + if _, ok := h.handlers[id]; ok { + h.logger.Debugf("Not adding connection ID %s, as it already exists.", id) + return false + } + h.handlers[id] = handler + h.logger.Debugf("Adding connection ID %s.", id) + return true +} + +func (h *packetHandlerMap) Get(connID protocol.ConnectionID) (packetHandler, bool) { + h.mutex.Lock() + defer h.mutex.Unlock() + handler, ok := h.handlers[connID] + return handler, ok +} + +func (h *packetHandlerMap) AddResetToken(token protocol.StatelessResetToken, handler packetHandler) { + h.mutex.Lock() + h.resetTokens[token] = handler + h.mutex.Unlock() +} + +func (h *packetHandlerMap) RemoveResetToken(token protocol.StatelessResetToken) { + h.mutex.Lock() + delete(h.resetTokens, token) + h.mutex.Unlock() +} + +func (h *packetHandlerMap) AddWithConnID(clientDestConnID, newConnID protocol.ConnectionID, handler packetHandler) bool { + h.mutex.Lock() + defer h.mutex.Unlock() + + if _, ok := h.handlers[clientDestConnID]; ok { + h.logger.Debugf("Not adding connection ID %s for a new connection, as it already exists.", clientDestConnID) + return false + } + h.handlers[clientDestConnID] = handler + h.handlers[newConnID] = handler + h.logger.Debugf("Adding connection IDs %s and %s for a new connection.", clientDestConnID, newConnID) + return true +} + +func (h *packetHandlerMap) Remove(id protocol.ConnectionID) { + h.mutex.Lock() + delete(h.handlers, id) + h.mutex.Unlock() + h.logger.Debugf("Removing connection ID %s.", id) +} + +// ReplaceWithClosed is called when a connection is closed. +// Depending on which side closed the connection, we need to: +// * remote close: absorb delayed packets +// * local close: retransmit the CONNECTION_CLOSE packet, in case it was lost +func (h *packetHandlerMap) ReplaceWithClosed(ids []protocol.ConnectionID, connClosePacket []byte, expiry time.Duration) { + var handler packetHandler + if connClosePacket != nil { + handler = newClosedLocalConn( + func(addr net.Addr, info packetInfo) { + select { + case h.closeQueue <- closePacket{payload: connClosePacket, addr: addr, info: info}: + default: + // We're backlogged. + // Just drop the packet, sending CONNECTION_CLOSE copies is best effort anyway. + } + }, + h.logger, + ) + } else { + handler = newClosedRemoteConn() + } + + h.mutex.Lock() + for _, id := range ids { + h.handlers[id] = handler + } + h.mutex.Unlock() + h.logger.Debugf("Replacing connection for connection IDs %s with a closed connection.", ids) + + time.AfterFunc(expiry, func() { + h.mutex.Lock() + for _, id := range ids { + delete(h.handlers, id) + } + if len(h.handlers) == 0 { + t := (*Transport)(h) + t.maybeStopListening() + } + h.mutex.Unlock() + h.logger.Debugf("Removing connection IDs %s for a closed connection after it has been retired.", ids) + }) +} diff --git a/vendor/go.uber.org/automaxprocs/.codecov.yml b/vendor/go.uber.org/automaxprocs/.codecov.yml deleted file mode 100644 index 9a2ed4a9..00000000 --- a/vendor/go.uber.org/automaxprocs/.codecov.yml +++ /dev/null @@ -1,14 +0,0 @@ -coverage: - range: 80..100 - round: down - precision: 2 - - status: - project: # measuring the overall project coverage - default: # context, you can create multiple ones with custom titles - enabled: yes # must be yes|true to enable this status - target: 90% # specify the target coverage for each commit status - # option: "auto" (must increase from parent commit or pull request base) - # option: "X%" a static target percentage to hit - if_not_found: success # if parent is not found report status as success, error, or failure - if_ci_failed: error # if ci fails report status as success, error, or failure diff --git a/vendor/go.uber.org/automaxprocs/.gitignore b/vendor/go.uber.org/automaxprocs/.gitignore deleted file mode 100644 index dd7bcf51..00000000 --- a/vendor/go.uber.org/automaxprocs/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test -vendor - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof -*.pprof -*.out -*.log -coverage.txt - -/bin -cover.out -cover.html diff --git a/vendor/go.uber.org/automaxprocs/CHANGELOG.md b/vendor/go.uber.org/automaxprocs/CHANGELOG.md deleted file mode 100644 index f421056a..00000000 --- a/vendor/go.uber.org/automaxprocs/CHANGELOG.md +++ /dev/null @@ -1,52 +0,0 @@ -# Changelog - -## v1.6.0 (2024-07-24) - -- Add RoundQuotaFunc option that allows configuration of rounding - behavior for floating point CPU quota. - -## v1.5.3 (2023-07-19) - -- Fix mountinfo parsing when super options have fields with spaces. -- Fix division by zero while parsing cgroups. - -## v1.5.2 (2023-03-16) - -- Support child control cgroups -- Fix file descriptor leak -- Update dependencies - -## v1.5.1 (2022-04-06) - -- Fix cgroups v2 mountpoint detection. - -## v1.5.0 (2022-04-05) - -- Add support for cgroups v2. - -Thanks to @emadolsky for their contribution to this release. - -## v1.4.0 (2021-02-01) - -- Support colons in cgroup names. -- Remove linters from runtime dependencies. - -## v1.3.0 (2020-01-23) - -- Migrate to Go modules. - -## v1.2.0 (2018-02-22) - -- Fixed quota clamping to always round down rather than up; Rather than - guaranteeing constant throttling at saturation, instead assume that the - fractional CPU was added as a hedge for factors outside of Go's scheduler. - -## v1.1.0 (2017-11-10) - -- Log the new value of `GOMAXPROCS` rather than the current value. -- Make logs more explicit about whether `GOMAXPROCS` was modified or not. -- Allow customization of the minimum `GOMAXPROCS`, and modify default from 2 to 1. - -## v1.0.0 (2017-08-09) - -- Initial release. diff --git a/vendor/go.uber.org/automaxprocs/CODE_OF_CONDUCT.md b/vendor/go.uber.org/automaxprocs/CODE_OF_CONDUCT.md deleted file mode 100644 index e327d9aa..00000000 --- a/vendor/go.uber.org/automaxprocs/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,75 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, -body size, disability, ethnicity, gender identity and expression, level of -experience, nationality, personal appearance, race, religion, or sexual -identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an -appointed representative at an online or offline event. Representation of a -project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at oss-conduct@uber.com. The project -team will review and investigate all complaints, and will respond in a way -that it deems appropriate to the circumstances. The project team is obligated -to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 1.4, available at -[http://contributor-covenant.org/version/1/4][version]. - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/go.uber.org/automaxprocs/CONTRIBUTING.md b/vendor/go.uber.org/automaxprocs/CONTRIBUTING.md deleted file mode 100644 index 2b6a6040..00000000 --- a/vendor/go.uber.org/automaxprocs/CONTRIBUTING.md +++ /dev/null @@ -1,81 +0,0 @@ -# Contributing - -We'd love your help improving this package! - -If you'd like to add new exported APIs, please [open an issue][open-issue] -describing your proposal — discussing API changes ahead of time makes -pull request review much smoother. In your issue, pull request, and any other -communications, please remember to treat your fellow contributors with -respect! We take our [code of conduct](CODE_OF_CONDUCT.md) seriously. - -Note that you'll need to sign [Uber's Contributor License Agreement][cla] -before we can accept any of your contributions. If necessary, a bot will remind -you to accept the CLA when you open your pull request. - -## Setup - -[Fork][fork], then clone the repository: - -``` -mkdir -p $GOPATH/src/go.uber.org -cd $GOPATH/src/go.uber.org -git clone git@github.com:your_github_username/automaxprocs.git -cd automaxprocs -git remote add upstream https://github.com/uber-go/automaxprocs.git -git fetch upstream -``` - -Install the test dependencies: - -``` -make dependencies -``` - -Make sure that the tests and the linters pass: - -``` -make test -make lint -``` - -If you're not using the minor version of Go specified in the Makefile's -`LINTABLE_MINOR_VERSIONS` variable, `make lint` doesn't do anything. This is -fine, but it means that you'll only discover lint failures after you open your -pull request. - -## Making Changes - -Start by creating a new branch for your changes: - -``` -cd $GOPATH/src/go.uber.org/automaxprocs -git checkout master -git fetch upstream -git rebase upstream/master -git checkout -b cool_new_feature -``` - -Make your changes, then ensure that `make lint` and `make test` still pass. If -you're satisfied with your changes, push them to your fork. - -``` -git push origin cool_new_feature -``` - -Then use the GitHub UI to open a pull request. - -At this point, you're waiting on us to review your changes. We *try* to respond -to issues and pull requests within a few business days, and we may suggest some -improvements or alternatives. Once your changes are approved, one of the -project maintainers will merge them. - -We're much more likely to approve your changes if you: - -* Add tests for new functionality. -* Write a [good commit message][commit-message]. -* Maintain backward compatibility. - -[fork]: https://github.com/uber-go/automaxprocs/fork -[open-issue]: https://github.com/uber-go/automaxprocs/issues/new -[cla]: https://cla-assistant.io/uber-go/automaxprocs -[commit-message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html diff --git a/vendor/go.uber.org/automaxprocs/Makefile b/vendor/go.uber.org/automaxprocs/Makefile deleted file mode 100644 index 1642b714..00000000 --- a/vendor/go.uber.org/automaxprocs/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -export GOBIN ?= $(shell pwd)/bin - -GO_FILES := $(shell \ - find . '(' -path '*/.*' -o -path './vendor' ')' -prune \ - -o -name '*.go' -print | cut -b3-) - -GOLINT = $(GOBIN)/golint -STATICCHECK = $(GOBIN)/staticcheck - -.PHONY: build -build: - go build ./... - -.PHONY: install -install: - go mod download - -.PHONY: test -test: - go test -race ./... - -.PHONY: cover -cover: - go test -coverprofile=cover.out -covermode=atomic -coverpkg=./... ./... - go tool cover -html=cover.out -o cover.html - -$(GOLINT): tools/go.mod - cd tools && go install golang.org/x/lint/golint - -$(STATICCHECK): tools/go.mod - cd tools && go install honnef.co/go/tools/cmd/staticcheck@2023.1.2 - -.PHONY: lint -lint: $(GOLINT) $(STATICCHECK) - @rm -rf lint.log - @echo "Checking gofmt" - @gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log - @echo "Checking go vet" - @go vet ./... 2>&1 | tee -a lint.log - @echo "Checking golint" - @$(GOLINT) ./... | tee -a lint.log - @echo "Checking staticcheck" - @$(STATICCHECK) ./... 2>&1 | tee -a lint.log - @echo "Checking for license headers..." - @./.build/check_license.sh | tee -a lint.log - @[ ! -s lint.log ] diff --git a/vendor/go.uber.org/automaxprocs/README.md b/vendor/go.uber.org/automaxprocs/README.md deleted file mode 100644 index bfed32ad..00000000 --- a/vendor/go.uber.org/automaxprocs/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# automaxprocs [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] - -Automatically set `GOMAXPROCS` to match Linux container CPU quota. - -## Installation - -`go get -u go.uber.org/automaxprocs` - -## Quick Start - -```go -import _ "go.uber.org/automaxprocs" - -func main() { - // Your application logic here. -} -``` - -# Performance -Data measured from Uber's internal load balancer. We ran the load balancer with 200% CPU quota (i.e., 2 cores): - -| GOMAXPROCS | RPS | P50 (ms) | P99.9 (ms) | -| ------------------ | --------- | -------- | ---------- | -| 1 | 28,893.18 | 1.46 | 19.70 | -| 2 (equal to quota) | 44,715.07 | 0.84 | 26.38 | -| 3 | 44,212.93 | 0.66 | 30.07 | -| 4 | 41,071.15 | 0.57 | 42.94 | -| 8 | 33,111.69 | 0.43 | 64.32 | -| Default (24) | 22,191.40 | 0.45 | 76.19 | - -When `GOMAXPROCS` is increased above the CPU quota, we see P50 decrease slightly, but see significant increases to P99. We also see that the total RPS handled also decreases. - -When `GOMAXPROCS` is higher than the CPU quota allocated, we also saw significant throttling: - -``` -$ cat /sys/fs/cgroup/cpu,cpuacct/system.slice/[...]/cpu.stat -nr_periods 42227334 -nr_throttled 131923 -throttled_time 88613212216618 -``` - -Once `GOMAXPROCS` was reduced to match the CPU quota, we saw no CPU throttling. - -## Development Status: Stable - -All APIs are finalized, and no breaking changes will be made in the 1.x series -of releases. Users of semver-aware dependency management systems should pin -automaxprocs to `^1`. - -## Contributing - -We encourage and support an active, healthy community of contributors — -including you! Details are in the [contribution guide](CONTRIBUTING.md) and -the [code of conduct](CODE_OF_CONDUCT.md). The automaxprocs maintainers keep -an eye on issues and pull requests, but you can also report any negative -conduct to oss-conduct@uber.com. That email list is a private, safe space; -even the automaxprocs maintainers don't have access, so don't hesitate to hold -us to a high standard. - -
- -Released under the [MIT License](LICENSE). - -[doc-img]: https://godoc.org/go.uber.org/automaxprocs?status.svg -[doc]: https://godoc.org/go.uber.org/automaxprocs -[ci-img]: https://github.com/uber-go/automaxprocs/actions/workflows/go.yml/badge.svg -[ci]: https://github.com/uber-go/automaxprocs/actions/workflows/go.yml -[cov-img]: https://codecov.io/gh/uber-go/automaxprocs/branch/master/graph/badge.svg -[cov]: https://codecov.io/gh/uber-go/automaxprocs - - diff --git a/vendor/go.uber.org/automaxprocs/automaxprocs.go b/vendor/go.uber.org/automaxprocs/automaxprocs.go deleted file mode 100644 index 69946a3e..00000000 --- a/vendor/go.uber.org/automaxprocs/automaxprocs.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2017 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -// Package automaxprocs automatically sets GOMAXPROCS to match the Linux -// container CPU quota, if any. -package automaxprocs // import "go.uber.org/automaxprocs" - -import ( - "log" - - "go.uber.org/automaxprocs/maxprocs" -) - -func init() { - maxprocs.Set(maxprocs.Logger(log.Printf)) -} diff --git a/vendor/go.uber.org/mock/mockgen/deprecated.go b/vendor/go.uber.org/mock/mockgen/deprecated.go deleted file mode 100644 index 0b45a2e3..00000000 --- a/vendor/go.uber.org/mock/mockgen/deprecated.go +++ /dev/null @@ -1,41 +0,0 @@ -package main - -import ( - "flag" - "log" - "os" -) - -const ( - deprecatedFlagProgOnly = "prog_only" - deprecatedFlagExecOnly = "exec_only" -) - -var ( - _ = flag.Bool("prog_only", false, "DEPRECATED (reflect mode) Only generate the reflection program; write it to stdout and exit.") - _ = flag.String("exec_only", "", "DEPRECATED (reflect mode) If set, execute this reflection program.") -) - -// notifyAboutDeprecatedFlags prints a warning message for a deprecated flags if they are set. -func notifyAboutDeprecatedFlags() { - const resetColorPostfix = "\033[0m" - logger := initWarningLogger() - - flag.Visit(func(f *flag.Flag) { - switch f.Name { - case deprecatedFlagProgOnly: - logger.Println("The -prog_only flag is deprecated and has no effect.", resetColorPostfix) - case deprecatedFlagExecOnly: - logger.Println("The -exec_only flag is deprecated and has no effect.", resetColorPostfix) - } - }) -} - -func initWarningLogger() *log.Logger { - const ( - yellowColor = "\033[33m" - warningPrefix = yellowColor + "WARNING: " - ) - - return log.New(os.Stdout, warningPrefix, log.Ldate|log.Ltime) -} diff --git a/vendor/go.uber.org/mock/mockgen/generic.go b/vendor/go.uber.org/mock/mockgen/generic.go deleted file mode 100644 index c2289c2a..00000000 --- a/vendor/go.uber.org/mock/mockgen/generic.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "errors" - "fmt" - "go/ast" - "go/token" - - "go.uber.org/mock/mockgen/model" -) - -func getTypeSpecTypeParams(ts *ast.TypeSpec) []*ast.Field { - if ts == nil || ts.TypeParams == nil { - return nil - } - return ts.TypeParams.List -} - -func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]model.Type) (model.Type, error) { - switch v := typ.(type) { - case *ast.IndexExpr: - m, err := p.parseType(pkg, v.X, tps) - if err != nil { - return nil, err - } - nm, ok := m.(*model.NamedType) - if !ok { - return m, nil - } - t, err := p.parseType(pkg, v.Index, tps) - if err != nil { - return nil, err - } - nm.TypeParams = &model.TypeParametersType{TypeParameters: []model.Type{t}} - return m, nil - case *ast.IndexListExpr: - m, err := p.parseType(pkg, v.X, tps) - if err != nil { - return nil, err - } - nm, ok := m.(*model.NamedType) - if !ok { - return m, nil - } - var ts []model.Type - for _, expr := range v.Indices { - t, err := p.parseType(pkg, expr, tps) - if err != nil { - return nil, err - } - ts = append(ts, t) - } - nm.TypeParams = &model.TypeParametersType{TypeParameters: ts} - return m, nil - } - return nil, nil -} - -func (p *fileParser) parseGenericMethod(field *ast.Field, it *namedInterface, iface *model.Interface, pkg string, tps map[string]model.Type) ([]*model.Method, error) { - var indices []ast.Expr - var typ ast.Expr - switch v := field.Type.(type) { - case *ast.IndexExpr: - indices = []ast.Expr{v.Index} - typ = v.X - case *ast.IndexListExpr: - indices = v.Indices - typ = v.X - case *ast.UnaryExpr: - if v.Op == token.TILDE { - return nil, errConstraintInterface - } - return nil, fmt.Errorf("~T may only appear as constraint for %T", field.Type) - case *ast.BinaryExpr: - if v.Op == token.OR { - return nil, errConstraintInterface - } - return nil, fmt.Errorf("A|B may only appear as constraint for %T", field.Type) - default: - return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type) - } - - nf := &ast.Field{ - Doc: field.Comment, - Names: field.Names, - Type: typ, - Tag: field.Tag, - Comment: field.Comment, - } - - it.embeddedInstTypeParams = indices - - return p.parseMethod(nf, it, iface, pkg, tps) -} - -var errConstraintInterface = errors.New("interface contains constraints") diff --git a/vendor/go.uber.org/mock/mockgen/gob.go b/vendor/go.uber.org/mock/mockgen/gob.go deleted file mode 100644 index b5ab0661..00000000 --- a/vendor/go.uber.org/mock/mockgen/gob.go +++ /dev/null @@ -1,21 +0,0 @@ -package main - -import ( - "encoding/gob" - "os" - - "go.uber.org/mock/mockgen/model" -) - -func gobMode(path string) (*model.Package, error) { - in, err := os.Open(path) - if err != nil { - return nil, err - } - defer in.Close() - var pkg model.Package - if err := gob.NewDecoder(in).Decode(&pkg); err != nil { - return nil, err - } - return &pkg, nil -} diff --git a/vendor/go.uber.org/mock/mockgen/mockgen.go b/vendor/go.uber.org/mock/mockgen/mockgen.go deleted file mode 100644 index 79cce84b..00000000 --- a/vendor/go.uber.org/mock/mockgen/mockgen.go +++ /dev/null @@ -1,920 +0,0 @@ -// Copyright 2010 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// MockGen generates mock implementations of Go interfaces. -package main - -// TODO: This does not support recursive embedded interfaces. -// TODO: This does not support embedding package-local interfaces in a separate file. - -import ( - "bytes" - "encoding/json" - "errors" - "flag" - "fmt" - "go/token" - "io" - "log" - "os" - "os/exec" - "path" - "path/filepath" - "runtime" - "sort" - "strconv" - "strings" - "unicode" - - "golang.org/x/mod/modfile" - toolsimports "golang.org/x/tools/imports" - - "go.uber.org/mock/mockgen/model" -) - -const ( - gomockImportPath = "go.uber.org/mock/gomock" -) - -var ( - version = "" - commit = "none" - date = "unknown" -) - -var ( - source = flag.String("source", "", "(source mode) Input Go source file; enables source mode.") - destination = flag.String("destination", "", "Output file; defaults to stdout.") - mockNames = flag.String("mock_names", "", "Comma-separated interfaceName=mockName pairs of explicit mock names to use. Mock names default to 'Mock'+ interfaceName suffix.") - packageOut = flag.String("package", "", "Package of the generated code; defaults to the package of the input with a 'mock_' prefix.") - selfPackage = flag.String("self_package", "", "The full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. This can happen if the mock's package is set to one of its inputs (usually the main one) and the output is stdio so mockgen cannot detect the final output package. Setting this flag will then tell mockgen which import to exclude.") - writeCmdComment = flag.Bool("write_command_comment", true, "Writes the command used as a comment if true.") - writePkgComment = flag.Bool("write_package_comment", true, "Writes package documentation comment (godoc) if true.") - writeSourceComment = flag.Bool("write_source_comment", true, "Writes original file (source mode) or interface names (package mode) comment if true.") - writeGenerateDirective = flag.Bool("write_generate_directive", false, "Add //go:generate directive to regenerate the mock") - copyrightFile = flag.String("copyright_file", "", "Copyright file used to add copyright header") - buildConstraint = flag.String("build_constraint", "", "If non-empty, added as //go:build ") - typed = flag.Bool("typed", false, "Generate Type-safe 'Return', 'Do', 'DoAndReturn' function") - imports = flag.String("imports", "", "(source mode) Comma-separated name=path pairs of explicit imports to use.") - auxFiles = flag.String("aux_files", "", "(source mode) Comma-separated pkg=path pairs of auxiliary Go source files.") - excludeInterfaces = flag.String("exclude_interfaces", "", "(source mode) Comma-separated names of interfaces to be excluded") - modelGob = flag.String("model_gob", "", "Skip package/source loading entirely and use the gob encoded model.Package at the given path") - - debugParser = flag.Bool("debug_parser", false, "Print out parser results only.") - showVersion = flag.Bool("version", false, "Print version.") -) - -func main() { - flag.Usage = usage - flag.Parse() - - notifyAboutDeprecatedFlags() - - if *showVersion { - printVersion() - return - } - - var pkg *model.Package - var err error - var packageName string - if *modelGob != "" { - pkg, err = gobMode(*modelGob) - } else if *source != "" { - pkg, err = sourceMode(*source) - } else { - if flag.NArg() != 2 { - usage() - log.Fatal("Expected exactly two arguments") - } - packageName = flag.Arg(0) - interfaces := strings.Split(flag.Arg(1), ",") - if packageName == "." { - dir, err := os.Getwd() - if err != nil { - log.Fatalf("Get current directory failed: %v", err) - } - packageName, err = packageNameOfDir(dir) - if err != nil { - log.Fatalf("Parse package name failed: %v", err) - } - } - parser := packageModeParser{} - pkg, err = parser.parsePackage(packageName, interfaces) - } - if err != nil { - log.Fatalf("Loading input failed: %v", err) - } - - if *debugParser { - pkg.Print(os.Stdout) - return - } - - outputPackageName := *packageOut - if outputPackageName == "" { - // pkg.Name in package mode is the base name of the import path, - // which might have characters that are illegal to have in package names. - outputPackageName = "mock_" + sanitize(pkg.Name) - } - - // outputPackagePath represents the fully qualified name of the package of - // the generated code. Its purposes are to prevent the module from importing - // itself and to prevent qualifying type names that come from its own - // package (i.e. if there is a type called X then we want to print "X" not - // "package.X" since "package" is this package). This can happen if the mock - // is output into an already existing package. - outputPackagePath := *selfPackage - if outputPackagePath == "" && *destination != "" { - dstPath, err := filepath.Abs(filepath.Dir(*destination)) - if err == nil { - pkgPath, err := parsePackageImport(dstPath) - if err == nil { - outputPackagePath = pkgPath - } else { - log.Println("Unable to infer -self_package from destination file path:", err) - } - } else { - log.Println("Unable to determine destination file path:", err) - } - } - - g := &generator{ - buildConstraint: *buildConstraint, - } - if *source != "" { - g.filename = *source - } else { - g.srcPackage = packageName - g.srcInterfaces = flag.Arg(1) - } - g.destination = *destination - - if *mockNames != "" { - g.mockNames = parseMockNames(*mockNames) - } - if *copyrightFile != "" { - header, err := os.ReadFile(*copyrightFile) - if err != nil { - log.Fatalf("Failed reading copyright file: %v", err) - } - - g.copyrightHeader = string(header) - } - if err := g.Generate(pkg, outputPackageName, outputPackagePath); err != nil { - log.Fatalf("Failed generating mock: %v", err) - } - output := g.Output() - dst := os.Stdout - if len(*destination) > 0 { - if err := os.MkdirAll(filepath.Dir(*destination), os.ModePerm); err != nil { - log.Fatalf("Unable to create directory: %v", err) - } - existing, err := os.ReadFile(*destination) - if err != nil && !errors.Is(err, os.ErrNotExist) { - log.Fatalf("Failed reading pre-exiting destination file: %v", err) - } - if len(existing) == len(output) && bytes.Equal(existing, output) { - return - } - f, err := os.Create(*destination) - if err != nil { - log.Fatalf("Failed opening destination file: %v", err) - } - defer f.Close() - dst = f - } - if _, err := dst.Write(output); err != nil { - log.Fatalf("Failed writing to destination: %v", err) - } -} - -func parseMockNames(names string) map[string]string { - mocksMap := make(map[string]string) - for _, kv := range strings.Split(names, ",") { - parts := strings.SplitN(kv, "=", 2) - if len(parts) != 2 || parts[1] == "" { - log.Fatalf("bad mock names spec: %v", kv) - } - mocksMap[parts[0]] = parts[1] - } - return mocksMap -} - -func parseExcludeInterfaces(names string) map[string]struct{} { - splitNames := strings.Split(names, ",") - namesSet := make(map[string]struct{}, len(splitNames)) - for _, name := range splitNames { - if name == "" { - continue - } - - namesSet[name] = struct{}{} - } - - if len(namesSet) == 0 { - return nil - } - - return namesSet -} - -func usage() { - _, _ = io.WriteString(os.Stderr, usageText) - flag.PrintDefaults() -} - -const usageText = `mockgen has two modes of operation: source and package. - -Source mode generates mock interfaces from a source file. -It is enabled by using the -source flag. Other flags that -may be useful in this mode are -imports, -aux_files and -exclude_interfaces. -Example: - mockgen -source=foo.go [other options] - -Package mode works by specifying the package and interface names. -It is enabled by passing two non-flag arguments: an import path, and a -comma-separated list of symbols. -You can use "." to refer to the current path's package. -Example: - mockgen database/sql/driver Conn,Driver - mockgen . SomeInterface - -` - -type generator struct { - buf bytes.Buffer - indent string - mockNames map[string]string // may be empty - filename string // may be empty - destination string // may be empty - srcPackage, srcInterfaces string // may be empty - copyrightHeader string - buildConstraint string // may be empty - - packageMap map[string]string // map from import path to package name -} - -func (g *generator) p(format string, args ...any) { - _, _ = fmt.Fprintf(&g.buf, g.indent+format+"\n", args...) -} - -func (g *generator) in() { - g.indent += "\t" -} - -func (g *generator) out() { - if len(g.indent) > 0 { - g.indent = g.indent[0 : len(g.indent)-1] - } -} - -// sanitize cleans up a string to make a suitable package name. -func sanitize(s string) string { - t := "" - for _, r := range s { - if t == "" { - if unicode.IsLetter(r) || r == '_' { - t += string(r) - continue - } - } else { - if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' { - t += string(r) - continue - } - } - t += "_" - } - if t == "_" { - t = "x" - } - return t -} - -func (g *generator) Generate(pkg *model.Package, outputPkgName string, outputPackagePath string) error { - if outputPkgName != pkg.Name && *selfPackage == "" { - // reset outputPackagePath if it's not passed in through -self_package - outputPackagePath = "" - } - - if g.copyrightHeader != "" { - lines := strings.Split(g.copyrightHeader, "\n") - for _, line := range lines { - g.p("// %s", line) - } - g.p("") - } - - if g.buildConstraint != "" { - g.p("//go:build %s", g.buildConstraint) - // https://pkg.go.dev/cmd/go#hdr-Build_constraints:~:text=a%20build%20constraint%20should%20be%20followed%20by%20a%20blank%20line - g.p("") - } - - g.p("// Code generated by MockGen. DO NOT EDIT.") - if *writeSourceComment { - if g.filename != "" { - g.p("// Source: %v", g.filename) - } else { - g.p("// Source: %v (interfaces: %v)", g.srcPackage, g.srcInterfaces) - } - } - if *writeCmdComment { - g.p("//") - g.p("// Generated by this command:") - g.p("//") - // only log the name of the executable, not the full path - name := filepath.Base(os.Args[0]) - if runtime.GOOS == "windows" { - name = strings.TrimSuffix(name, ".exe") - } - g.p("//\t%v", strings.Join(append([]string{name}, os.Args[1:]...), " ")) - g.p("//") - } - - // Get all required imports, and generate unique names for them all. - im := pkg.Imports() - im[gomockImportPath] = true - - // Only import reflect if it's used. We only use reflect in mocked methods - // so only import if any of the mocked interfaces have methods. - for _, intf := range pkg.Interfaces { - if len(intf.Methods) > 0 { - im["reflect"] = true - break - } - } - - // Sort keys to make import alias generation predictable - sortedPaths := make([]string, len(im)) - x := 0 - for pth := range im { - sortedPaths[x] = pth - x++ - } - sort.Strings(sortedPaths) - - packagesName := createPackageMap(sortedPaths) - - definedImports := make(map[string]string, len(im)) - if *imports != "" { - for _, kv := range strings.Split(*imports, ",") { - eq := strings.Index(kv, "=") - if k, v := kv[:eq], kv[eq+1:]; k != "." { - definedImports[v] = k - } - } - } - - g.packageMap = make(map[string]string, len(im)) - localNames := make(map[string]bool, len(im)) - for _, pth := range sortedPaths { - base, ok := packagesName[pth] - if !ok { - base = sanitize(path.Base(pth)) - } - - // Local names for an imported package can usually be the basename of the import path. - // A couple of situations don't permit that, such as duplicate local names - // (e.g. importing "html/template" and "text/template"), or where the basename is - // a keyword (e.g. "foo/case") or when defining a name for that by using the -imports flag. - // try base0, base1, ... - pkgName := base - - if _, ok := definedImports[pth]; ok { - pkgName = definedImports[pth] - } - - i := 0 - for localNames[pkgName] || token.Lookup(pkgName).IsKeyword() || pkgName == "any" { - pkgName = base + strconv.Itoa(i) - i++ - } - - // Avoid importing package if source pkg == output pkg - if pth == pkg.PkgPath && outputPackagePath == pkg.PkgPath { - continue - } - - g.packageMap[pth] = pkgName - localNames[pkgName] = true - } - - // Ensure there is an empty line between “generated by” block and - // package documentation comments to follow the recommendations: - // https://go.dev/wiki/CodeReviewComments#package-comments - // That is, “generated by” should not be a package comment. - g.p("") - - if *writePkgComment { - g.p("// Package %v is a generated GoMock package.", outputPkgName) - } - g.p("package %v", outputPkgName) - g.p("") - g.p("import (") - g.in() - for pkgPath, pkgName := range g.packageMap { - if pkgPath == outputPackagePath { - continue - } - g.p("%v %q", pkgName, pkgPath) - } - for _, pkgPath := range pkg.DotImports { - g.p(". %q", pkgPath) - } - g.out() - g.p(")") - - if *writeGenerateDirective { - g.p("//go:generate %v", strings.Join(os.Args, " ")) - } - - for _, intf := range pkg.Interfaces { - if err := g.GenerateMockInterface(intf, outputPackagePath); err != nil { - return err - } - } - - return nil -} - -// The name of the mock type to use for the given interface identifier. -func (g *generator) mockName(typeName string) string { - if mockName, ok := g.mockNames[typeName]; ok { - return mockName - } - - return "Mock" + typeName -} - -// formattedTypeParams returns a long and short form of type param info used for -// printing. If analyzing a interface with type param [I any, O any] the result -// will be: -// "[I any, O any]", "[I, O]" -func (g *generator) formattedTypeParams(it *model.Interface, pkgOverride string) (string, string) { - if len(it.TypeParams) == 0 { - return "", "" - } - var long, short strings.Builder - long.WriteString("[") - short.WriteString("[") - for i, v := range it.TypeParams { - if i != 0 { - long.WriteString(", ") - short.WriteString(", ") - } - long.WriteString(v.Name) - short.WriteString(v.Name) - long.WriteString(fmt.Sprintf(" %s", v.Type.String(g.packageMap, pkgOverride))) - } - long.WriteString("]") - short.WriteString("]") - return long.String(), short.String() -} - -func (g *generator) GenerateMockInterface(intf *model.Interface, outputPackagePath string) error { - mockType := g.mockName(intf.Name) - longTp, shortTp := g.formattedTypeParams(intf, outputPackagePath) - - g.p("") - g.p("// %v is a mock of %v interface.", mockType, intf.Name) - g.p("type %v%v struct {", mockType, longTp) - g.in() - g.p("ctrl *gomock.Controller") - g.p("recorder *%vMockRecorder%v", mockType, shortTp) - g.p("isgomock struct{}") - g.out() - g.p("}") - g.p("") - - g.p("// %vMockRecorder is the mock recorder for %v.", mockType, mockType) - g.p("type %vMockRecorder%v struct {", mockType, longTp) - g.in() - g.p("mock *%v%v", mockType, shortTp) - g.out() - g.p("}") - g.p("") - - g.p("// New%v creates a new mock instance.", mockType) - g.p("func New%v%v(ctrl *gomock.Controller) *%v%v {", mockType, longTp, mockType, shortTp) - g.in() - g.p("mock := &%v%v{ctrl: ctrl}", mockType, shortTp) - g.p("mock.recorder = &%vMockRecorder%v{mock}", mockType, shortTp) - g.p("return mock") - g.out() - g.p("}") - g.p("") - - // XXX: possible name collision here if someone has EXPECT in their interface. - g.p("// EXPECT returns an object that allows the caller to indicate expected use.") - g.p("func (m *%v%v) EXPECT() *%vMockRecorder%v {", mockType, shortTp, mockType, shortTp) - g.in() - g.p("return m.recorder") - g.out() - g.p("}") - - g.GenerateMockMethods(mockType, intf, outputPackagePath, longTp, shortTp, *typed) - - return nil -} - -type byMethodName []*model.Method - -func (b byMethodName) Len() int { return len(b) } -func (b byMethodName) Swap(i, j int) { b[i], b[j] = b[j], b[i] } -func (b byMethodName) Less(i, j int) bool { return b[i].Name < b[j].Name } - -func (g *generator) GenerateMockMethods(mockType string, intf *model.Interface, pkgOverride, longTp, shortTp string, typed bool) { - sort.Sort(byMethodName(intf.Methods)) - for _, m := range intf.Methods { - g.p("") - _ = g.GenerateMockMethod(mockType, m, pkgOverride, shortTp) - g.p("") - _ = g.GenerateMockRecorderMethod(intf, m, shortTp, typed) - if typed { - g.p("") - _ = g.GenerateMockReturnCallMethod(intf, m, pkgOverride, longTp, shortTp) - } - } -} - -func makeArgString(argNames, argTypes []string) string { - args := make([]string, len(argNames)) - for i, name := range argNames { - // specify the type only once for consecutive args of the same type - if i+1 < len(argTypes) && argTypes[i] == argTypes[i+1] { - args[i] = name - } else { - args[i] = name + " " + argTypes[i] - } - } - return strings.Join(args, ", ") -} - -// GenerateMockMethod generates a mock method implementation. -// If non-empty, pkgOverride is the package in which unqualified types reside. -func (g *generator) GenerateMockMethod(mockType string, m *model.Method, pkgOverride, shortTp string) error { - argNames := g.getArgNames(m, true /* in */) - argTypes := g.getArgTypes(m, pkgOverride, true /* in */) - argString := makeArgString(argNames, argTypes) - - rets := make([]string, len(m.Out)) - for i, p := range m.Out { - rets[i] = p.Type.String(g.packageMap, pkgOverride) - } - retString := strings.Join(rets, ", ") - if len(rets) > 1 { - retString = "(" + retString + ")" - } - if retString != "" { - retString = " " + retString - } - - ia := newIdentifierAllocator(argNames) - idRecv := ia.allocateIdentifier("m") - - g.p("// %v mocks base method.", m.Name) - g.p("func (%v *%v%v) %v(%v)%v {", idRecv, mockType, shortTp, m.Name, argString, retString) - g.in() - g.p("%s.ctrl.T.Helper()", idRecv) - - var callArgs string - if m.Variadic == nil { - if len(argNames) > 0 { - callArgs = ", " + strings.Join(argNames, ", ") - } - } else { - // Non-trivial. The generated code must build a []any, - // but the variadic argument may be any type. - idVarArgs := ia.allocateIdentifier("varargs") - idVArg := ia.allocateIdentifier("a") - g.p("%s := []any{%s}", idVarArgs, strings.Join(argNames[:len(argNames)-1], ", ")) - g.p("for _, %s := range %s {", idVArg, argNames[len(argNames)-1]) - g.in() - g.p("%s = append(%s, %s)", idVarArgs, idVarArgs, idVArg) - g.out() - g.p("}") - callArgs = ", " + idVarArgs + "..." - } - if len(m.Out) == 0 { - g.p(`%v.ctrl.Call(%v, %q%v)`, idRecv, idRecv, m.Name, callArgs) - } else { - idRet := ia.allocateIdentifier("ret") - g.p(`%v := %v.ctrl.Call(%v, %q%v)`, idRet, idRecv, idRecv, m.Name, callArgs) - - // Go does not allow "naked" type assertions on nil values, so we use the two-value form here. - // The value of that is either (x.(T), true) or (Z, false), where Z is the zero value for T. - // Happily, this coincides with the semantics we want here. - retNames := make([]string, len(rets)) - for i, t := range rets { - retNames[i] = ia.allocateIdentifier(fmt.Sprintf("ret%d", i)) - g.p("%s, _ := %s[%d].(%s)", retNames[i], idRet, i, t) - } - g.p("return " + strings.Join(retNames, ", ")) - } - - g.out() - g.p("}") - return nil -} - -func (g *generator) GenerateMockRecorderMethod(intf *model.Interface, m *model.Method, shortTp string, typed bool) error { - mockType := g.mockName(intf.Name) - argNames := g.getArgNames(m, true) - - var argString string - if m.Variadic == nil { - argString = strings.Join(argNames, ", ") - } else { - argString = strings.Join(argNames[:len(argNames)-1], ", ") - } - if argString != "" { - argString += " any" - } - - if m.Variadic != nil { - if argString != "" { - argString += ", " - } - argString += fmt.Sprintf("%s ...any", argNames[len(argNames)-1]) - } - - ia := newIdentifierAllocator(argNames) - idRecv := ia.allocateIdentifier("mr") - - g.p("// %v indicates an expected call of %v.", m.Name, m.Name) - if typed { - g.p("func (%s *%vMockRecorder%v) %v(%v) *%s%sCall%s {", idRecv, mockType, shortTp, m.Name, argString, mockType, m.Name, shortTp) - } else { - g.p("func (%s *%vMockRecorder%v) %v(%v) *gomock.Call {", idRecv, mockType, shortTp, m.Name, argString) - } - - g.in() - g.p("%s.mock.ctrl.T.Helper()", idRecv) - - var callArgs string - if m.Variadic == nil { - if len(argNames) > 0 { - callArgs = ", " + strings.Join(argNames, ", ") - } - } else { - if len(argNames) == 1 { - // Easy: just use ... to push the arguments through. - callArgs = ", " + argNames[0] + "..." - } else { - // Hard: create a temporary slice. - idVarArgs := ia.allocateIdentifier("varargs") - g.p("%s := append([]any{%s}, %s...)", - idVarArgs, - strings.Join(argNames[:len(argNames)-1], ", "), - argNames[len(argNames)-1]) - callArgs = ", " + idVarArgs + "..." - } - } - if typed { - g.p(`call := %s.mock.ctrl.RecordCallWithMethodType(%s.mock, "%s", reflect.TypeOf((*%s%s)(nil).%s)%s)`, idRecv, idRecv, m.Name, mockType, shortTp, m.Name, callArgs) - g.p(`return &%s%sCall%s{Call: call}`, mockType, m.Name, shortTp) - } else { - g.p(`return %s.mock.ctrl.RecordCallWithMethodType(%s.mock, "%s", reflect.TypeOf((*%s%s)(nil).%s)%s)`, idRecv, idRecv, m.Name, mockType, shortTp, m.Name, callArgs) - } - - g.out() - g.p("}") - return nil -} - -func (g *generator) GenerateMockReturnCallMethod(intf *model.Interface, m *model.Method, pkgOverride, longTp, shortTp string) error { - mockType := g.mockName(intf.Name) - argNames := g.getArgNames(m, true /* in */) - retNames := g.getArgNames(m, false /* out */) - argTypes := g.getArgTypes(m, pkgOverride, true /* in */) - retTypes := g.getArgTypes(m, pkgOverride, false /* out */) - argString := strings.Join(argTypes, ", ") - - rets := make([]string, len(m.Out)) - for i, p := range m.Out { - rets[i] = p.Type.String(g.packageMap, pkgOverride) - } - - var retString string - switch { - case len(rets) == 1: - retString = " " + rets[0] - case len(rets) > 1: - retString = " (" + strings.Join(rets, ", ") + ")" - } - - ia := newIdentifierAllocator(argNames) - idRecv := ia.allocateIdentifier("c") - - recvStructName := mockType + m.Name - - g.p("// %s%sCall wrap *gomock.Call", mockType, m.Name) - g.p("type %s%sCall%s struct{", mockType, m.Name, longTp) - g.in() - g.p("*gomock.Call") - g.out() - g.p("}") - - g.p("// Return rewrite *gomock.Call.Return") - g.p("func (%s *%sCall%s) Return(%v) *%sCall%s {", idRecv, recvStructName, shortTp, makeArgString(retNames, retTypes), recvStructName, shortTp) - g.in() - var retArgs string - if len(retNames) > 0 { - retArgs = strings.Join(retNames, ", ") - } - g.p(`%s.Call = %v.Call.Return(%v)`, idRecv, idRecv, retArgs) - g.p("return %s", idRecv) - g.out() - g.p("}") - - g.p("// Do rewrite *gomock.Call.Do") - g.p("func (%s *%sCall%s) Do(f func(%v)%v) *%sCall%s {", idRecv, recvStructName, shortTp, argString, retString, recvStructName, shortTp) - g.in() - g.p(`%s.Call = %v.Call.Do(f)`, idRecv, idRecv) - g.p("return %s", idRecv) - g.out() - g.p("}") - - g.p("// DoAndReturn rewrite *gomock.Call.DoAndReturn") - g.p("func (%s *%sCall%s) DoAndReturn(f func(%v)%v) *%sCall%s {", idRecv, recvStructName, shortTp, argString, retString, recvStructName, shortTp) - g.in() - g.p(`%s.Call = %v.Call.DoAndReturn(f)`, idRecv, idRecv) - g.p("return %s", idRecv) - g.out() - g.p("}") - return nil -} - -// nameExistsAsPackage returns true if the name exists as a package name. -// This is used to avoid name collisions when generating mock method arguments. -func (g *generator) nameExistsAsPackage(name string) bool { - for _, symbolName := range g.packageMap { - if symbolName == name { - return true - } - } - return false -} - -func (g *generator) getArgNames(m *model.Method, in bool) []string { - var params []*model.Parameter - if in { - params = m.In - } else { - params = m.Out - } - argNames := make([]string, len(params)) - - for i, p := range params { - name := p.Name - - if name == "" || name == "_" || g.nameExistsAsPackage(name) { - name = fmt.Sprintf("arg%d", i) - } - argNames[i] = name - } - if m.Variadic != nil && in { - name := m.Variadic.Name - - if name == "" || g.nameExistsAsPackage(name) { - name = fmt.Sprintf("arg%d", len(params)) - } - argNames = append(argNames, name) - } - return argNames -} - -func (g *generator) getArgTypes(m *model.Method, pkgOverride string, in bool) []string { - var params []*model.Parameter - if in { - params = m.In - } else { - params = m.Out - } - argTypes := make([]string, len(params)) - for i, p := range params { - argTypes[i] = p.Type.String(g.packageMap, pkgOverride) - } - if m.Variadic != nil { - argTypes = append(argTypes, "..."+m.Variadic.Type.String(g.packageMap, pkgOverride)) - } - return argTypes -} - -type identifierAllocator map[string]struct{} - -func newIdentifierAllocator(taken []string) identifierAllocator { - a := make(identifierAllocator, len(taken)) - for _, s := range taken { - a[s] = struct{}{} - } - return a -} - -func (o identifierAllocator) allocateIdentifier(want string) string { - id := want - for i := 2; ; i++ { - if _, ok := o[id]; !ok { - o[id] = struct{}{} - return id - } - id = want + "_" + strconv.Itoa(i) - } -} - -// Output returns the generator's output, formatted in the standard Go style. -func (g *generator) Output() []byte { - src, err := toolsimports.Process(g.destination, g.buf.Bytes(), nil) - if err != nil { - log.Fatalf("Failed to format generated source code: %s\n%s", err, g.buf.String()) - } - return src -} - -// createPackageMap returns a map of import path to package name -// for specified importPaths. -func createPackageMap(importPaths []string) map[string]string { - var pkg struct { - Name string - ImportPath string - } - pkgMap := make(map[string]string) - b := bytes.NewBuffer(nil) - args := []string{"list", "-json=ImportPath,Name"} - args = append(args, importPaths...) - cmd := exec.Command("go", args...) - cmd.Stdout = b - cmd.Run() - dec := json.NewDecoder(b) - for dec.More() { - err := dec.Decode(&pkg) - if err != nil { - log.Printf("failed to decode 'go list' output: %v", err) - continue - } - pkgMap[pkg.ImportPath] = pkg.Name - } - return pkgMap -} - -func printVersion() { - if version != "" { - fmt.Printf("v%s\nCommit: %s\nDate: %s\n", version, commit, date) - } else { - printModuleVersion() - } -} - -// parseImportPackage get package import path via source file -// an alternative implementation is to use: -// cfg := &packages.Config{Mode: packages.NeedName, Tests: true, Dir: srcDir} -// pkgs, err := packages.Load(cfg, "file="+source) -// However, it will call "go list" and slow down the performance -func parsePackageImport(srcDir string) (string, error) { - moduleMode := os.Getenv("GO111MODULE") - // trying to find the module - if moduleMode != "off" { - currentDir := srcDir - for { - dat, err := os.ReadFile(filepath.Join(currentDir, "go.mod")) - if os.IsNotExist(err) { - if currentDir == filepath.Dir(currentDir) { - // at the root - break - } - currentDir = filepath.Dir(currentDir) - continue - } else if err != nil { - return "", err - } - modulePath := modfile.ModulePath(dat) - return filepath.ToSlash(filepath.Join(modulePath, strings.TrimPrefix(srcDir, currentDir))), nil - } - } - // fall back to GOPATH mode - goPaths := os.Getenv("GOPATH") - if goPaths == "" { - return "", fmt.Errorf("GOPATH is not set") - } - goPathList := strings.Split(goPaths, string(os.PathListSeparator)) - for _, goPath := range goPathList { - sourceRoot := filepath.Join(goPath, "src") + string(os.PathSeparator) - if strings.HasPrefix(srcDir, sourceRoot) { - return filepath.ToSlash(strings.TrimPrefix(srcDir, sourceRoot)), nil - } - } - return "", errOutsideGoPath -} diff --git a/vendor/go.uber.org/mock/mockgen/model/model.go b/vendor/go.uber.org/mock/mockgen/model/model.go deleted file mode 100644 index 853dbf2d..00000000 --- a/vendor/go.uber.org/mock/mockgen/model/model.go +++ /dev/null @@ -1,533 +0,0 @@ -// Copyright 2012 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package model contains the data model necessary for generating mock implementations. -package model - -import ( - "encoding/gob" - "fmt" - "io" - "reflect" - "strings" -) - -// pkgPath is the importable path for package model -const pkgPath = "go.uber.org/mock/mockgen/model" - -// Package is a Go package. It may be a subset. -type Package struct { - Name string - PkgPath string - Interfaces []*Interface - DotImports []string -} - -// Print writes the package name and its exported interfaces. -func (pkg *Package) Print(w io.Writer) { - _, _ = fmt.Fprintf(w, "package %s\n", pkg.Name) - for _, intf := range pkg.Interfaces { - intf.Print(w) - } -} - -// Imports returns the imports needed by the Package as a set of import paths. -func (pkg *Package) Imports() map[string]bool { - im := make(map[string]bool) - for _, intf := range pkg.Interfaces { - intf.addImports(im) - for _, tp := range intf.TypeParams { - tp.Type.addImports(im) - } - } - return im -} - -// Interface is a Go interface. -type Interface struct { - Name string - Methods []*Method - TypeParams []*Parameter -} - -// Print writes the interface name and its methods. -func (intf *Interface) Print(w io.Writer) { - _, _ = fmt.Fprintf(w, "interface %s\n", intf.Name) - for _, m := range intf.Methods { - m.Print(w) - } -} - -func (intf *Interface) addImports(im map[string]bool) { - for _, m := range intf.Methods { - m.addImports(im) - } -} - -// AddMethod adds a new method, de-duplicating by method name. -func (intf *Interface) AddMethod(m *Method) { - for _, me := range intf.Methods { - if me.Name == m.Name { - return - } - } - intf.Methods = append(intf.Methods, m) -} - -// Method is a single method of an interface. -type Method struct { - Name string - In, Out []*Parameter - Variadic *Parameter // may be nil -} - -// Print writes the method name and its signature. -func (m *Method) Print(w io.Writer) { - _, _ = fmt.Fprintf(w, " - method %s\n", m.Name) - if len(m.In) > 0 { - _, _ = fmt.Fprintf(w, " in:\n") - for _, p := range m.In { - p.Print(w) - } - } - if m.Variadic != nil { - _, _ = fmt.Fprintf(w, " ...:\n") - m.Variadic.Print(w) - } - if len(m.Out) > 0 { - _, _ = fmt.Fprintf(w, " out:\n") - for _, p := range m.Out { - p.Print(w) - } - } -} - -func (m *Method) addImports(im map[string]bool) { - for _, p := range m.In { - p.Type.addImports(im) - } - if m.Variadic != nil { - m.Variadic.Type.addImports(im) - } - for _, p := range m.Out { - p.Type.addImports(im) - } -} - -// Parameter is an argument or return parameter of a method. -type Parameter struct { - Name string // may be empty - Type Type -} - -// Print writes a method parameter. -func (p *Parameter) Print(w io.Writer) { - n := p.Name - if n == "" { - n = `""` - } - _, _ = fmt.Fprintf(w, " - %v: %v\n", n, p.Type.String(nil, "")) -} - -// Type is a Go type. -type Type interface { - String(pm map[string]string, pkgOverride string) string - addImports(im map[string]bool) -} - -func init() { - // Call gob.RegisterName with pkgPath as prefix to avoid conflicting with - // github.com/golang/mock/mockgen/model 's registration. - gob.RegisterName(pkgPath+".ArrayType", &ArrayType{}) - gob.RegisterName(pkgPath+".ChanType", &ChanType{}) - gob.RegisterName(pkgPath+".FuncType", &FuncType{}) - gob.RegisterName(pkgPath+".MapType", &MapType{}) - gob.RegisterName(pkgPath+".NamedType", &NamedType{}) - gob.RegisterName(pkgPath+".PointerType", &PointerType{}) - - // Call gob.RegisterName to make sure it has the consistent name registered - // for both gob decoder and encoder. - // - // For a non-pointer type, gob.Register will try to get package full path by - // calling rt.PkgPath() for a name to register. If your project has vendor - // directory, it is possible that PkgPath will get a path like this: - // ../../../vendor/go.uber.org/mock/mockgen/model - gob.RegisterName(pkgPath+".PredeclaredType", PredeclaredType("")) -} - -// ArrayType is an array or slice type. -type ArrayType struct { - Len int // -1 for slices, >= 0 for arrays - Type Type -} - -func (at *ArrayType) String(pm map[string]string, pkgOverride string) string { - s := "[]" - if at.Len > -1 { - s = fmt.Sprintf("[%d]", at.Len) - } - return s + at.Type.String(pm, pkgOverride) -} - -func (at *ArrayType) addImports(im map[string]bool) { at.Type.addImports(im) } - -// ChanType is a channel type. -type ChanType struct { - Dir ChanDir // 0, 1 or 2 - Type Type -} - -func (ct *ChanType) String(pm map[string]string, pkgOverride string) string { - s := ct.Type.String(pm, pkgOverride) - if ct.Dir == RecvDir { - return "<-chan " + s - } - if ct.Dir == SendDir { - return "chan<- " + s - } - return "chan " + s -} - -func (ct *ChanType) addImports(im map[string]bool) { ct.Type.addImports(im) } - -// ChanDir is a channel direction. -type ChanDir int - -// Constants for channel directions. -const ( - RecvDir ChanDir = 1 - SendDir ChanDir = 2 -) - -// FuncType is a function type. -type FuncType struct { - In, Out []*Parameter - Variadic *Parameter // may be nil -} - -func (ft *FuncType) String(pm map[string]string, pkgOverride string) string { - args := make([]string, len(ft.In)) - for i, p := range ft.In { - args[i] = p.Type.String(pm, pkgOverride) - } - if ft.Variadic != nil { - args = append(args, "..."+ft.Variadic.Type.String(pm, pkgOverride)) - } - rets := make([]string, len(ft.Out)) - for i, p := range ft.Out { - rets[i] = p.Type.String(pm, pkgOverride) - } - retString := strings.Join(rets, ", ") - if nOut := len(ft.Out); nOut == 1 { - retString = " " + retString - } else if nOut > 1 { - retString = " (" + retString + ")" - } - return "func(" + strings.Join(args, ", ") + ")" + retString -} - -func (ft *FuncType) addImports(im map[string]bool) { - for _, p := range ft.In { - p.Type.addImports(im) - } - if ft.Variadic != nil { - ft.Variadic.Type.addImports(im) - } - for _, p := range ft.Out { - p.Type.addImports(im) - } -} - -// MapType is a map type. -type MapType struct { - Key, Value Type -} - -func (mt *MapType) String(pm map[string]string, pkgOverride string) string { - return "map[" + mt.Key.String(pm, pkgOverride) + "]" + mt.Value.String(pm, pkgOverride) -} - -func (mt *MapType) addImports(im map[string]bool) { - mt.Key.addImports(im) - mt.Value.addImports(im) -} - -// NamedType is an exported type in a package. -type NamedType struct { - Package string // may be empty - Type string - TypeParams *TypeParametersType -} - -func (nt *NamedType) String(pm map[string]string, pkgOverride string) string { - if pkgOverride == nt.Package { - return nt.Type + nt.TypeParams.String(pm, pkgOverride) - } - prefix := pm[nt.Package] - if prefix != "" { - return prefix + "." + nt.Type + nt.TypeParams.String(pm, pkgOverride) - } - - return nt.Type + nt.TypeParams.String(pm, pkgOverride) -} - -func (nt *NamedType) addImports(im map[string]bool) { - if nt.Package != "" { - im[nt.Package] = true - } - nt.TypeParams.addImports(im) -} - -// PointerType is a pointer to another type. -type PointerType struct { - Type Type -} - -func (pt *PointerType) String(pm map[string]string, pkgOverride string) string { - return "*" + pt.Type.String(pm, pkgOverride) -} -func (pt *PointerType) addImports(im map[string]bool) { pt.Type.addImports(im) } - -// PredeclaredType is a predeclared type such as "int". -type PredeclaredType string - -func (pt PredeclaredType) String(map[string]string, string) string { return string(pt) } -func (pt PredeclaredType) addImports(map[string]bool) {} - -// TypeParametersType contains type parameters for a NamedType. -type TypeParametersType struct { - TypeParameters []Type -} - -func (tp *TypeParametersType) String(pm map[string]string, pkgOverride string) string { - if tp == nil || len(tp.TypeParameters) == 0 { - return "" - } - var sb strings.Builder - sb.WriteString("[") - for i, v := range tp.TypeParameters { - if i != 0 { - sb.WriteString(", ") - } - sb.WriteString(v.String(pm, pkgOverride)) - } - sb.WriteString("]") - return sb.String() -} - -func (tp *TypeParametersType) addImports(im map[string]bool) { - if tp == nil { - return - } - for _, v := range tp.TypeParameters { - v.addImports(im) - } -} - -// The following code is intended to be called by the program generated by ../reflect.go. - -// InterfaceFromInterfaceType returns a pointer to an interface for the -// given reflection interface type. -func InterfaceFromInterfaceType(it reflect.Type) (*Interface, error) { - if it.Kind() != reflect.Interface { - return nil, fmt.Errorf("%v is not an interface", it) - } - intf := &Interface{} - - for i := 0; i < it.NumMethod(); i++ { - mt := it.Method(i) - // TODO: need to skip unexported methods? or just raise an error? - m := &Method{ - Name: mt.Name, - } - - var err error - m.In, m.Variadic, m.Out, err = funcArgsFromType(mt.Type) - if err != nil { - return nil, err - } - - intf.AddMethod(m) - } - - return intf, nil -} - -// t's Kind must be a reflect.Func. -func funcArgsFromType(t reflect.Type) (in []*Parameter, variadic *Parameter, out []*Parameter, err error) { - nin := t.NumIn() - if t.IsVariadic() { - nin-- - } - var p *Parameter - for i := 0; i < nin; i++ { - p, err = parameterFromType(t.In(i)) - if err != nil { - return - } - in = append(in, p) - } - if t.IsVariadic() { - p, err = parameterFromType(t.In(nin).Elem()) - if err != nil { - return - } - variadic = p - } - for i := 0; i < t.NumOut(); i++ { - p, err = parameterFromType(t.Out(i)) - if err != nil { - return - } - out = append(out, p) - } - return -} - -func parameterFromType(t reflect.Type) (*Parameter, error) { - tt, err := typeFromType(t) - if err != nil { - return nil, err - } - return &Parameter{Type: tt}, nil -} - -var errorType = reflect.TypeOf((*error)(nil)).Elem() - -var byteType = reflect.TypeOf(byte(0)) - -func typeFromType(t reflect.Type) (Type, error) { - // Hack workaround for https://golang.org/issue/3853. - // This explicit check should not be necessary. - if t == byteType { - return PredeclaredType("byte"), nil - } - - if imp := t.PkgPath(); imp != "" { - return &NamedType{ - Package: impPath(imp), - Type: t.Name(), - }, nil - } - - // only unnamed or predeclared types after here - - // Lots of types have element types. Let's do the parsing and error checking for all of them. - var elemType Type - switch t.Kind() { - case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice: - var err error - elemType, err = typeFromType(t.Elem()) - if err != nil { - return nil, err - } - } - - switch t.Kind() { - case reflect.Array: - return &ArrayType{ - Len: t.Len(), - Type: elemType, - }, nil - case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, - reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String: - return PredeclaredType(t.Kind().String()), nil - case reflect.Chan: - var dir ChanDir - switch t.ChanDir() { - case reflect.RecvDir: - dir = RecvDir - case reflect.SendDir: - dir = SendDir - } - return &ChanType{ - Dir: dir, - Type: elemType, - }, nil - case reflect.Func: - in, variadic, out, err := funcArgsFromType(t) - if err != nil { - return nil, err - } - return &FuncType{ - In: in, - Out: out, - Variadic: variadic, - }, nil - case reflect.Interface: - // Two special interfaces. - if t.NumMethod() == 0 { - return PredeclaredType("any"), nil - } - if t == errorType { - return PredeclaredType("error"), nil - } - case reflect.Map: - kt, err := typeFromType(t.Key()) - if err != nil { - return nil, err - } - return &MapType{ - Key: kt, - Value: elemType, - }, nil - case reflect.Ptr: - return &PointerType{ - Type: elemType, - }, nil - case reflect.Slice: - return &ArrayType{ - Len: -1, - Type: elemType, - }, nil - case reflect.Struct: - if t.NumField() == 0 { - return PredeclaredType("struct{}"), nil - } - } - - // TODO: Struct, UnsafePointer - return nil, fmt.Errorf("can't yet turn %v (%v) into a model.Type", t, t.Kind()) -} - -// impPath sanitizes the package path returned by `PkgPath` method of a reflect Type so that -// it is importable. PkgPath might return a path that includes "vendor". These paths do not -// compile, so we need to remove everything up to and including "/vendor/". -// See https://github.com/golang/go/issues/12019. -func impPath(imp string) string { - if strings.HasPrefix(imp, "vendor/") { - imp = "/" + imp - } - if i := strings.LastIndex(imp, "/vendor/"); i != -1 { - imp = imp[i+len("/vendor/"):] - } - return imp -} - -// ErrorInterface represent built-in error interface. -var ErrorInterface = Interface{ - Name: "error", - Methods: []*Method{ - { - Name: "Error", - Out: []*Parameter{ - { - Name: "", - Type: PredeclaredType("string"), - }, - }, - }, - }, -} diff --git a/vendor/go.uber.org/mock/mockgen/package_mode.go b/vendor/go.uber.org/mock/mockgen/package_mode.go deleted file mode 100644 index acbe487f..00000000 --- a/vendor/go.uber.org/mock/mockgen/package_mode.go +++ /dev/null @@ -1,468 +0,0 @@ -package main - -import ( - "errors" - "flag" - "fmt" - "go/ast" - "go/types" - "strings" - - "go.uber.org/mock/mockgen/model" - "golang.org/x/tools/go/packages" -) - -var ( - buildFlags = flag.String("build_flags", "", "(package mode) Additional flags for go build.") -) - -type packageModeParser struct { - pkgName string - - // Mapping from underlying types to aliases used within the package source. - // - // We prefer to use aliases used in the source rather than underlying type names - // as those may be unexported or internal. - // TODO(joaks): Once mock is Go1.23+ only, we can remove this - // as the casing for types.Alias will automatically handle this - // in all cases. - aliasReplacements map[types.Type]aliasReplacement -} - -type aliasReplacement struct { - name string - pkg string -} - -func (p *packageModeParser) parsePackage(packageName string, ifaces []string) (*model.Package, error) { - p.pkgName = packageName - - pkg, err := p.loadPackage(packageName) - if err != nil { - return nil, fmt.Errorf("load package: %w", err) - } - - p.buildAliasReplacements(pkg) - - interfaces, err := p.extractInterfacesFromPackage(pkg, ifaces) - if err != nil { - return nil, fmt.Errorf("extract interfaces from package: %w", err) - } - - return &model.Package{ - Name: pkg.Types.Name(), - PkgPath: packageName, - Interfaces: interfaces, - }, nil -} - -// buildAliasReplacements finds and records any references to aliases -// within the given package's source. -// These aliases will be preferred when parsing types -// over the underlying name counterparts, as those may be unexported / internal. -// -// If a type has more than one alias within the source package, -// the latest one to be inspected will be the one used for mapping. -// This is fine, since all aliases and their underlying types are interchangeable -// from a type-checking standpoint. -func (p *packageModeParser) buildAliasReplacements(pkg *packages.Package) { - p.aliasReplacements = make(map[types.Type]aliasReplacement) - - // checkIdent checks if the given identifier exists - // in the given package as an alias, and adds it to - // the alias replacements map if so. - checkIdent := func(pkg *types.Package, ident string) bool { - scope := pkg.Scope() - if scope == nil { - return true - } - obj := scope.Lookup(ident) - if obj == nil { - return true - } - objTypeName, ok := obj.(*types.TypeName) - if !ok { - return true - } - if !objTypeName.IsAlias() { - return true - } - typ := objTypeName.Type() - if typ == nil { - return true - } - p.aliasReplacements[typ] = aliasReplacement{ - name: objTypeName.Name(), - pkg: pkg.Path(), - } - return false - - } - - for _, f := range pkg.Syntax { - fileScope, ok := pkg.TypesInfo.Scopes[f] - if !ok { - continue - } - ast.Inspect(f, func(node ast.Node) bool { - - // Simple identifiers: check if it is an alias - // from the source package. - if ident, ok := node.(*ast.Ident); ok { - return checkIdent(pkg.Types, ident.String()) - } - - // Selector expressions: check if it is an alias - // from the package represented by the qualifier. - selExpr, ok := node.(*ast.SelectorExpr) - if !ok { - return true - } - - x, sel := selExpr.X, selExpr.Sel - xident, ok := x.(*ast.Ident) - if !ok { - return true - } - - xObj := fileScope.Lookup(xident.String()) - pkgName, ok := xObj.(*types.PkgName) - if !ok { - return true - } - - xPkg := pkgName.Imported() - if xPkg == nil { - return true - } - return checkIdent(xPkg, sel.String()) - }) - } -} - -func (p *packageModeParser) loadPackage(packageName string) (*packages.Package, error) { - var buildFlagsSet []string - if *buildFlags != "" { - buildFlagsSet = strings.Split(*buildFlags, " ") - } - - cfg := &packages.Config{ - Mode: packages.NeedDeps | packages.NeedImports | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedEmbedFiles | packages.LoadSyntax, - BuildFlags: buildFlagsSet, - } - pkgs, err := packages.Load(cfg, packageName) - if err != nil { - return nil, fmt.Errorf("load packages: %w", err) - } - - if len(pkgs) != 1 { - return nil, fmt.Errorf("packages length must be 1: %d", len(pkgs)) - } - - if len(pkgs[0].Errors) > 0 { - errs := make([]error, len(pkgs[0].Errors)) - for i, err := range pkgs[0].Errors { - errs[i] = err - } - - return nil, errors.Join(errs...) - } - - return pkgs[0], nil -} - -func (p *packageModeParser) extractInterfacesFromPackage(pkg *packages.Package, ifaces []string) ([]*model.Interface, error) { - interfaces := make([]*model.Interface, len(ifaces)) - for i, iface := range ifaces { - obj := pkg.Types.Scope().Lookup(iface) - if obj == nil { - return nil, fmt.Errorf("interface %s does not exist", iface) - } - - modelIface, err := p.parseInterface(obj) - if err != nil { - return nil, newParseTypeError("parse interface", obj.Name(), err) - } - - interfaces[i] = modelIface - } - - return interfaces, nil -} - -func (p *packageModeParser) parseInterface(obj types.Object) (*model.Interface, error) { - named, ok := types.Unalias(obj.Type()).(*types.Named) - if !ok { - return nil, fmt.Errorf("%s is not an interface. it is a %T", obj.Name(), obj.Type().Underlying()) - } - - iface, ok := named.Underlying().(*types.Interface) - if !ok { - return nil, fmt.Errorf("%s is not an interface. it is a %T", obj.Name(), obj.Type().Underlying()) - } - - if p.isConstraint(iface) { - return nil, fmt.Errorf("interface %s is a constraint", obj.Name()) - } - - methods := make([]*model.Method, iface.NumMethods()) - for i := range iface.NumMethods() { - method := iface.Method(i) - typedMethod, ok := method.Type().(*types.Signature) - if !ok { - return nil, fmt.Errorf("method %s is not a signature", method.Name()) - } - - modelFunc, err := p.parseFunc(typedMethod) - if err != nil { - return nil, newParseTypeError("parse method", typedMethod.String(), err) - } - - methods[i] = &model.Method{ - Name: method.Name(), - In: modelFunc.In, - Out: modelFunc.Out, - Variadic: modelFunc.Variadic, - } - } - - if named.TypeParams() == nil { - return &model.Interface{Name: obj.Name(), Methods: methods}, nil - } - - typeParams := make([]*model.Parameter, named.TypeParams().Len()) - for i := range named.TypeParams().Len() { - param := named.TypeParams().At(i) - typeParam, err := p.parseConstraint(param) - if err != nil { - return nil, newParseTypeError("parse type parameter", param.String(), err) - } - - typeParams[i] = &model.Parameter{Name: param.Obj().Name(), Type: typeParam} - } - - return &model.Interface{Name: obj.Name(), Methods: methods, TypeParams: typeParams}, nil -} - -func (o *packageModeParser) isConstraint(t *types.Interface) bool { - for i := range t.NumEmbeddeds() { - embed := t.EmbeddedType(i) - if _, ok := embed.Underlying().(*types.Interface); !ok { - return true - } - } - - return false -} - -func (p *packageModeParser) parseType(t types.Type) (model.Type, error) { - switch t := t.(type) { - case *types.Array: - elementType, err := p.parseType(t.Elem()) - if err != nil { - return nil, newParseTypeError("parse array type", t.Elem().String(), err) - } - return &model.ArrayType{Len: int(t.Len()), Type: elementType}, nil - case *types.Slice: - elementType, err := p.parseType(t.Elem()) - if err != nil { - return nil, newParseTypeError("parse slice type", t.Elem().String(), err) - } - - return &model.ArrayType{Len: -1, Type: elementType}, nil - case *types.Chan: - var dir model.ChanDir - switch t.Dir() { - case types.RecvOnly: - dir = model.RecvDir - case types.SendOnly: - dir = model.SendDir - } - - chanType, err := p.parseType(t.Elem()) - if err != nil { - return nil, newParseTypeError("parse chan type", t.Elem().String(), err) - } - - return &model.ChanType{Dir: dir, Type: chanType}, nil - case *types.Signature: - sig, err := p.parseFunc(t) - if err != nil { - return nil, newParseTypeError("parse signature", t.String(), err) - } - - return sig, nil - case *types.Named, *types.Alias: - object := t.(interface{ Obj() *types.TypeName }) - name := object.Obj().Name() - var pkg string - if object.Obj().Pkg() != nil { - pkg = object.Obj().Pkg().Path() - } - - // If there was an alias to this type used somewhere in the source, - // use that alias instead of the underlying type, - // since the underlying type might be unexported. - if alias, ok := p.aliasReplacements[t]; ok { - name = alias.name - pkg = alias.pkg - } - - // TypeArgs method not available for aliases in go1.22 - genericType, ok := t.(interface{ TypeArgs() *types.TypeList }) - if !ok || genericType.TypeArgs() == nil { - return &model.NamedType{ - Package: pkg, - Type: name, - }, nil - } - - typeParams := &model.TypeParametersType{TypeParameters: make([]model.Type, genericType.TypeArgs().Len())} - for i := range genericType.TypeArgs().Len() { - typeParam := genericType.TypeArgs().At(i) - typedParam, err := p.parseType(typeParam) - if err != nil { - return nil, newParseTypeError("parse type parameter", typeParam.String(), err) - } - - typeParams.TypeParameters[i] = typedParam - } - - return &model.NamedType{ - Package: pkg, - Type: name, - TypeParams: typeParams, - }, nil - case *types.Interface: - if t.Empty() { - return model.PredeclaredType("any"), nil - } - - return nil, fmt.Errorf("cannot handle non-empty unnamed interfaces") - case *types.Map: - key, err := p.parseType(t.Key()) - if err != nil { - return nil, newParseTypeError("parse map key", t.Key().String(), err) - } - value, err := p.parseType(t.Elem()) - if err != nil { - return nil, newParseTypeError("parse map value", t.Elem().String(), err) - } - - return &model.MapType{Key: key, Value: value}, nil - case *types.Pointer: - valueType, err := p.parseType(t.Elem()) - if err != nil { - return nil, newParseTypeError("parse pointer type", t.Elem().String(), err) - } - - return &model.PointerType{Type: valueType}, nil - case *types.Struct: - if t.NumFields() > 0 { - return nil, fmt.Errorf("cannot handle non-empty unnamed structs") - } - - return model.PredeclaredType("struct{}"), nil - case *types.Basic: - return model.PredeclaredType(t.Name()), nil - case *types.Tuple: - panic("tuple field") // TODO - case *types.TypeParam: - return &model.NamedType{Type: t.Obj().Name()}, nil - default: - panic("unknown type") // TODO - } -} - -func (p *packageModeParser) parseFunc(sig *types.Signature) (*model.FuncType, error) { - var variadic *model.Parameter - params := make([]*model.Parameter, 0, sig.Params().Len()) - for i := range sig.Params().Len() { - param := sig.Params().At(i) - - isVariadicParam := i == sig.Params().Len()-1 && sig.Variadic() - parseType := param.Type() - if isVariadicParam { - sliceType, ok := param.Type().(*types.Slice) - if !ok { - return nil, newParseTypeError("variadic parameter is not a slice", param.String(), nil) - } - - parseType = sliceType.Elem() - } - - paramType, err := p.parseType(parseType) - if err != nil { - return nil, newParseTypeError("parse parameter type", parseType.String(), err) - } - - modelParameter := &model.Parameter{Type: paramType, Name: param.Name()} - - if isVariadicParam { - variadic = modelParameter - } else { - params = append(params, modelParameter) - } - } - - if len(params) == 0 { - params = nil - } - - results := make([]*model.Parameter, sig.Results().Len()) - for i := range sig.Results().Len() { - result := sig.Results().At(i) - - resultType, err := p.parseType(result.Type()) - if err != nil { - return nil, newParseTypeError("parse result type", result.Type().String(), err) - } - - results[i] = &model.Parameter{Type: resultType, Name: result.Name()} - } - - if len(results) == 0 { - results = nil - } - - return &model.FuncType{ - In: params, - Out: results, - Variadic: variadic, - }, nil -} - -func (p *packageModeParser) parseConstraint(t *types.TypeParam) (model.Type, error) { - if t == nil { - return nil, fmt.Errorf("nil type param") - } - - typeParam, err := p.parseType(t.Constraint()) - if err != nil { - return nil, newParseTypeError("parse constraint type", t.Constraint().String(), err) - } - - return typeParam, nil -} - -type parseTypeError struct { - message string - typeString string - error error -} - -func newParseTypeError(message string, typeString string, error error) *parseTypeError { - return &parseTypeError{typeString: typeString, error: error, message: message} -} - -func (p parseTypeError) Error() string { - if p.error != nil { - return fmt.Sprintf("%s: error parsing %s: %s", p.message, p.typeString, p.error) - } - - return fmt.Sprintf("%s: error parsing type %s", p.message, p.typeString) -} - -func (p parseTypeError) Unwrap() error { - return p.error -} diff --git a/vendor/go.uber.org/mock/mockgen/parse.go b/vendor/go.uber.org/mock/mockgen/parse.go deleted file mode 100644 index f43321c3..00000000 --- a/vendor/go.uber.org/mock/mockgen/parse.go +++ /dev/null @@ -1,805 +0,0 @@ -// Copyright 2012 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -// This file contains the model construction by parsing source files. - -import ( - "errors" - "fmt" - "go/ast" - "go/build" - "go/importer" - "go/parser" - "go/token" - "go/types" - "log" - "os" - "path" - "path/filepath" - "strconv" - "strings" - - "go.uber.org/mock/mockgen/model" -) - -// sourceMode generates mocks via source file. -func sourceMode(source string) (*model.Package, error) { - srcDir, err := filepath.Abs(filepath.Dir(source)) - if err != nil { - return nil, fmt.Errorf("failed getting source directory: %v", err) - } - - packageImport, err := parsePackageImport(srcDir) - if err != nil { - return nil, err - } - - fs := token.NewFileSet() - file, err := parser.ParseFile(fs, source, nil, 0) - if err != nil { - return nil, fmt.Errorf("failed parsing source file %v: %v", source, err) - } - - p := &fileParser{ - fileSet: fs, - imports: make(map[string]importedPackage), - importedInterfaces: newInterfaceCache(), - auxInterfaces: newInterfaceCache(), - srcDir: srcDir, - } - - // Handle -imports. - dotImports := make(map[string]bool) - if *imports != "" { - for _, kv := range strings.Split(*imports, ",") { - eq := strings.Index(kv, "=") - k, v := kv[:eq], kv[eq+1:] - if k == "." { - dotImports[v] = true - } else { - p.imports[k] = importedPkg{path: v} - } - } - } - - if *excludeInterfaces != "" { - p.excludeNamesSet = parseExcludeInterfaces(*excludeInterfaces) - } - - // Handle -aux_files. - if err := p.parseAuxFiles(*auxFiles); err != nil { - return nil, err - } - p.addAuxInterfacesFromFile(packageImport, file) // this file - - pkg, err := p.parseFile(packageImport, file) - if err != nil { - return nil, err - } - for pkgPath := range dotImports { - pkg.DotImports = append(pkg.DotImports, pkgPath) - } - return pkg, nil -} - -type importedPackage interface { - Path() string - Parser() *fileParser -} - -type importedPkg struct { - path string - parser *fileParser -} - -func (i importedPkg) Path() string { return i.path } -func (i importedPkg) Parser() *fileParser { return i.parser } - -// duplicateImport is a bit of a misnomer. Currently the parser can't -// handle cases of multi-file packages importing different packages -// under the same name. Often these imports would not be problematic, -// so this type lets us defer raising an error unless the package name -// is actually used. -type duplicateImport struct { - name string - duplicates []string -} - -func (d duplicateImport) Error() string { - return fmt.Sprintf("%q is ambiguous because of duplicate imports: %v", d.name, d.duplicates) -} - -func (d duplicateImport) Path() string { log.Fatal(d.Error()); return "" } -func (d duplicateImport) Parser() *fileParser { log.Fatal(d.Error()); return nil } - -type interfaceCache struct { - m map[string]map[string]*namedInterface -} - -func newInterfaceCache() *interfaceCache { - return &interfaceCache{ - m: make(map[string]map[string]*namedInterface), - } -} - -func (i *interfaceCache) Set(pkg, name string, it *namedInterface) { - if _, ok := i.m[pkg]; !ok { - i.m[pkg] = make(map[string]*namedInterface) - } - i.m[pkg][name] = it -} - -func (i *interfaceCache) Get(pkg, name string) *namedInterface { - if _, ok := i.m[pkg]; !ok { - return nil - } - return i.m[pkg][name] -} - -func (i *interfaceCache) GetASTIface(pkg, name string) *ast.InterfaceType { - if _, ok := i.m[pkg]; !ok { - return nil - } - it, ok := i.m[pkg][name] - if !ok { - return nil - } - return it.it -} - -type fileParser struct { - fileSet *token.FileSet - imports map[string]importedPackage // package name => imported package - importedInterfaces *interfaceCache - auxFiles []*ast.File - auxInterfaces *interfaceCache - srcDir string - excludeNamesSet map[string]struct{} -} - -func (p *fileParser) errorf(pos token.Pos, format string, args ...any) error { - ps := p.fileSet.Position(pos) - format = "%s:%d:%d: " + format - args = append([]any{ps.Filename, ps.Line, ps.Column}, args...) - return fmt.Errorf(format, args...) -} - -func (p *fileParser) parseAuxFiles(auxFiles string) error { - auxFiles = strings.TrimSpace(auxFiles) - if auxFiles == "" { - return nil - } - for _, kv := range strings.Split(auxFiles, ",") { - parts := strings.SplitN(kv, "=", 2) - if len(parts) != 2 { - return fmt.Errorf("bad aux file spec: %v", kv) - } - pkg, fpath := parts[0], parts[1] - - file, err := parser.ParseFile(p.fileSet, fpath, nil, 0) - if err != nil { - return err - } - p.auxFiles = append(p.auxFiles, file) - p.addAuxInterfacesFromFile(pkg, file) - } - return nil -} - -func (p *fileParser) addAuxInterfacesFromFile(pkg string, file *ast.File) { - for ni := range iterInterfaces(file) { - p.auxInterfaces.Set(pkg, ni.name.Name, ni) - } -} - -// parseFile loads all file imports and auxiliary files import into the -// fileParser, parses all file interfaces and returns package model. -func (p *fileParser) parseFile(importPath string, file *ast.File) (*model.Package, error) { - allImports, dotImports := importsOfFile(file) - // Don't stomp imports provided by -imports. Those should take precedence. - for pkg, pkgI := range allImports { - if _, ok := p.imports[pkg]; !ok { - p.imports[pkg] = pkgI - } - } - // Add imports from auxiliary files, which might be needed for embedded interfaces. - // Don't stomp any other imports. - for _, f := range p.auxFiles { - auxImports, _ := importsOfFile(f) - for pkg, pkgI := range auxImports { - if _, ok := p.imports[pkg]; !ok { - p.imports[pkg] = pkgI - } - } - } - - var is []*model.Interface - for ni := range iterInterfaces(file) { - if _, ok := p.excludeNamesSet[ni.name.String()]; ok { - continue - } - i, err := p.parseInterface(ni.name.String(), importPath, ni) - if errors.Is(err, errConstraintInterface) { - continue - } - if err != nil { - return nil, err - } - is = append(is, i) - } - return &model.Package{ - Name: file.Name.String(), - PkgPath: importPath, - Interfaces: is, - DotImports: dotImports, - }, nil -} - -// parsePackage loads package specified by path, parses it and returns -// a new fileParser with the parsed imports and interfaces. -func (p *fileParser) parsePackage(path string) (*fileParser, error) { - newP := &fileParser{ - fileSet: token.NewFileSet(), - imports: make(map[string]importedPackage), - importedInterfaces: newInterfaceCache(), - auxInterfaces: newInterfaceCache(), - srcDir: p.srcDir, - } - - var pkgs map[string]*ast.Package - if imp, err := build.Import(path, newP.srcDir, build.FindOnly); err != nil { - return nil, err - } else if pkgs, err = parser.ParseDir(newP.fileSet, imp.Dir, nil, 0); err != nil { - return nil, err - } - - for _, pkg := range pkgs { - file := ast.MergePackageFiles(pkg, ast.FilterFuncDuplicates|ast.FilterUnassociatedComments|ast.FilterImportDuplicates) - for ni := range iterInterfaces(file) { - newP.importedInterfaces.Set(path, ni.name.Name, ni) - } - imports, _ := importsOfFile(file) - for pkgName, pkgI := range imports { - newP.imports[pkgName] = pkgI - } - } - return newP, nil -} - -func (p *fileParser) constructInstParams(pkg string, params []*ast.Field, instParams []model.Type, embeddedInstParams []ast.Expr, tps map[string]model.Type) ([]model.Type, error) { - pm := make(map[string]int) - var i int - for _, v := range params { - for _, n := range v.Names { - pm[n.Name] = i - instParams = append(instParams, model.PredeclaredType(n.Name)) - i++ - } - } - - var runtimeInstParams []model.Type - for _, instParam := range embeddedInstParams { - switch t := instParam.(type) { - case *ast.Ident: - if idx, ok := pm[t.Name]; ok { - runtimeInstParams = append(runtimeInstParams, instParams[idx]) - continue - } - } - modelType, err := p.parseType(pkg, instParam, tps) - if err != nil { - return nil, err - } - runtimeInstParams = append(runtimeInstParams, modelType) - } - - return runtimeInstParams, nil -} - -func (p *fileParser) constructTps(it *namedInterface) (tps map[string]model.Type) { - tps = make(map[string]model.Type) - n := 0 - for _, tp := range it.typeParams { - for _, tm := range tp.Names { - tps[tm.Name] = nil - if len(it.instTypes) != 0 { - tps[tm.Name] = it.instTypes[n] - n++ - } - } - } - return tps -} - -// parseInterface loads interface specified by pkg and name, parses it and returns -// a new model with the parsed. -func (p *fileParser) parseInterface(name, pkg string, it *namedInterface) (*model.Interface, error) { - iface := &model.Interface{Name: name} - tps := p.constructTps(it) - tp, err := p.parseFieldList(pkg, it.typeParams, tps) - if err != nil { - return nil, fmt.Errorf("unable to parse interface type parameters: %v", name) - } - - iface.TypeParams = tp - for _, field := range it.it.Methods.List { - var methods []*model.Method - if methods, err = p.parseMethod(field, it, iface, pkg, tps); err != nil { - return nil, err - } - for _, m := range methods { - iface.AddMethod(m) - } - } - return iface, nil -} - -func (p *fileParser) parseMethod(field *ast.Field, it *namedInterface, iface *model.Interface, pkg string, tps map[string]model.Type) ([]*model.Method, error) { - // {} for git diff - { - switch v := field.Type.(type) { - case *ast.FuncType: - if nn := len(field.Names); nn != 1 { - return nil, fmt.Errorf("expected one name for interface %v, got %d", iface.Name, nn) - } - m := &model.Method{ - Name: field.Names[0].String(), - } - var err error - m.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v, tps) - if err != nil { - return nil, err - } - return []*model.Method{m}, nil - case *ast.Ident: - // Embedded interface in this package. - embeddedIfaceType := p.auxInterfaces.Get(pkg, v.String()) - if embeddedIfaceType == nil { - embeddedIfaceType = p.importedInterfaces.Get(pkg, v.String()) - } - - var embeddedIface *model.Interface - if embeddedIfaceType != nil { - var err error - embeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps) - if err != nil { - return nil, err - } - embeddedIface, err = p.parseInterface(v.String(), pkg, embeddedIfaceType) - if err != nil { - return nil, err - } - - } else { - // This is built-in error interface. - if v.String() == model.ErrorInterface.Name { - embeddedIface = &model.ErrorInterface - } else { - ip, err := p.parsePackage(pkg) - if err != nil { - return nil, p.errorf(v.Pos(), "could not parse package %s: %v", pkg, err) - } - - if embeddedIfaceType = ip.importedInterfaces.Get(pkg, v.String()); embeddedIfaceType == nil { - return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", pkg, v.String()) - } - - embeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps) - if err != nil { - return nil, err - } - embeddedIface, err = ip.parseInterface(v.String(), pkg, embeddedIfaceType) - if err != nil { - return nil, err - } - } - } - return embeddedIface.Methods, nil - case *ast.SelectorExpr: - // Embedded interface in another package. - filePkg, sel := v.X.(*ast.Ident).String(), v.Sel.String() - embeddedPkg, ok := p.imports[filePkg] - if !ok { - return nil, p.errorf(v.X.Pos(), "unknown package %s", filePkg) - } - - var embeddedIface *model.Interface - var err error - embeddedIfaceType := p.auxInterfaces.Get(filePkg, sel) - if embeddedIfaceType != nil { - embeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps) - if err != nil { - return nil, err - } - embeddedIface, err = p.parseInterface(sel, filePkg, embeddedIfaceType) - if err != nil { - return nil, err - } - } else { - path := embeddedPkg.Path() - parser := embeddedPkg.Parser() - if parser == nil { - ip, err := p.parsePackage(path) - if err != nil { - return nil, p.errorf(v.Pos(), "could not parse package %s: %v", path, err) - } - parser = ip - p.imports[filePkg] = importedPkg{ - path: embeddedPkg.Path(), - parser: parser, - } - } - if embeddedIfaceType = parser.importedInterfaces.Get(path, sel); embeddedIfaceType == nil { - return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", path, sel) - } - - embeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps) - if err != nil { - return nil, err - } - embeddedIface, err = parser.parseInterface(sel, path, embeddedIfaceType) - if err != nil { - return nil, err - } - } - // TODO: apply shadowing rules. - return embeddedIface.Methods, nil - default: - return p.parseGenericMethod(field, it, iface, pkg, tps) - } - } -} - -func (p *fileParser) parseFunc(pkg string, f *ast.FuncType, tps map[string]model.Type) (inParam []*model.Parameter, variadic *model.Parameter, outParam []*model.Parameter, err error) { - if f.Params != nil { - regParams := f.Params.List - if isVariadic(f) { - n := len(regParams) - varParams := regParams[n-1:] - regParams = regParams[:n-1] - vp, err := p.parseFieldList(pkg, varParams, tps) - if err != nil { - return nil, nil, nil, p.errorf(varParams[0].Pos(), "failed parsing variadic argument: %v", err) - } - variadic = vp[0] - } - inParam, err = p.parseFieldList(pkg, regParams, tps) - if err != nil { - return nil, nil, nil, p.errorf(f.Pos(), "failed parsing arguments: %v", err) - } - } - if f.Results != nil { - outParam, err = p.parseFieldList(pkg, f.Results.List, tps) - if err != nil { - return nil, nil, nil, p.errorf(f.Pos(), "failed parsing returns: %v", err) - } - } - return -} - -func (p *fileParser) parseFieldList(pkg string, fields []*ast.Field, tps map[string]model.Type) ([]*model.Parameter, error) { - nf := 0 - for _, f := range fields { - nn := len(f.Names) - if nn == 0 { - nn = 1 // anonymous parameter - } - nf += nn - } - if nf == 0 { - return nil, nil - } - ps := make([]*model.Parameter, nf) - i := 0 // destination index - for _, f := range fields { - t, err := p.parseType(pkg, f.Type, tps) - if err != nil { - return nil, err - } - - if len(f.Names) == 0 { - // anonymous arg - ps[i] = &model.Parameter{Type: t} - i++ - continue - } - for _, name := range f.Names { - ps[i] = &model.Parameter{Name: name.Name, Type: t} - i++ - } - } - return ps, nil -} - -func (p *fileParser) parseType(pkg string, typ ast.Expr, tps map[string]model.Type) (model.Type, error) { - switch v := typ.(type) { - case *ast.ArrayType: - ln := -1 - if v.Len != nil { - value, err := p.parseArrayLength(v.Len) - if err != nil { - return nil, err - } - ln, err = strconv.Atoi(value) - if err != nil { - return nil, p.errorf(v.Len.Pos(), "bad array size: %v", err) - } - } - t, err := p.parseType(pkg, v.Elt, tps) - if err != nil { - return nil, err - } - return &model.ArrayType{Len: ln, Type: t}, nil - case *ast.ChanType: - t, err := p.parseType(pkg, v.Value, tps) - if err != nil { - return nil, err - } - var dir model.ChanDir - if v.Dir == ast.SEND { - dir = model.SendDir - } - if v.Dir == ast.RECV { - dir = model.RecvDir - } - return &model.ChanType{Dir: dir, Type: t}, nil - case *ast.Ellipsis: - // assume we're parsing a variadic argument - return p.parseType(pkg, v.Elt, tps) - case *ast.FuncType: - in, variadic, out, err := p.parseFunc(pkg, v, tps) - if err != nil { - return nil, err - } - return &model.FuncType{In: in, Out: out, Variadic: variadic}, nil - case *ast.Ident: - it, ok := tps[v.Name] - if v.IsExported() && !ok { - // `pkg` may be an aliased imported pkg - // if so, patch the import w/ the fully qualified import - maybeImportedPkg, ok := p.imports[pkg] - if ok { - pkg = maybeImportedPkg.Path() - } - // assume type in this package - return &model.NamedType{Package: pkg, Type: v.Name}, nil - } - if ok && it != nil { - return it, nil - } - // assume predeclared type - return model.PredeclaredType(v.Name), nil - case *ast.InterfaceType: - if v.Methods != nil && len(v.Methods.List) > 0 { - return nil, p.errorf(v.Pos(), "can't handle non-empty unnamed interface types") - } - return model.PredeclaredType("any"), nil - case *ast.MapType: - key, err := p.parseType(pkg, v.Key, tps) - if err != nil { - return nil, err - } - value, err := p.parseType(pkg, v.Value, tps) - if err != nil { - return nil, err - } - return &model.MapType{Key: key, Value: value}, nil - case *ast.SelectorExpr: - pkgName := v.X.(*ast.Ident).String() - pkg, ok := p.imports[pkgName] - if !ok { - return nil, p.errorf(v.Pos(), "unknown package %q", pkgName) - } - return &model.NamedType{Package: pkg.Path(), Type: v.Sel.String()}, nil - case *ast.StarExpr: - t, err := p.parseType(pkg, v.X, tps) - if err != nil { - return nil, err - } - return &model.PointerType{Type: t}, nil - case *ast.StructType: - if v.Fields != nil && len(v.Fields.List) > 0 { - return nil, p.errorf(v.Pos(), "can't handle non-empty unnamed struct types") - } - return model.PredeclaredType("struct{}"), nil - case *ast.ParenExpr: - return p.parseType(pkg, v.X, tps) - default: - mt, err := p.parseGenericType(pkg, typ, tps) - if err != nil { - return nil, err - } - if mt == nil { - break - } - return mt, nil - } - - return nil, fmt.Errorf("don't know how to parse type %T", typ) -} - -func (p *fileParser) parseArrayLength(expr ast.Expr) (string, error) { - switch val := expr.(type) { - case (*ast.BasicLit): - return val.Value, nil - case (*ast.Ident): - // when the length is a const defined locally - return val.Obj.Decl.(*ast.ValueSpec).Values[0].(*ast.BasicLit).Value, nil - case (*ast.SelectorExpr): - // when the length is a const defined in an external package - usedPkg, err := importer.Default().Import(fmt.Sprintf("%s", val.X)) - if err != nil { - return "", p.errorf(expr.Pos(), "unknown package in array length: %v", err) - } - ev, err := types.Eval(token.NewFileSet(), usedPkg, token.NoPos, val.Sel.Name) - if err != nil { - return "", p.errorf(expr.Pos(), "unknown constant in array length: %v", err) - } - return ev.Value.String(), nil - case (*ast.ParenExpr): - return p.parseArrayLength(val.X) - case (*ast.BinaryExpr): - x, err := p.parseArrayLength(val.X) - if err != nil { - return "", err - } - y, err := p.parseArrayLength(val.Y) - if err != nil { - return "", err - } - biExpr := fmt.Sprintf("%s%v%s", x, val.Op, y) - tv, err := types.Eval(token.NewFileSet(), nil, token.NoPos, biExpr) - if err != nil { - return "", p.errorf(expr.Pos(), "invalid expression in array length: %v", err) - } - return tv.Value.String(), nil - default: - return "", p.errorf(expr.Pos(), "invalid expression in array length: %v", val) - } -} - -// importsOfFile returns a map of package name to import path -// of the imports in file. -func importsOfFile(file *ast.File) (normalImports map[string]importedPackage, dotImports []string) { - var importPaths []string - for _, is := range file.Imports { - if is.Name != nil { - continue - } - importPath := is.Path.Value[1 : len(is.Path.Value)-1] // remove quotes - importPaths = append(importPaths, importPath) - } - packagesName := createPackageMap(importPaths) - normalImports = make(map[string]importedPackage) - dotImports = make([]string, 0) - for _, is := range file.Imports { - var pkgName string - importPath := is.Path.Value[1 : len(is.Path.Value)-1] // remove quotes - - if is.Name != nil { - // Named imports are always certain. - if is.Name.Name == "_" { - continue - } - pkgName = is.Name.Name - } else { - pkg, ok := packagesName[importPath] - if !ok { - // Fallback to import path suffix. Note that this is uncertain. - _, last := path.Split(importPath) - // If the last path component has dots, the first dot-delimited - // field is used as the name. - pkgName = strings.SplitN(last, ".", 2)[0] - } else { - pkgName = pkg - } - } - - if pkgName == "." { - dotImports = append(dotImports, importPath) - } else { - if pkg, ok := normalImports[pkgName]; ok { - switch p := pkg.(type) { - case duplicateImport: - normalImports[pkgName] = duplicateImport{ - name: p.name, - duplicates: append([]string{importPath}, p.duplicates...), - } - case importedPkg: - normalImports[pkgName] = duplicateImport{ - name: pkgName, - duplicates: []string{p.path, importPath}, - } - } - } else { - normalImports[pkgName] = importedPkg{path: importPath} - } - } - } - return -} - -type namedInterface struct { - name *ast.Ident - it *ast.InterfaceType - typeParams []*ast.Field - embeddedInstTypeParams []ast.Expr - instTypes []model.Type -} - -// Create an iterator over all interfaces in file. -func iterInterfaces(file *ast.File) <-chan *namedInterface { - ch := make(chan *namedInterface) - go func() { - for _, decl := range file.Decls { - gd, ok := decl.(*ast.GenDecl) - if !ok || gd.Tok != token.TYPE { - continue - } - for _, spec := range gd.Specs { - ts, ok := spec.(*ast.TypeSpec) - if !ok { - continue - } - it, ok := ts.Type.(*ast.InterfaceType) - if !ok { - continue - } - - ch <- &namedInterface{name: ts.Name, it: it, typeParams: getTypeSpecTypeParams(ts)} - } - } - close(ch) - }() - return ch -} - -// isVariadic returns whether the function is variadic. -func isVariadic(f *ast.FuncType) bool { - nargs := len(f.Params.List) - if nargs == 0 { - return false - } - _, ok := f.Params.List[nargs-1].Type.(*ast.Ellipsis) - return ok -} - -// packageNameOfDir get package import path via dir -func packageNameOfDir(srcDir string) (string, error) { - files, err := os.ReadDir(srcDir) - if err != nil { - log.Fatal(err) - } - - var goFilePath string - for _, file := range files { - if !file.IsDir() && strings.HasSuffix(file.Name(), ".go") { - goFilePath = file.Name() - break - } - } - if goFilePath == "" { - return "", fmt.Errorf("go source file not found %s", srcDir) - } - - packageImport, err := parsePackageImport(srcDir) - if err != nil { - return "", err - } - return packageImport, nil -} - -var errOutsideGoPath = errors.New("source directory is outside GOPATH") diff --git a/vendor/go.uber.org/mock/mockgen/version.go b/vendor/go.uber.org/mock/mockgen/version.go deleted file mode 100644 index 6db160ac..00000000 --- a/vendor/go.uber.org/mock/mockgen/version.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2022 Google LLC -// -// 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 main - -import ( - "fmt" - "log" - "runtime/debug" -) - -func printModuleVersion() { - if bi, exists := debug.ReadBuildInfo(); exists { - fmt.Println(bi.Main.Version) - } else { - log.Printf("No version information found. Make sure to use " + - "GO111MODULE=on when running 'go get' in order to use specific " + - "version of the binary.") - } -} diff --git a/vendor/golang.org/x/mod/LICENSE b/vendor/golang.org/x/mod/LICENSE deleted file mode 100644 index 2a7cf70d..00000000 --- a/vendor/golang.org/x/mod/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright 2009 The Go Authors. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/mod/PATENTS b/vendor/golang.org/x/mod/PATENTS deleted file mode 100644 index 73309904..00000000 --- a/vendor/golang.org/x/mod/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google 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, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go b/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go deleted file mode 100644 index 150f887e..00000000 --- a/vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2018 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 lazyregexp is a thin wrapper over regexp, allowing the use of global -// regexp variables without forcing them to be compiled at init. -package lazyregexp - -import ( - "os" - "regexp" - "strings" - "sync" -) - -// Regexp is a wrapper around [regexp.Regexp], where the underlying regexp will be -// compiled the first time it is needed. -type Regexp struct { - str string - once sync.Once - rx *regexp.Regexp -} - -func (r *Regexp) re() *regexp.Regexp { - r.once.Do(r.build) - return r.rx -} - -func (r *Regexp) build() { - r.rx = regexp.MustCompile(r.str) - r.str = "" -} - -func (r *Regexp) FindSubmatch(s []byte) [][]byte { - return r.re().FindSubmatch(s) -} - -func (r *Regexp) FindStringSubmatch(s string) []string { - return r.re().FindStringSubmatch(s) -} - -func (r *Regexp) FindStringSubmatchIndex(s string) []int { - return r.re().FindStringSubmatchIndex(s) -} - -func (r *Regexp) ReplaceAllString(src, repl string) string { - return r.re().ReplaceAllString(src, repl) -} - -func (r *Regexp) FindString(s string) string { - return r.re().FindString(s) -} - -func (r *Regexp) FindAllString(s string, n int) []string { - return r.re().FindAllString(s, n) -} - -func (r *Regexp) MatchString(s string) bool { - return r.re().MatchString(s) -} - -func (r *Regexp) SubexpNames() []string { - return r.re().SubexpNames() -} - -var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test") - -// New creates a new lazy regexp, delaying the compiling work until it is first -// needed. If the code is being run as part of tests, the regexp compiling will -// happen immediately. -func New(str string) *Regexp { - lr := &Regexp{str: str} - if inTest { - // In tests, always compile the regexps early. - lr.re() - } - return lr -} diff --git a/vendor/golang.org/x/mod/modfile/print.go b/vendor/golang.org/x/mod/modfile/print.go deleted file mode 100644 index 48dbd82a..00000000 --- a/vendor/golang.org/x/mod/modfile/print.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2018 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. - -// Module file printer. - -package modfile - -import ( - "bytes" - "fmt" - "strings" -) - -// Format returns a go.mod file as a byte slice, formatted in standard style. -func Format(f *FileSyntax) []byte { - pr := &printer{} - pr.file(f) - - // remove trailing blank lines - b := pr.Bytes() - for len(b) > 0 && b[len(b)-1] == '\n' && (len(b) == 1 || b[len(b)-2] == '\n') { - b = b[:len(b)-1] - } - return b -} - -// A printer collects the state during printing of a file or expression. -type printer struct { - bytes.Buffer // output buffer - comment []Comment // pending end-of-line comments - margin int // left margin (indent), a number of tabs -} - -// printf prints to the buffer. -func (p *printer) printf(format string, args ...any) { - fmt.Fprintf(p, format, args...) -} - -// indent returns the position on the current line, in bytes, 0-indexed. -func (p *printer) indent() int { - b := p.Bytes() - n := 0 - for n < len(b) && b[len(b)-1-n] != '\n' { - n++ - } - return n -} - -// newline ends the current line, flushing end-of-line comments. -func (p *printer) newline() { - if len(p.comment) > 0 { - p.printf(" ") - for i, com := range p.comment { - if i > 0 { - p.trim() - p.printf("\n") - for i := 0; i < p.margin; i++ { - p.printf("\t") - } - } - p.printf("%s", strings.TrimSpace(com.Token)) - } - p.comment = p.comment[:0] - } - - p.trim() - if b := p.Bytes(); len(b) == 0 || (len(b) >= 2 && b[len(b)-1] == '\n' && b[len(b)-2] == '\n') { - // skip the blank line at top of file or after a blank line - } else { - p.printf("\n") - } - for i := 0; i < p.margin; i++ { - p.printf("\t") - } -} - -// trim removes trailing spaces and tabs from the current line. -func (p *printer) trim() { - // Remove trailing spaces and tabs from line we're about to end. - b := p.Bytes() - n := len(b) - for n > 0 && (b[n-1] == '\t' || b[n-1] == ' ') { - n-- - } - p.Truncate(n) -} - -// file formats the given file into the print buffer. -func (p *printer) file(f *FileSyntax) { - for _, com := range f.Before { - p.printf("%s", strings.TrimSpace(com.Token)) - p.newline() - } - - for i, stmt := range f.Stmt { - switch x := stmt.(type) { - case *CommentBlock: - // comments already handled - p.expr(x) - - default: - p.expr(x) - p.newline() - } - - for _, com := range stmt.Comment().After { - p.printf("%s", strings.TrimSpace(com.Token)) - p.newline() - } - - if i+1 < len(f.Stmt) { - p.newline() - } - } -} - -func (p *printer) expr(x Expr) { - // Emit line-comments preceding this expression. - if before := x.Comment().Before; len(before) > 0 { - // Want to print a line comment. - // Line comments must be at the current margin. - p.trim() - if p.indent() > 0 { - // There's other text on the line. Start a new line. - p.printf("\n") - } - // Re-indent to margin. - for i := 0; i < p.margin; i++ { - p.printf("\t") - } - for _, com := range before { - p.printf("%s", strings.TrimSpace(com.Token)) - p.newline() - } - } - - switch x := x.(type) { - default: - panic(fmt.Errorf("printer: unexpected type %T", x)) - - case *CommentBlock: - // done - - case *LParen: - p.printf("(") - case *RParen: - p.printf(")") - - case *Line: - p.tokens(x.Token) - - case *LineBlock: - p.tokens(x.Token) - p.printf(" ") - p.expr(&x.LParen) - p.margin++ - for _, l := range x.Line { - p.newline() - p.expr(l) - } - p.margin-- - p.newline() - p.expr(&x.RParen) - } - - // Queue end-of-line comments for printing when we - // reach the end of the line. - p.comment = append(p.comment, x.Comment().Suffix...) -} - -func (p *printer) tokens(tokens []string) { - sep := "" - for _, t := range tokens { - if t == "," || t == ")" || t == "]" || t == "}" { - sep = "" - } - p.printf("%s%s", sep, t) - sep = " " - if t == "(" || t == "[" || t == "{" { - sep = "" - } - } -} diff --git a/vendor/golang.org/x/mod/modfile/read.go b/vendor/golang.org/x/mod/modfile/read.go deleted file mode 100644 index 504a2f1d..00000000 --- a/vendor/golang.org/x/mod/modfile/read.go +++ /dev/null @@ -1,964 +0,0 @@ -// Copyright 2018 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 modfile - -import ( - "bytes" - "errors" - "fmt" - "os" - "strconv" - "strings" - "unicode" - "unicode/utf8" -) - -// A Position describes an arbitrary source position in a file, including the -// file, line, column, and byte offset. -type Position struct { - Line int // line in input (starting at 1) - LineRune int // rune in line (starting at 1) - Byte int // byte in input (starting at 0) -} - -// add returns the position at the end of s, assuming it starts at p. -func (p Position) add(s string) Position { - p.Byte += len(s) - if n := strings.Count(s, "\n"); n > 0 { - p.Line += n - s = s[strings.LastIndex(s, "\n")+1:] - p.LineRune = 1 - } - p.LineRune += utf8.RuneCountInString(s) - return p -} - -// An Expr represents an input element. -type Expr interface { - // Span returns the start and end position of the expression, - // excluding leading or trailing comments. - Span() (start, end Position) - - // Comment returns the comments attached to the expression. - // This method would normally be named 'Comments' but that - // would interfere with embedding a type of the same name. - Comment() *Comments -} - -// A Comment represents a single // comment. -type Comment struct { - Start Position - Token string // without trailing newline - Suffix bool // an end of line (not whole line) comment -} - -// Comments collects the comments associated with an expression. -type Comments struct { - Before []Comment // whole-line comments before this expression - Suffix []Comment // end-of-line comments after this expression - - // For top-level expressions only, After lists whole-line - // comments following the expression. - After []Comment -} - -// Comment returns the receiver. This isn't useful by itself, but -// a [Comments] struct is embedded into all the expression -// implementation types, and this gives each of those a Comment -// method to satisfy the Expr interface. -func (c *Comments) Comment() *Comments { - return c -} - -// A FileSyntax represents an entire go.mod file. -type FileSyntax struct { - Name string // file path - Comments - Stmt []Expr -} - -func (x *FileSyntax) Span() (start, end Position) { - if len(x.Stmt) == 0 { - return - } - start, _ = x.Stmt[0].Span() - _, end = x.Stmt[len(x.Stmt)-1].Span() - return start, end -} - -// addLine adds a line containing the given tokens to the file. -// -// If the first token of the hint matches the first token of the -// line, the new line is added at the end of the block containing hint, -// extracting hint into a new block if it is not yet in one. -// -// If the hint is non-nil but its first token does not match, -// the new line is added after the block containing hint -// (or hint itself, if not in a block). -// -// If no hint is provided, addLine appends the line to the end of -// the last block with a matching first token, -// or to the end of the file if no such block exists. -func (x *FileSyntax) addLine(hint Expr, tokens ...string) *Line { - if hint == nil { - // If no hint given, add to the last statement of the given type. - Loop: - for i := len(x.Stmt) - 1; i >= 0; i-- { - stmt := x.Stmt[i] - switch stmt := stmt.(type) { - case *Line: - if stmt.Token != nil && stmt.Token[0] == tokens[0] { - hint = stmt - break Loop - } - case *LineBlock: - if stmt.Token[0] == tokens[0] { - hint = stmt - break Loop - } - } - } - } - - newLineAfter := func(i int) *Line { - new := &Line{Token: tokens} - if i == len(x.Stmt) { - x.Stmt = append(x.Stmt, new) - } else { - x.Stmt = append(x.Stmt, nil) - copy(x.Stmt[i+2:], x.Stmt[i+1:]) - x.Stmt[i+1] = new - } - return new - } - - if hint != nil { - for i, stmt := range x.Stmt { - switch stmt := stmt.(type) { - case *Line: - if stmt == hint { - if stmt.Token == nil || stmt.Token[0] != tokens[0] { - return newLineAfter(i) - } - - // Convert line to line block. - stmt.InBlock = true - block := &LineBlock{Token: stmt.Token[:1], Line: []*Line{stmt}} - stmt.Token = stmt.Token[1:] - x.Stmt[i] = block - new := &Line{Token: tokens[1:], InBlock: true} - block.Line = append(block.Line, new) - return new - } - - case *LineBlock: - if stmt == hint { - if stmt.Token[0] != tokens[0] { - return newLineAfter(i) - } - - new := &Line{Token: tokens[1:], InBlock: true} - stmt.Line = append(stmt.Line, new) - return new - } - - for j, line := range stmt.Line { - if line == hint { - if stmt.Token[0] != tokens[0] { - return newLineAfter(i) - } - - // Add new line after hint within the block. - stmt.Line = append(stmt.Line, nil) - copy(stmt.Line[j+2:], stmt.Line[j+1:]) - new := &Line{Token: tokens[1:], InBlock: true} - stmt.Line[j+1] = new - return new - } - } - } - } - } - - new := &Line{Token: tokens} - x.Stmt = append(x.Stmt, new) - return new -} - -func (x *FileSyntax) updateLine(line *Line, tokens ...string) { - if line.InBlock { - tokens = tokens[1:] - } - line.Token = tokens -} - -// markRemoved modifies line so that it (and its end-of-line comment, if any) -// will be dropped by (*FileSyntax).Cleanup. -func (line *Line) markRemoved() { - line.Token = nil - line.Comments.Suffix = nil -} - -// Cleanup cleans up the file syntax x after any edit operations. -// To avoid quadratic behavior, (*Line).markRemoved marks the line as dead -// by setting line.Token = nil but does not remove it from the slice -// in which it appears. After edits have all been indicated, -// calling Cleanup cleans out the dead lines. -func (x *FileSyntax) Cleanup() { - w := 0 - for _, stmt := range x.Stmt { - switch stmt := stmt.(type) { - case *Line: - if stmt.Token == nil { - continue - } - case *LineBlock: - ww := 0 - for _, line := range stmt.Line { - if line.Token != nil { - stmt.Line[ww] = line - ww++ - } - } - if ww == 0 { - continue - } - if ww == 1 && len(stmt.RParen.Comments.Before) == 0 { - // Collapse block into single line but keep the Line reference used by the - // parsed File structure. - *stmt.Line[0] = Line{ - Comments: Comments{ - Before: commentsAdd(stmt.Before, stmt.Line[0].Before), - Suffix: commentsAdd(stmt.Line[0].Suffix, stmt.Suffix), - After: commentsAdd(stmt.Line[0].After, stmt.After), - }, - Token: stringsAdd(stmt.Token, stmt.Line[0].Token), - } - x.Stmt[w] = stmt.Line[0] - w++ - continue - } - stmt.Line = stmt.Line[:ww] - } - x.Stmt[w] = stmt - w++ - } - x.Stmt = x.Stmt[:w] -} - -func commentsAdd(x, y []Comment) []Comment { - return append(x[:len(x):len(x)], y...) -} - -func stringsAdd(x, y []string) []string { - return append(x[:len(x):len(x)], y...) -} - -// A CommentBlock represents a top-level block of comments separate -// from any rule. -type CommentBlock struct { - Comments - Start Position -} - -func (x *CommentBlock) Span() (start, end Position) { - return x.Start, x.Start -} - -// A Line is a single line of tokens. -type Line struct { - Comments - Start Position - Token []string - InBlock bool - End Position -} - -func (x *Line) Span() (start, end Position) { - return x.Start, x.End -} - -// A LineBlock is a factored block of lines, like -// -// require ( -// "x" -// "y" -// ) -type LineBlock struct { - Comments - Start Position - LParen LParen - Token []string - Line []*Line - RParen RParen -} - -func (x *LineBlock) Span() (start, end Position) { - return x.Start, x.RParen.Pos.add(")") -} - -// An LParen represents the beginning of a parenthesized line block. -// It is a place to store suffix comments. -type LParen struct { - Comments - Pos Position -} - -func (x *LParen) Span() (start, end Position) { - return x.Pos, x.Pos.add(")") -} - -// An RParen represents the end of a parenthesized line block. -// It is a place to store whole-line (before) comments. -type RParen struct { - Comments - Pos Position -} - -func (x *RParen) Span() (start, end Position) { - return x.Pos, x.Pos.add(")") -} - -// An input represents a single input file being parsed. -type input struct { - // Lexing state. - filename string // name of input file, for errors - complete []byte // entire input - remaining []byte // remaining input - tokenStart []byte // token being scanned to end of input - token token // next token to be returned by lex, peek - pos Position // current input position - comments []Comment // accumulated comments - - // Parser state. - file *FileSyntax // returned top-level syntax tree - parseErrors ErrorList // errors encountered during parsing - - // Comment assignment state. - pre []Expr // all expressions, in preorder traversal - post []Expr // all expressions, in postorder traversal -} - -func newInput(filename string, data []byte) *input { - return &input{ - filename: filename, - complete: data, - remaining: data, - pos: Position{Line: 1, LineRune: 1, Byte: 0}, - } -} - -// parse parses the input file. -func parse(file string, data []byte) (f *FileSyntax, err error) { - // The parser panics for both routine errors like syntax errors - // and for programmer bugs like array index errors. - // Turn both into error returns. Catching bug panics is - // especially important when processing many files. - in := newInput(file, data) - defer func() { - if e := recover(); e != nil && e != &in.parseErrors { - in.parseErrors = append(in.parseErrors, Error{ - Filename: in.filename, - Pos: in.pos, - Err: fmt.Errorf("internal error: %v", e), - }) - } - if err == nil && len(in.parseErrors) > 0 { - err = in.parseErrors - } - }() - - // Prime the lexer by reading in the first token. It will be available - // in the next peek() or lex() call. - in.readToken() - - // Invoke the parser. - in.parseFile() - if len(in.parseErrors) > 0 { - return nil, in.parseErrors - } - in.file.Name = in.filename - - // Assign comments to nearby syntax. - in.assignComments() - - return in.file, nil -} - -// Error is called to report an error. -// Error does not return: it panics. -func (in *input) Error(s string) { - in.parseErrors = append(in.parseErrors, Error{ - Filename: in.filename, - Pos: in.pos, - Err: errors.New(s), - }) - panic(&in.parseErrors) -} - -// eof reports whether the input has reached end of file. -func (in *input) eof() bool { - return len(in.remaining) == 0 -} - -// peekRune returns the next rune in the input without consuming it. -func (in *input) peekRune() int { - if len(in.remaining) == 0 { - return 0 - } - r, _ := utf8.DecodeRune(in.remaining) - return int(r) -} - -// peekPrefix reports whether the remaining input begins with the given prefix. -func (in *input) peekPrefix(prefix string) bool { - // This is like bytes.HasPrefix(in.remaining, []byte(prefix)) - // but without the allocation of the []byte copy of prefix. - for i := 0; i < len(prefix); i++ { - if i >= len(in.remaining) || in.remaining[i] != prefix[i] { - return false - } - } - return true -} - -// readRune consumes and returns the next rune in the input. -func (in *input) readRune() int { - if len(in.remaining) == 0 { - in.Error("internal lexer error: readRune at EOF") - } - r, size := utf8.DecodeRune(in.remaining) - in.remaining = in.remaining[size:] - if r == '\n' { - in.pos.Line++ - in.pos.LineRune = 1 - } else { - in.pos.LineRune++ - } - in.pos.Byte += size - return int(r) -} - -type token struct { - kind tokenKind - pos Position - endPos Position - text string -} - -type tokenKind int - -const ( - _EOF tokenKind = -(iota + 1) - _EOLCOMMENT - _IDENT - _STRING - _COMMENT - - // newlines and punctuation tokens are allowed as ASCII codes. -) - -func (k tokenKind) isComment() bool { - return k == _COMMENT || k == _EOLCOMMENT -} - -// isEOL returns whether a token terminates a line. -func (k tokenKind) isEOL() bool { - return k == _EOF || k == _EOLCOMMENT || k == '\n' -} - -// startToken marks the beginning of the next input token. -// It must be followed by a call to endToken, once the token's text has -// been consumed using readRune. -func (in *input) startToken() { - in.tokenStart = in.remaining - in.token.text = "" - in.token.pos = in.pos -} - -// endToken marks the end of an input token. -// It records the actual token string in tok.text. -// A single trailing newline (LF or CRLF) will be removed from comment tokens. -func (in *input) endToken(kind tokenKind) { - in.token.kind = kind - text := string(in.tokenStart[:len(in.tokenStart)-len(in.remaining)]) - if kind.isComment() { - if strings.HasSuffix(text, "\r\n") { - text = text[:len(text)-2] - } else { - text = strings.TrimSuffix(text, "\n") - } - } - in.token.text = text - in.token.endPos = in.pos -} - -// peek returns the kind of the next token returned by lex. -func (in *input) peek() tokenKind { - return in.token.kind -} - -// lex is called from the parser to obtain the next input token. -func (in *input) lex() token { - tok := in.token - in.readToken() - return tok -} - -// readToken lexes the next token from the text and stores it in in.token. -func (in *input) readToken() { - // Skip past spaces, stopping at non-space or EOF. - for !in.eof() { - c := in.peekRune() - if c == ' ' || c == '\t' || c == '\r' { - in.readRune() - continue - } - - // Comment runs to end of line. - if in.peekPrefix("//") { - in.startToken() - - // Is this comment the only thing on its line? - // Find the last \n before this // and see if it's all - // spaces from there to here. - i := bytes.LastIndex(in.complete[:in.pos.Byte], []byte("\n")) - suffix := len(bytes.TrimSpace(in.complete[i+1:in.pos.Byte])) > 0 - in.readRune() - in.readRune() - - // Consume comment. - for len(in.remaining) > 0 && in.readRune() != '\n' { - } - - // If we are at top level (not in a statement), hand the comment to - // the parser as a _COMMENT token. The grammar is written - // to handle top-level comments itself. - if !suffix { - in.endToken(_COMMENT) - return - } - - // Otherwise, save comment for later attachment to syntax tree. - in.endToken(_EOLCOMMENT) - in.comments = append(in.comments, Comment{in.token.pos, in.token.text, suffix}) - return - } - - if in.peekPrefix("/*") { - in.Error("mod files must use // comments (not /* */ comments)") - } - - // Found non-space non-comment. - break - } - - // Found the beginning of the next token. - in.startToken() - - // End of file. - if in.eof() { - in.endToken(_EOF) - return - } - - // Punctuation tokens. - switch c := in.peekRune(); c { - case '\n', '(', ')', '[', ']', '{', '}', ',': - in.readRune() - in.endToken(tokenKind(c)) - return - - case '"', '`': // quoted string - quote := c - in.readRune() - for { - if in.eof() { - in.pos = in.token.pos - in.Error("unexpected EOF in string") - } - if in.peekRune() == '\n' { - in.Error("unexpected newline in string") - } - c := in.readRune() - if c == quote { - break - } - if c == '\\' && quote != '`' { - if in.eof() { - in.pos = in.token.pos - in.Error("unexpected EOF in string") - } - in.readRune() - } - } - in.endToken(_STRING) - return - } - - // Checked all punctuation. Must be identifier token. - if c := in.peekRune(); !isIdent(c) { - in.Error(fmt.Sprintf("unexpected input character %#q", rune(c))) - } - - // Scan over identifier. - for isIdent(in.peekRune()) { - if in.peekPrefix("//") { - break - } - if in.peekPrefix("/*") { - in.Error("mod files must use // comments (not /* */ comments)") - } - in.readRune() - } - in.endToken(_IDENT) -} - -// isIdent reports whether c is an identifier rune. -// We treat most printable runes as identifier runes, except for a handful of -// ASCII punctuation characters. -func isIdent(c int) bool { - switch r := rune(c); r { - case ' ', '(', ')', '[', ']', '{', '}', ',': - return false - default: - return !unicode.IsSpace(r) && unicode.IsPrint(r) - } -} - -// Comment assignment. -// We build two lists of all subexpressions, preorder and postorder. -// The preorder list is ordered by start location, with outer expressions first. -// The postorder list is ordered by end location, with outer expressions last. -// We use the preorder list to assign each whole-line comment to the syntax -// immediately following it, and we use the postorder list to assign each -// end-of-line comment to the syntax immediately preceding it. - -// order walks the expression adding it and its subexpressions to the -// preorder and postorder lists. -func (in *input) order(x Expr) { - if x != nil { - in.pre = append(in.pre, x) - } - switch x := x.(type) { - default: - panic(fmt.Errorf("order: unexpected type %T", x)) - case nil: - // nothing - case *LParen, *RParen: - // nothing - case *CommentBlock: - // nothing - case *Line: - // nothing - case *FileSyntax: - for _, stmt := range x.Stmt { - in.order(stmt) - } - case *LineBlock: - in.order(&x.LParen) - for _, l := range x.Line { - in.order(l) - } - in.order(&x.RParen) - } - if x != nil { - in.post = append(in.post, x) - } -} - -// assignComments attaches comments to nearby syntax. -func (in *input) assignComments() { - const debug = false - - // Generate preorder and postorder lists. - in.order(in.file) - - // Split into whole-line comments and suffix comments. - var line, suffix []Comment - for _, com := range in.comments { - if com.Suffix { - suffix = append(suffix, com) - } else { - line = append(line, com) - } - } - - if debug { - for _, c := range line { - fmt.Fprintf(os.Stderr, "LINE %q :%d:%d #%d\n", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte) - } - } - - // Assign line comments to syntax immediately following. - for _, x := range in.pre { - start, _ := x.Span() - if debug { - fmt.Fprintf(os.Stderr, "pre %T :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte) - } - xcom := x.Comment() - for len(line) > 0 && start.Byte >= line[0].Start.Byte { - if debug { - fmt.Fprintf(os.Stderr, "ASSIGN LINE %q #%d\n", line[0].Token, line[0].Start.Byte) - } - xcom.Before = append(xcom.Before, line[0]) - line = line[1:] - } - } - - // Remaining line comments go at end of file. - in.file.After = append(in.file.After, line...) - - if debug { - for _, c := range suffix { - fmt.Fprintf(os.Stderr, "SUFFIX %q :%d:%d #%d\n", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte) - } - } - - // Assign suffix comments to syntax immediately before. - for i := len(in.post) - 1; i >= 0; i-- { - x := in.post[i] - - start, end := x.Span() - if debug { - fmt.Fprintf(os.Stderr, "post %T :%d:%d #%d :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte, end.Line, end.LineRune, end.Byte) - } - - // Do not assign suffix comments to end of line block or whole file. - // Instead assign them to the last element inside. - switch x.(type) { - case *FileSyntax: - continue - } - - // Do not assign suffix comments to something that starts - // on an earlier line, so that in - // - // x ( y - // z ) // comment - // - // we assign the comment to z and not to x ( ... ). - if start.Line != end.Line { - continue - } - xcom := x.Comment() - for len(suffix) > 0 && end.Byte <= suffix[len(suffix)-1].Start.Byte { - if debug { - fmt.Fprintf(os.Stderr, "ASSIGN SUFFIX %q #%d\n", suffix[len(suffix)-1].Token, suffix[len(suffix)-1].Start.Byte) - } - xcom.Suffix = append(xcom.Suffix, suffix[len(suffix)-1]) - suffix = suffix[:len(suffix)-1] - } - } - - // We assigned suffix comments in reverse. - // If multiple suffix comments were appended to the same - // expression node, they are now in reverse. Fix that. - for _, x := range in.post { - reverseComments(x.Comment().Suffix) - } - - // Remaining suffix comments go at beginning of file. - in.file.Before = append(in.file.Before, suffix...) -} - -// reverseComments reverses the []Comment list. -func reverseComments(list []Comment) { - for i, j := 0, len(list)-1; i < j; i, j = i+1, j-1 { - list[i], list[j] = list[j], list[i] - } -} - -func (in *input) parseFile() { - in.file = new(FileSyntax) - var cb *CommentBlock - for { - switch in.peek() { - case '\n': - in.lex() - if cb != nil { - in.file.Stmt = append(in.file.Stmt, cb) - cb = nil - } - case _COMMENT: - tok := in.lex() - if cb == nil { - cb = &CommentBlock{Start: tok.pos} - } - com := cb.Comment() - com.Before = append(com.Before, Comment{Start: tok.pos, Token: tok.text}) - case _EOF: - if cb != nil { - in.file.Stmt = append(in.file.Stmt, cb) - } - return - default: - in.parseStmt() - if cb != nil { - in.file.Stmt[len(in.file.Stmt)-1].Comment().Before = cb.Before - cb = nil - } - } - } -} - -func (in *input) parseStmt() { - tok := in.lex() - start := tok.pos - end := tok.endPos - tokens := []string{tok.text} - for { - tok := in.lex() - switch { - case tok.kind.isEOL(): - in.file.Stmt = append(in.file.Stmt, &Line{ - Start: start, - Token: tokens, - End: end, - }) - return - - case tok.kind == '(': - if next := in.peek(); next.isEOL() { - // Start of block: no more tokens on this line. - in.file.Stmt = append(in.file.Stmt, in.parseLineBlock(start, tokens, tok)) - return - } else if next == ')' { - rparen := in.lex() - if in.peek().isEOL() { - // Empty block. - in.lex() - in.file.Stmt = append(in.file.Stmt, &LineBlock{ - Start: start, - Token: tokens, - LParen: LParen{Pos: tok.pos}, - RParen: RParen{Pos: rparen.pos}, - }) - return - } - // '( )' in the middle of the line, not a block. - tokens = append(tokens, tok.text, rparen.text) - } else { - // '(' in the middle of the line, not a block. - tokens = append(tokens, tok.text) - } - - default: - tokens = append(tokens, tok.text) - end = tok.endPos - } - } -} - -func (in *input) parseLineBlock(start Position, token []string, lparen token) *LineBlock { - x := &LineBlock{ - Start: start, - Token: token, - LParen: LParen{Pos: lparen.pos}, - } - var comments []Comment - for { - switch in.peek() { - case _EOLCOMMENT: - // Suffix comment, will be attached later by assignComments. - in.lex() - case '\n': - // Blank line. Add an empty comment to preserve it. - in.lex() - if len(comments) == 0 && len(x.Line) > 0 || len(comments) > 0 && comments[len(comments)-1].Token != "" { - comments = append(comments, Comment{}) - } - case _COMMENT: - tok := in.lex() - comments = append(comments, Comment{Start: tok.pos, Token: tok.text}) - case _EOF: - in.Error(fmt.Sprintf("syntax error (unterminated block started at %s:%d:%d)", in.filename, x.Start.Line, x.Start.LineRune)) - case ')': - rparen := in.lex() - // Don't preserve blank lines (denoted by a single empty comment, added above) - // at the end of the block. - if len(comments) == 1 && comments[0] == (Comment{}) { - comments = nil - } - x.RParen.Before = comments - x.RParen.Pos = rparen.pos - if !in.peek().isEOL() { - in.Error("syntax error (expected newline after closing paren)") - } - in.lex() - return x - default: - l := in.parseLine() - x.Line = append(x.Line, l) - l.Comment().Before = comments - comments = nil - } - } -} - -func (in *input) parseLine() *Line { - tok := in.lex() - if tok.kind.isEOL() { - in.Error("internal parse error: parseLine at end of line") - } - start := tok.pos - end := tok.endPos - tokens := []string{tok.text} - for { - tok := in.lex() - if tok.kind.isEOL() { - return &Line{ - Start: start, - Token: tokens, - End: end, - InBlock: true, - } - } - tokens = append(tokens, tok.text) - end = tok.endPos - } -} - -var ( - slashSlash = []byte("//") - moduleStr = []byte("module") -) - -// ModulePath returns the module path from the gomod file text. -// If it cannot find a module path, it returns an empty string. -// It is tolerant of unrelated problems in the go.mod file. -func ModulePath(mod []byte) string { - for len(mod) > 0 { - line := mod - mod = nil - if i := bytes.IndexByte(line, '\n'); i >= 0 { - line, mod = line[:i], line[i+1:] - } - if i := bytes.Index(line, slashSlash); i >= 0 { - line = line[:i] - } - line = bytes.TrimSpace(line) - if !bytes.HasPrefix(line, moduleStr) { - continue - } - line = line[len(moduleStr):] - n := len(line) - line = bytes.TrimSpace(line) - if len(line) == n || len(line) == 0 { - continue - } - - if line[0] == '"' || line[0] == '`' { - p, err := strconv.Unquote(string(line)) - if err != nil { - return "" // malformed quoted string or multiline module path - } - return p - } - - return string(line) - } - return "" // missing module path -} diff --git a/vendor/golang.org/x/mod/modfile/rule.go b/vendor/golang.org/x/mod/modfile/rule.go deleted file mode 100644 index c5b8305d..00000000 --- a/vendor/golang.org/x/mod/modfile/rule.go +++ /dev/null @@ -1,1904 +0,0 @@ -// Copyright 2018 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 modfile implements a parser and formatter for go.mod files. -// -// The go.mod syntax is described in -// https://pkg.go.dev/cmd/go/#hdr-The_go_mod_file. -// -// The [Parse] and [ParseLax] functions both parse a go.mod file and return an -// abstract syntax tree. ParseLax ignores unknown statements and may be used to -// parse go.mod files that may have been developed with newer versions of Go. -// -// The [File] struct returned by Parse and ParseLax represent an abstract -// go.mod file. File has several methods like [File.AddNewRequire] and -// [File.DropReplace] that can be used to programmatically edit a file. -// -// The [Format] function formats a File back to a byte slice which can be -// written to a file. -package modfile - -import ( - "cmp" - "errors" - "fmt" - "path/filepath" - "slices" - "strconv" - "strings" - "unicode" - - "golang.org/x/mod/internal/lazyregexp" - "golang.org/x/mod/module" - "golang.org/x/mod/semver" -) - -// A File is the parsed, interpreted form of a go.mod file. -type File struct { - Module *Module - Go *Go - Toolchain *Toolchain - Godebug []*Godebug - Require []*Require - Exclude []*Exclude - Replace []*Replace - Retract []*Retract - Tool []*Tool - Ignore []*Ignore - - Syntax *FileSyntax -} - -// A Module is the module statement. -type Module struct { - Mod module.Version - Deprecated string - Syntax *Line -} - -// A Go is the go statement. -type Go struct { - Version string // "1.23" - Syntax *Line -} - -// A Toolchain is the toolchain statement. -type Toolchain struct { - Name string // "go1.21rc1" - Syntax *Line -} - -// A Godebug is a single godebug key=value statement. -type Godebug struct { - Key string - Value string - Syntax *Line -} - -// An Exclude is a single exclude statement. -type Exclude struct { - Mod module.Version - Syntax *Line -} - -// A Replace is a single replace statement. -type Replace struct { - Old module.Version - New module.Version - Syntax *Line -} - -// A Retract is a single retract statement. -type Retract struct { - VersionInterval - Rationale string - Syntax *Line -} - -// A Tool is a single tool statement. -type Tool struct { - Path string - Syntax *Line -} - -// An Ignore is a single ignore statement. -type Ignore struct { - Path string - Syntax *Line -} - -// A VersionInterval represents a range of versions with upper and lower bounds. -// Intervals are closed: both bounds are included. When Low is equal to High, -// the interval may refer to a single version ('v1.2.3') or an interval -// ('[v1.2.3, v1.2.3]'); both have the same representation. -type VersionInterval struct { - Low, High string -} - -// A Require is a single require statement. -type Require struct { - Mod module.Version - Indirect bool // has "// indirect" comment - Syntax *Line -} - -func (r *Require) markRemoved() { - r.Syntax.markRemoved() - *r = Require{} -} - -func (r *Require) setVersion(v string) { - r.Mod.Version = v - - if line := r.Syntax; len(line.Token) > 0 { - if line.InBlock { - // If the line is preceded by an empty line, remove it; see - // https://golang.org/issue/33779. - if len(line.Comments.Before) == 1 && len(line.Comments.Before[0].Token) == 0 { - line.Comments.Before = line.Comments.Before[:0] - } - if len(line.Token) >= 2 { // example.com v1.2.3 - line.Token[1] = v - } - } else { - if len(line.Token) >= 3 { // require example.com v1.2.3 - line.Token[2] = v - } - } - } -} - -// setIndirect sets line to have (or not have) a "// indirect" comment. -func (r *Require) setIndirect(indirect bool) { - r.Indirect = indirect - line := r.Syntax - if isIndirect(line) == indirect { - return - } - if indirect { - // Adding comment. - if len(line.Suffix) == 0 { - // New comment. - line.Suffix = []Comment{{Token: "// indirect", Suffix: true}} - return - } - - com := &line.Suffix[0] - text := strings.TrimSpace(strings.TrimPrefix(com.Token, string(slashSlash))) - if text == "" { - // Empty comment. - com.Token = "// indirect" - return - } - - // Insert at beginning of existing comment. - com.Token = "// indirect; " + text - return - } - - // Removing comment. - f := strings.TrimSpace(strings.TrimPrefix(line.Suffix[0].Token, string(slashSlash))) - if f == "indirect" { - // Remove whole comment. - line.Suffix = nil - return - } - - // Remove comment prefix. - com := &line.Suffix[0] - i := strings.Index(com.Token, "indirect;") - com.Token = "//" + com.Token[i+len("indirect;"):] -} - -// isIndirect reports whether line has a "// indirect" comment, -// meaning it is in go.mod only for its effect on indirect dependencies, -// so that it can be dropped entirely once the effective version of the -// indirect dependency reaches the given minimum version. -func isIndirect(line *Line) bool { - if len(line.Suffix) == 0 { - return false - } - f := strings.Fields(strings.TrimPrefix(line.Suffix[0].Token, string(slashSlash))) - return (len(f) == 1 && f[0] == "indirect" || len(f) > 1 && f[0] == "indirect;") -} - -func (f *File) AddModuleStmt(path string) error { - if f.Syntax == nil { - f.Syntax = new(FileSyntax) - } - if f.Module == nil { - f.Module = &Module{ - Mod: module.Version{Path: path}, - Syntax: f.Syntax.addLine(nil, "module", AutoQuote(path)), - } - } else { - f.Module.Mod.Path = path - f.Syntax.updateLine(f.Module.Syntax, "module", AutoQuote(path)) - } - return nil -} - -func (f *File) AddComment(text string) { - if f.Syntax == nil { - f.Syntax = new(FileSyntax) - } - f.Syntax.Stmt = append(f.Syntax.Stmt, &CommentBlock{ - Comments: Comments{ - Before: []Comment{ - { - Token: text, - }, - }, - }, - }) -} - -type VersionFixer func(path, version string) (string, error) - -// errDontFix is returned by a VersionFixer to indicate the version should be -// left alone, even if it's not canonical. -var dontFixRetract VersionFixer = func(_, vers string) (string, error) { - return vers, nil -} - -// Parse parses and returns a go.mod file. -// -// file is the name of the file, used in positions and errors. -// -// data is the content of the file. -// -// fix is an optional function that canonicalizes module versions. -// If fix is nil, all module versions must be canonical ([module.CanonicalVersion] -// must return the same string). -func Parse(file string, data []byte, fix VersionFixer) (*File, error) { - return parseToFile(file, data, fix, true) -} - -// ParseLax is like Parse but ignores unknown statements. -// It is used when parsing go.mod files other than the main module, -// under the theory that most statement types we add in the future will -// only apply in the main module, like exclude and replace, -// and so we get better gradual deployments if old go commands -// simply ignore those statements when found in go.mod files -// in dependencies. -func ParseLax(file string, data []byte, fix VersionFixer) (*File, error) { - return parseToFile(file, data, fix, false) -} - -func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (parsed *File, err error) { - fs, err := parse(file, data) - if err != nil { - return nil, err - } - f := &File{ - Syntax: fs, - } - var errs ErrorList - - // fix versions in retract directives after the file is parsed. - // We need the module path to fix versions, and it might be at the end. - defer func() { - oldLen := len(errs) - f.fixRetract(fix, &errs) - if len(errs) > oldLen { - parsed, err = nil, errs - } - }() - - for _, x := range fs.Stmt { - switch x := x.(type) { - case *Line: - f.add(&errs, nil, x, x.Token[0], x.Token[1:], fix, strict) - - case *LineBlock: - if len(x.Token) > 1 { - if strict { - errs = append(errs, Error{ - Filename: file, - Pos: x.Start, - Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), - }) - } - continue - } - switch x.Token[0] { - default: - if strict { - errs = append(errs, Error{ - Filename: file, - Pos: x.Start, - Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), - }) - } - continue - case "module", "godebug", "require", "exclude", "replace", "retract", "tool", "ignore": - for _, l := range x.Line { - f.add(&errs, x, l, x.Token[0], l.Token, fix, strict) - } - } - } - } - - if len(errs) > 0 { - return nil, errs - } - return f, nil -} - -var GoVersionRE = lazyregexp.New(`^([1-9][0-9]*)\.(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))?([a-z]+[0-9]+)?$`) -var laxGoVersionRE = lazyregexp.New(`^v?(([1-9][0-9]*)\.(0|[1-9][0-9]*))([^0-9].*)$`) - -// Toolchains must be named beginning with `go1`, -// like "go1.20.3" or "go1.20.3-gccgo". As a special case, "default" is also permitted. -// Note that this regexp is a much looser condition than go/version.IsValid, -// for forward compatibility. -// (This code has to be work to identify new toolchains even if we tweak the syntax in the future.) -var ToolchainRE = lazyregexp.New(`^default$|^go1($|\.)`) - -func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, args []string, fix VersionFixer, strict bool) { - // If strict is false, this module is a dependency. - // We ignore all unknown directives as well as main-module-only - // directives like replace and exclude. It will work better for - // forward compatibility if we can depend on modules that have unknown - // statements (presumed relevant only when acting as the main module) - // and simply ignore those statements. - if !strict { - switch verb { - case "go", "module", "retract", "require", "ignore": - // want these even for dependency go.mods - default: - return - } - } - - wrapModPathError := func(modPath string, err error) { - *errs = append(*errs, Error{ - Filename: f.Syntax.Name, - Pos: line.Start, - ModPath: modPath, - Verb: verb, - Err: err, - }) - } - wrapError := func(err error) { - *errs = append(*errs, Error{ - Filename: f.Syntax.Name, - Pos: line.Start, - Err: err, - }) - } - errorf := func(format string, args ...any) { - wrapError(fmt.Errorf(format, args...)) - } - - switch verb { - default: - errorf("unknown directive: %s", verb) - - case "go": - if f.Go != nil { - errorf("repeated go statement") - return - } - if len(args) != 1 { - errorf("go directive expects exactly one argument") - return - } else if !GoVersionRE.MatchString(args[0]) { - fixed := false - if !strict { - if m := laxGoVersionRE.FindStringSubmatch(args[0]); m != nil { - args[0] = m[1] - fixed = true - } - } - if !fixed { - errorf("invalid go version '%s': must match format 1.23.0", args[0]) - return - } - } - - f.Go = &Go{Syntax: line} - f.Go.Version = args[0] - - case "toolchain": - if f.Toolchain != nil { - errorf("repeated toolchain statement") - return - } - if len(args) != 1 { - errorf("toolchain directive expects exactly one argument") - return - } else if !ToolchainRE.MatchString(args[0]) { - errorf("invalid toolchain version '%s': must match format go1.23.0 or default", args[0]) - return - } - f.Toolchain = &Toolchain{Syntax: line} - f.Toolchain.Name = args[0] - - case "module": - if f.Module != nil { - errorf("repeated module statement") - return - } - deprecated := parseDeprecation(block, line) - f.Module = &Module{ - Syntax: line, - Deprecated: deprecated, - } - if len(args) != 1 { - errorf("usage: module module/path") - return - } - s, err := parseString(&args[0]) - if err != nil { - errorf("invalid quoted string: %v", err) - return - } - f.Module.Mod = module.Version{Path: s} - - case "godebug": - if len(args) != 1 || strings.ContainsAny(args[0], "\"`',") { - errorf("usage: godebug key=value") - return - } - key, value, ok := strings.Cut(args[0], "=") - if !ok { - errorf("usage: godebug key=value") - return - } - f.Godebug = append(f.Godebug, &Godebug{ - Key: key, - Value: value, - Syntax: line, - }) - - case "require", "exclude": - if len(args) != 2 { - errorf("usage: %s module/path v1.2.3", verb) - return - } - s, err := parseString(&args[0]) - if err != nil { - errorf("invalid quoted string: %v", err) - return - } - v, err := parseVersion(verb, s, &args[1], fix) - if err != nil { - wrapError(err) - return - } - pathMajor, err := modulePathMajor(s) - if err != nil { - wrapError(err) - return - } - if err := module.CheckPathMajor(v, pathMajor); err != nil { - wrapModPathError(s, err) - return - } - if verb == "require" { - f.Require = append(f.Require, &Require{ - Mod: module.Version{Path: s, Version: v}, - Syntax: line, - Indirect: isIndirect(line), - }) - } else { - f.Exclude = append(f.Exclude, &Exclude{ - Mod: module.Version{Path: s, Version: v}, - Syntax: line, - }) - } - - case "replace": - replace, wrappederr := parseReplace(f.Syntax.Name, line, verb, args, fix) - if wrappederr != nil { - *errs = append(*errs, *wrappederr) - return - } - f.Replace = append(f.Replace, replace) - - case "retract": - rationale := parseDirectiveComment(block, line) - vi, err := parseVersionInterval(verb, "", &args, dontFixRetract) - if err != nil { - if strict { - wrapError(err) - return - } else { - // Only report errors parsing intervals in the main module. We may - // support additional syntax in the future, such as open and half-open - // intervals. Those can't be supported now, because they break the - // go.mod parser, even in lax mode. - return - } - } - if len(args) > 0 && strict { - // In the future, there may be additional information after the version. - errorf("unexpected token after version: %q", args[0]) - return - } - retract := &Retract{ - VersionInterval: vi, - Rationale: rationale, - Syntax: line, - } - f.Retract = append(f.Retract, retract) - - case "tool": - if len(args) != 1 { - errorf("tool directive expects exactly one argument") - return - } - s, err := parseString(&args[0]) - if err != nil { - errorf("invalid quoted string: %v", err) - return - } - f.Tool = append(f.Tool, &Tool{ - Path: s, - Syntax: line, - }) - - case "ignore": - if len(args) != 1 { - errorf("ignore directive expects exactly one argument") - return - } - s, err := parseString(&args[0]) - if err != nil { - errorf("invalid quoted string: %v", err) - return - } - f.Ignore = append(f.Ignore, &Ignore{ - Path: s, - Syntax: line, - }) - } -} - -func parseReplace(filename string, line *Line, verb string, args []string, fix VersionFixer) (*Replace, *Error) { - wrapModPathError := func(modPath string, err error) *Error { - return &Error{ - Filename: filename, - Pos: line.Start, - ModPath: modPath, - Verb: verb, - Err: err, - } - } - wrapError := func(err error) *Error { - return &Error{ - Filename: filename, - Pos: line.Start, - Err: err, - } - } - errorf := func(format string, args ...any) *Error { - return wrapError(fmt.Errorf(format, args...)) - } - - arrow := 2 - if len(args) >= 2 && args[1] == "=>" { - arrow = 1 - } - if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" { - return nil, errorf("usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory", verb, verb) - } - s, err := parseString(&args[0]) - if err != nil { - return nil, errorf("invalid quoted string: %v", err) - } - pathMajor, err := modulePathMajor(s) - if err != nil { - return nil, wrapModPathError(s, err) - - } - var v string - if arrow == 2 { - v, err = parseVersion(verb, s, &args[1], fix) - if err != nil { - return nil, wrapError(err) - } - if err := module.CheckPathMajor(v, pathMajor); err != nil { - return nil, wrapModPathError(s, err) - } - } - ns, err := parseString(&args[arrow+1]) - if err != nil { - return nil, errorf("invalid quoted string: %v", err) - } - nv := "" - if len(args) == arrow+2 { - if !IsDirectoryPath(ns) { - if strings.Contains(ns, "@") { - return nil, errorf("replacement module must match format 'path version', not 'path@version'") - } - return nil, errorf("replacement module without version must be directory path (rooted or starting with . or ..)") - } - if filepath.Separator == '/' && strings.Contains(ns, `\`) { - return nil, errorf("replacement directory appears to be Windows path (on a non-windows system)") - } - } - if len(args) == arrow+3 { - nv, err = parseVersion(verb, ns, &args[arrow+2], fix) - if err != nil { - return nil, wrapError(err) - } - if IsDirectoryPath(ns) { - return nil, errorf("replacement module directory path %q cannot have version", ns) - } - } - return &Replace{ - Old: module.Version{Path: s, Version: v}, - New: module.Version{Path: ns, Version: nv}, - Syntax: line, - }, nil -} - -// fixRetract applies fix to each retract directive in f, appending any errors -// to errs. -// -// Most versions are fixed as we parse the file, but for retract directives, -// the relevant module path is the one specified with the module directive, -// and that might appear at the end of the file (or not at all). -func (f *File) fixRetract(fix VersionFixer, errs *ErrorList) { - if fix == nil { - return - } - path := "" - if f.Module != nil { - path = f.Module.Mod.Path - } - var r *Retract - wrapError := func(err error) { - *errs = append(*errs, Error{ - Filename: f.Syntax.Name, - Pos: r.Syntax.Start, - Err: err, - }) - } - - for _, r = range f.Retract { - if path == "" { - wrapError(errors.New("no module directive found, so retract cannot be used")) - return // only print the first one of these - } - - args := r.Syntax.Token - if args[0] == "retract" { - args = args[1:] - } - vi, err := parseVersionInterval("retract", path, &args, fix) - if err != nil { - wrapError(err) - } - r.VersionInterval = vi - } -} - -func (f *WorkFile) add(errs *ErrorList, line *Line, verb string, args []string, fix VersionFixer) { - wrapError := func(err error) { - *errs = append(*errs, Error{ - Filename: f.Syntax.Name, - Pos: line.Start, - Err: err, - }) - } - errorf := func(format string, args ...any) { - wrapError(fmt.Errorf(format, args...)) - } - - switch verb { - default: - errorf("unknown directive: %s", verb) - - case "go": - if f.Go != nil { - errorf("repeated go statement") - return - } - if len(args) != 1 { - errorf("go directive expects exactly one argument") - return - } else if !GoVersionRE.MatchString(args[0]) { - errorf("invalid go version '%s': must match format 1.23.0", args[0]) - return - } - - f.Go = &Go{Syntax: line} - f.Go.Version = args[0] - - case "toolchain": - if f.Toolchain != nil { - errorf("repeated toolchain statement") - return - } - if len(args) != 1 { - errorf("toolchain directive expects exactly one argument") - return - } else if !ToolchainRE.MatchString(args[0]) { - errorf("invalid toolchain version '%s': must match format go1.23.0 or default", args[0]) - return - } - - f.Toolchain = &Toolchain{Syntax: line} - f.Toolchain.Name = args[0] - - case "godebug": - if len(args) != 1 || strings.ContainsAny(args[0], "\"`',") { - errorf("usage: godebug key=value") - return - } - key, value, ok := strings.Cut(args[0], "=") - if !ok { - errorf("usage: godebug key=value") - return - } - f.Godebug = append(f.Godebug, &Godebug{ - Key: key, - Value: value, - Syntax: line, - }) - - case "use": - if len(args) != 1 { - errorf("usage: %s local/dir", verb) - return - } - s, err := parseString(&args[0]) - if err != nil { - errorf("invalid quoted string: %v", err) - return - } - f.Use = append(f.Use, &Use{ - Path: s, - Syntax: line, - }) - - case "replace": - replace, wrappederr := parseReplace(f.Syntax.Name, line, verb, args, fix) - if wrappederr != nil { - *errs = append(*errs, *wrappederr) - return - } - f.Replace = append(f.Replace, replace) - } -} - -// IsDirectoryPath reports whether the given path should be interpreted as a directory path. -// Just like on the go command line, relative paths starting with a '.' or '..' path component -// and rooted paths are directory paths; the rest are module paths. -func IsDirectoryPath(ns string) bool { - // Because go.mod files can move from one system to another, - // we check all known path syntaxes, both Unix and Windows. - return ns == "." || strings.HasPrefix(ns, "./") || strings.HasPrefix(ns, `.\`) || - ns == ".." || strings.HasPrefix(ns, "../") || strings.HasPrefix(ns, `..\`) || - strings.HasPrefix(ns, "/") || strings.HasPrefix(ns, `\`) || - len(ns) >= 2 && ('A' <= ns[0] && ns[0] <= 'Z' || 'a' <= ns[0] && ns[0] <= 'z') && ns[1] == ':' -} - -// MustQuote reports whether s must be quoted in order to appear as -// a single token in a go.mod line. -func MustQuote(s string) bool { - for _, r := range s { - switch r { - case ' ', '"', '\'', '`': - return true - - case '(', ')', '[', ']', '{', '}', ',': - if len(s) > 1 { - return true - } - - default: - if !unicode.IsPrint(r) { - return true - } - } - } - return s == "" || strings.Contains(s, "//") || strings.Contains(s, "/*") -} - -// AutoQuote returns s or, if quoting is required for s to appear in a go.mod, -// the quotation of s. -func AutoQuote(s string) string { - if MustQuote(s) { - return strconv.Quote(s) - } - return s -} - -func parseVersionInterval(verb string, path string, args *[]string, fix VersionFixer) (VersionInterval, error) { - toks := *args - if len(toks) == 0 || toks[0] == "(" { - return VersionInterval{}, fmt.Errorf("expected '[' or version") - } - if toks[0] != "[" { - v, err := parseVersion(verb, path, &toks[0], fix) - if err != nil { - return VersionInterval{}, err - } - *args = toks[1:] - return VersionInterval{Low: v, High: v}, nil - } - toks = toks[1:] - - if len(toks) == 0 { - return VersionInterval{}, fmt.Errorf("expected version after '['") - } - low, err := parseVersion(verb, path, &toks[0], fix) - if err != nil { - return VersionInterval{}, err - } - toks = toks[1:] - - if len(toks) == 0 || toks[0] != "," { - return VersionInterval{}, fmt.Errorf("expected ',' after version") - } - toks = toks[1:] - - if len(toks) == 0 { - return VersionInterval{}, fmt.Errorf("expected version after ','") - } - high, err := parseVersion(verb, path, &toks[0], fix) - if err != nil { - return VersionInterval{}, err - } - toks = toks[1:] - - if len(toks) == 0 || toks[0] != "]" { - return VersionInterval{}, fmt.Errorf("expected ']' after version") - } - toks = toks[1:] - - *args = toks - return VersionInterval{Low: low, High: high}, nil -} - -func parseString(s *string) (string, error) { - t := *s - if strings.HasPrefix(t, `"`) { - var err error - if t, err = strconv.Unquote(t); err != nil { - return "", err - } - } else if strings.ContainsAny(t, "\"'`") { - // Other quotes are reserved both for possible future expansion - // and to avoid confusion. For example if someone types 'x' - // we want that to be a syntax error and not a literal x in literal quotation marks. - return "", fmt.Errorf("unquoted string cannot contain quote") - } - *s = AutoQuote(t) - return t, nil -} - -var deprecatedRE = lazyregexp.New(`(?s)(?:^|\n\n)Deprecated: *(.*?)(?:$|\n\n)`) - -// parseDeprecation extracts the text of comments on a "module" directive and -// extracts a deprecation message from that. -// -// A deprecation message is contained in a paragraph within a block of comments -// that starts with "Deprecated:" (case sensitive). The message runs until the -// end of the paragraph and does not include the "Deprecated:" prefix. If the -// comment block has multiple paragraphs that start with "Deprecated:", -// parseDeprecation returns the message from the first. -func parseDeprecation(block *LineBlock, line *Line) string { - text := parseDirectiveComment(block, line) - m := deprecatedRE.FindStringSubmatch(text) - if m == nil { - return "" - } - return m[1] -} - -// parseDirectiveComment extracts the text of comments on a directive. -// If the directive's line does not have comments and is part of a block that -// does have comments, the block's comments are used. -func parseDirectiveComment(block *LineBlock, line *Line) string { - comments := line.Comment() - if block != nil && len(comments.Before) == 0 && len(comments.Suffix) == 0 { - comments = block.Comment() - } - groups := [][]Comment{comments.Before, comments.Suffix} - var lines []string - for _, g := range groups { - for _, c := range g { - if !strings.HasPrefix(c.Token, "//") { - continue // blank line - } - lines = append(lines, strings.TrimSpace(strings.TrimPrefix(c.Token, "//"))) - } - } - return strings.Join(lines, "\n") -} - -type ErrorList []Error - -func (e ErrorList) Error() string { - errStrs := make([]string, len(e)) - for i, err := range e { - errStrs[i] = err.Error() - } - return strings.Join(errStrs, "\n") -} - -type Error struct { - Filename string - Pos Position - Verb string - ModPath string - Err error -} - -func (e *Error) Error() string { - var pos string - if e.Pos.LineRune > 1 { - // Don't print LineRune if it's 1 (beginning of line). - // It's always 1 except in scanner errors, which are rare. - pos = fmt.Sprintf("%s:%d:%d: ", e.Filename, e.Pos.Line, e.Pos.LineRune) - } else if e.Pos.Line > 0 { - pos = fmt.Sprintf("%s:%d: ", e.Filename, e.Pos.Line) - } else if e.Filename != "" { - pos = fmt.Sprintf("%s: ", e.Filename) - } - - var directive string - if e.ModPath != "" { - directive = fmt.Sprintf("%s %s: ", e.Verb, e.ModPath) - } else if e.Verb != "" { - directive = fmt.Sprintf("%s: ", e.Verb) - } - - return pos + directive + e.Err.Error() -} - -func (e *Error) Unwrap() error { return e.Err } - -func parseVersion(verb string, path string, s *string, fix VersionFixer) (string, error) { - t, err := parseString(s) - if err != nil { - return "", &Error{ - Verb: verb, - ModPath: path, - Err: &module.InvalidVersionError{ - Version: *s, - Err: err, - }, - } - } - if fix != nil { - fixed, err := fix(path, t) - if err != nil { - if err, ok := err.(*module.ModuleError); ok { - return "", &Error{ - Verb: verb, - ModPath: path, - Err: err.Err, - } - } - return "", err - } - t = fixed - } else { - cv := module.CanonicalVersion(t) - if cv == "" { - return "", &Error{ - Verb: verb, - ModPath: path, - Err: &module.InvalidVersionError{ - Version: t, - Err: errors.New("must be of the form v1.2.3"), - }, - } - } - t = cv - } - *s = t - return *s, nil -} - -func modulePathMajor(path string) (string, error) { - _, major, ok := module.SplitPathVersion(path) - if !ok { - return "", fmt.Errorf("invalid module path") - } - return major, nil -} - -func (f *File) Format() ([]byte, error) { - return Format(f.Syntax), nil -} - -// Cleanup cleans up the file f after any edit operations. -// To avoid quadratic behavior, modifications like [File.DropRequire] -// clear the entry but do not remove it from the slice. -// Cleanup cleans out all the cleared entries. -func (f *File) Cleanup() { - w := 0 - for _, g := range f.Godebug { - if g.Key != "" { - f.Godebug[w] = g - w++ - } - } - f.Godebug = f.Godebug[:w] - - w = 0 - for _, r := range f.Require { - if r.Mod.Path != "" { - f.Require[w] = r - w++ - } - } - f.Require = f.Require[:w] - - w = 0 - for _, x := range f.Exclude { - if x.Mod.Path != "" { - f.Exclude[w] = x - w++ - } - } - f.Exclude = f.Exclude[:w] - - w = 0 - for _, r := range f.Replace { - if r.Old.Path != "" { - f.Replace[w] = r - w++ - } - } - f.Replace = f.Replace[:w] - - w = 0 - for _, r := range f.Retract { - if r.Low != "" || r.High != "" { - f.Retract[w] = r - w++ - } - } - f.Retract = f.Retract[:w] - - f.Syntax.Cleanup() -} - -func (f *File) AddGoStmt(version string) error { - if !GoVersionRE.MatchString(version) { - return fmt.Errorf("invalid language version %q", version) - } - if f.Go == nil { - var hint Expr - if f.Module != nil && f.Module.Syntax != nil { - hint = f.Module.Syntax - } else if f.Syntax == nil { - f.Syntax = new(FileSyntax) - } - f.Go = &Go{ - Version: version, - Syntax: f.Syntax.addLine(hint, "go", version), - } - } else { - f.Go.Version = version - f.Syntax.updateLine(f.Go.Syntax, "go", version) - } - return nil -} - -// DropGoStmt deletes the go statement from the file. -func (f *File) DropGoStmt() { - if f.Go != nil { - f.Go.Syntax.markRemoved() - f.Go = nil - } -} - -// DropToolchainStmt deletes the toolchain statement from the file. -func (f *File) DropToolchainStmt() { - if f.Toolchain != nil { - f.Toolchain.Syntax.markRemoved() - f.Toolchain = nil - } -} - -func (f *File) AddToolchainStmt(name string) error { - if !ToolchainRE.MatchString(name) { - return fmt.Errorf("invalid toolchain name %q", name) - } - if f.Toolchain == nil { - var hint Expr - if f.Go != nil && f.Go.Syntax != nil { - hint = f.Go.Syntax - } else if f.Module != nil && f.Module.Syntax != nil { - hint = f.Module.Syntax - } - f.Toolchain = &Toolchain{ - Name: name, - Syntax: f.Syntax.addLine(hint, "toolchain", name), - } - } else { - f.Toolchain.Name = name - f.Syntax.updateLine(f.Toolchain.Syntax, "toolchain", name) - } - return nil -} - -// AddGodebug sets the first godebug line for key to value, -// preserving any existing comments for that line and removing all -// other godebug lines for key. -// -// If no line currently exists for key, AddGodebug adds a new line -// at the end of the last godebug block. -func (f *File) AddGodebug(key, value string) error { - need := true - for _, g := range f.Godebug { - if g.Key == key { - if need { - g.Value = value - f.Syntax.updateLine(g.Syntax, "godebug", key+"="+value) - need = false - } else { - g.Syntax.markRemoved() - *g = Godebug{} - } - } - } - - if need { - f.addNewGodebug(key, value) - } - return nil -} - -// addNewGodebug adds a new godebug key=value line at the end -// of the last godebug block, regardless of any existing godebug lines for key. -func (f *File) addNewGodebug(key, value string) { - line := f.Syntax.addLine(nil, "godebug", key+"="+value) - g := &Godebug{ - Key: key, - Value: value, - Syntax: line, - } - f.Godebug = append(f.Godebug, g) -} - -// AddRequire sets the first require line for path to version vers, -// preserving any existing comments for that line and removing all -// other lines for path. -// -// If no line currently exists for path, AddRequire adds a new line -// at the end of the last require block. -func (f *File) AddRequire(path, vers string) error { - need := true - for _, r := range f.Require { - if r.Mod.Path == path { - if need { - r.Mod.Version = vers - f.Syntax.updateLine(r.Syntax, "require", AutoQuote(path), vers) - need = false - } else { - r.Syntax.markRemoved() - *r = Require{} - } - } - } - - if need { - f.AddNewRequire(path, vers, false) - } - return nil -} - -// AddNewRequire adds a new require line for path at version vers at the end of -// the last require block, regardless of any existing require lines for path. -func (f *File) AddNewRequire(path, vers string, indirect bool) { - line := f.Syntax.addLine(nil, "require", AutoQuote(path), vers) - r := &Require{ - Mod: module.Version{Path: path, Version: vers}, - Syntax: line, - } - r.setIndirect(indirect) - f.Require = append(f.Require, r) -} - -// SetRequire updates the requirements of f to contain exactly req, preserving -// the existing block structure and line comment contents (except for 'indirect' -// markings) for the first requirement on each named module path. -// -// The Syntax field is ignored for the requirements in req. -// -// Any requirements not already present in the file are added to the block -// containing the last require line. -// -// The requirements in req must specify at most one distinct version for each -// module path. -// -// If any existing requirements may be removed, the caller should call -// [File.Cleanup] after all edits are complete. -func (f *File) SetRequire(req []*Require) { - type elem struct { - version string - indirect bool - } - need := make(map[string]elem) - for _, r := range req { - if prev, dup := need[r.Mod.Path]; dup && prev.version != r.Mod.Version { - panic(fmt.Errorf("SetRequire called with conflicting versions for path %s (%s and %s)", r.Mod.Path, prev.version, r.Mod.Version)) - } - need[r.Mod.Path] = elem{r.Mod.Version, r.Indirect} - } - - // Update or delete the existing Require entries to preserve - // only the first for each module path in req. - for _, r := range f.Require { - e, ok := need[r.Mod.Path] - if ok { - r.setVersion(e.version) - r.setIndirect(e.indirect) - } else { - r.markRemoved() - } - delete(need, r.Mod.Path) - } - - // Add new entries in the last block of the file for any paths that weren't - // already present. - // - // This step is nondeterministic, but the final result will be deterministic - // because we will sort the block. - for path, e := range need { - f.AddNewRequire(path, e.version, e.indirect) - } - - f.SortBlocks() -} - -// SetRequireSeparateIndirect updates the requirements of f to contain the given -// requirements. Comment contents (except for 'indirect' markings) are retained -// from the first existing requirement for each module path. Like SetRequire, -// SetRequireSeparateIndirect adds requirements for new paths in req, -// updates the version and "// indirect" comment on existing requirements, -// and deletes requirements on paths not in req. Existing duplicate requirements -// are deleted. -// -// As its name suggests, SetRequireSeparateIndirect puts direct and indirect -// requirements into two separate blocks, one containing only direct -// requirements, and the other containing only indirect requirements. -// SetRequireSeparateIndirect may move requirements between these two blocks -// when their indirect markings change. However, SetRequireSeparateIndirect -// won't move requirements from other blocks, especially blocks with comments. -// -// If the file initially has one uncommented block of requirements, -// SetRequireSeparateIndirect will split it into a direct-only and indirect-only -// block. This aids in the transition to separate blocks. -func (f *File) SetRequireSeparateIndirect(req []*Require) { - // hasComments returns whether a line or block has comments - // other than "indirect". - hasComments := func(c Comments) bool { - return len(c.Before) > 0 || len(c.After) > 0 || len(c.Suffix) > 1 || - (len(c.Suffix) == 1 && - strings.TrimSpace(strings.TrimPrefix(c.Suffix[0].Token, string(slashSlash))) != "indirect") - } - - // moveReq adds r to block. If r was in another block, moveReq deletes - // it from that block and transfers its comments. - moveReq := func(r *Require, block *LineBlock) { - var line *Line - if r.Syntax == nil { - line = &Line{Token: []string{AutoQuote(r.Mod.Path), r.Mod.Version}} - r.Syntax = line - if r.Indirect { - r.setIndirect(true) - } - } else { - line = new(Line) - *line = *r.Syntax - if !line.InBlock && len(line.Token) > 0 && line.Token[0] == "require" { - line.Token = line.Token[1:] - } - r.Syntax.Token = nil // Cleanup will delete the old line. - r.Syntax = line - } - line.InBlock = true - block.Line = append(block.Line, line) - } - - // Examine existing require lines and blocks. - var ( - // We may insert new requirements into the last uncommented - // direct-only and indirect-only blocks. We may also move requirements - // to the opposite block if their indirect markings change. - lastDirectIndex = -1 - lastIndirectIndex = -1 - - // If there are no direct-only or indirect-only blocks, a new block may - // be inserted after the last require line or block. - lastRequireIndex = -1 - - // If there's only one require line or block, and it's uncommented, - // we'll move its requirements to the direct-only or indirect-only blocks. - requireLineOrBlockCount = 0 - - // Track the block each requirement belongs to (if any) so we can - // move them later. - lineToBlock = make(map[*Line]*LineBlock) - ) - for i, stmt := range f.Syntax.Stmt { - switch stmt := stmt.(type) { - case *Line: - if len(stmt.Token) == 0 || stmt.Token[0] != "require" { - continue - } - lastRequireIndex = i - requireLineOrBlockCount++ - if !hasComments(stmt.Comments) { - if isIndirect(stmt) { - lastIndirectIndex = i - } else { - lastDirectIndex = i - } - } - - case *LineBlock: - if len(stmt.Token) == 0 || stmt.Token[0] != "require" { - continue - } - lastRequireIndex = i - requireLineOrBlockCount++ - allDirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments) - allIndirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments) - for _, line := range stmt.Line { - lineToBlock[line] = stmt - if hasComments(line.Comments) { - allDirect = false - allIndirect = false - } else if isIndirect(line) { - allDirect = false - } else { - allIndirect = false - } - } - if allDirect { - lastDirectIndex = i - } - if allIndirect { - lastIndirectIndex = i - } - } - } - - oneFlatUncommentedBlock := requireLineOrBlockCount == 1 && - !hasComments(*f.Syntax.Stmt[lastRequireIndex].Comment()) - - // Create direct and indirect blocks if needed. Convert lines into blocks - // if needed. If we end up with an empty block or a one-line block, - // Cleanup will delete it or convert it to a line later. - insertBlock := func(i int) *LineBlock { - block := &LineBlock{Token: []string{"require"}} - f.Syntax.Stmt = append(f.Syntax.Stmt, nil) - copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:]) - f.Syntax.Stmt[i] = block - return block - } - - ensureBlock := func(i int) *LineBlock { - switch stmt := f.Syntax.Stmt[i].(type) { - case *LineBlock: - return stmt - case *Line: - block := &LineBlock{ - Token: []string{"require"}, - Line: []*Line{stmt}, - } - stmt.Token = stmt.Token[1:] // remove "require" - stmt.InBlock = true - f.Syntax.Stmt[i] = block - return block - default: - panic(fmt.Sprintf("unexpected statement: %v", stmt)) - } - } - - var lastDirectBlock *LineBlock - if lastDirectIndex < 0 { - if lastIndirectIndex >= 0 { - lastDirectIndex = lastIndirectIndex - lastIndirectIndex++ - } else if lastRequireIndex >= 0 { - lastDirectIndex = lastRequireIndex + 1 - } else { - lastDirectIndex = len(f.Syntax.Stmt) - } - lastDirectBlock = insertBlock(lastDirectIndex) - } else { - lastDirectBlock = ensureBlock(lastDirectIndex) - } - - var lastIndirectBlock *LineBlock - if lastIndirectIndex < 0 { - lastIndirectIndex = lastDirectIndex + 1 - lastIndirectBlock = insertBlock(lastIndirectIndex) - } else { - lastIndirectBlock = ensureBlock(lastIndirectIndex) - } - - // Delete requirements we don't want anymore. - // Update versions and indirect comments on requirements we want to keep. - // If a requirement is in last{Direct,Indirect}Block with the wrong - // indirect marking after this, or if the requirement is in an single - // uncommented mixed block (oneFlatUncommentedBlock), move it to the - // correct block. - // - // Some blocks may be empty after this. Cleanup will remove them. - need := make(map[string]*Require) - for _, r := range req { - need[r.Mod.Path] = r - } - have := make(map[string]*Require) - for _, r := range f.Require { - path := r.Mod.Path - if need[path] == nil || have[path] != nil { - // Requirement not needed, or duplicate requirement. Delete. - r.markRemoved() - continue - } - have[r.Mod.Path] = r - r.setVersion(need[path].Mod.Version) - r.setIndirect(need[path].Indirect) - if need[path].Indirect && - (oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastDirectBlock) { - moveReq(r, lastIndirectBlock) - } else if !need[path].Indirect && - (oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastIndirectBlock) { - moveReq(r, lastDirectBlock) - } - } - - // Add new requirements. - for path, r := range need { - if have[path] == nil { - if r.Indirect { - moveReq(r, lastIndirectBlock) - } else { - moveReq(r, lastDirectBlock) - } - f.Require = append(f.Require, r) - } - } - - f.SortBlocks() -} - -func (f *File) DropGodebug(key string) error { - for _, g := range f.Godebug { - if g.Key == key { - g.Syntax.markRemoved() - *g = Godebug{} - } - } - return nil -} - -func (f *File) DropRequire(path string) error { - for _, r := range f.Require { - if r.Mod.Path == path { - r.Syntax.markRemoved() - *r = Require{} - } - } - return nil -} - -// AddExclude adds a exclude statement to the mod file. Errors if the provided -// version is not a canonical version string -func (f *File) AddExclude(path, vers string) error { - if err := checkCanonicalVersion(path, vers); err != nil { - return err - } - - var hint *Line - for _, x := range f.Exclude { - if x.Mod.Path == path && x.Mod.Version == vers { - return nil - } - if x.Mod.Path == path { - hint = x.Syntax - } - } - - f.Exclude = append(f.Exclude, &Exclude{Mod: module.Version{Path: path, Version: vers}, Syntax: f.Syntax.addLine(hint, "exclude", AutoQuote(path), vers)}) - return nil -} - -func (f *File) DropExclude(path, vers string) error { - for _, x := range f.Exclude { - if x.Mod.Path == path && x.Mod.Version == vers { - x.Syntax.markRemoved() - *x = Exclude{} - } - } - return nil -} - -func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error { - return addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers) -} - -func addReplace(syntax *FileSyntax, replace *[]*Replace, oldPath, oldVers, newPath, newVers string) error { - need := true - old := module.Version{Path: oldPath, Version: oldVers} - new := module.Version{Path: newPath, Version: newVers} - tokens := []string{"replace", AutoQuote(oldPath)} - if oldVers != "" { - tokens = append(tokens, oldVers) - } - tokens = append(tokens, "=>", AutoQuote(newPath)) - if newVers != "" { - tokens = append(tokens, newVers) - } - - var hint *Line - for _, r := range *replace { - if r.Old.Path == oldPath && (oldVers == "" || r.Old.Version == oldVers) { - if need { - // Found replacement for old; update to use new. - r.New = new - syntax.updateLine(r.Syntax, tokens...) - need = false - continue - } - // Already added; delete other replacements for same. - r.Syntax.markRemoved() - *r = Replace{} - } - if r.Old.Path == oldPath { - hint = r.Syntax - } - } - if need { - *replace = append(*replace, &Replace{Old: old, New: new, Syntax: syntax.addLine(hint, tokens...)}) - } - return nil -} - -func (f *File) DropReplace(oldPath, oldVers string) error { - for _, r := range f.Replace { - if r.Old.Path == oldPath && r.Old.Version == oldVers { - r.Syntax.markRemoved() - *r = Replace{} - } - } - return nil -} - -// AddRetract adds a retract statement to the mod file. Errors if the provided -// version interval does not consist of canonical version strings -func (f *File) AddRetract(vi VersionInterval, rationale string) error { - var path string - if f.Module != nil { - path = f.Module.Mod.Path - } - if err := checkCanonicalVersion(path, vi.High); err != nil { - return err - } - if err := checkCanonicalVersion(path, vi.Low); err != nil { - return err - } - - r := &Retract{ - VersionInterval: vi, - } - if vi.Low == vi.High { - r.Syntax = f.Syntax.addLine(nil, "retract", AutoQuote(vi.Low)) - } else { - r.Syntax = f.Syntax.addLine(nil, "retract", "[", AutoQuote(vi.Low), ",", AutoQuote(vi.High), "]") - } - if rationale != "" { - for line := range strings.SplitSeq(rationale, "\n") { - com := Comment{Token: "// " + line} - r.Syntax.Comment().Before = append(r.Syntax.Comment().Before, com) - } - } - return nil -} - -func (f *File) DropRetract(vi VersionInterval) error { - for _, r := range f.Retract { - if r.VersionInterval == vi { - r.Syntax.markRemoved() - *r = Retract{} - } - } - return nil -} - -// AddTool adds a new tool directive with the given path. -// It does nothing if the tool line already exists. -func (f *File) AddTool(path string) error { - for _, t := range f.Tool { - if t.Path == path { - return nil - } - } - - f.Tool = append(f.Tool, &Tool{ - Path: path, - Syntax: f.Syntax.addLine(nil, "tool", path), - }) - - f.SortBlocks() - return nil -} - -// RemoveTool removes a tool directive with the given path. -// It does nothing if no such tool directive exists. -func (f *File) DropTool(path string) error { - for _, t := range f.Tool { - if t.Path == path { - t.Syntax.markRemoved() - *t = Tool{} - } - } - return nil -} - -// AddIgnore adds a new ignore directive with the given path. -// It does nothing if the ignore line already exists. -func (f *File) AddIgnore(path string) error { - for _, t := range f.Ignore { - if t.Path == path { - return nil - } - } - - f.Ignore = append(f.Ignore, &Ignore{ - Path: path, - Syntax: f.Syntax.addLine(nil, "ignore", path), - }) - - f.SortBlocks() - return nil -} - -// DropIgnore removes a ignore directive with the given path. -// It does nothing if no such ignore directive exists. -func (f *File) DropIgnore(path string) error { - for _, t := range f.Ignore { - if t.Path == path { - t.Syntax.markRemoved() - *t = Ignore{} - } - } - return nil -} - -func (f *File) SortBlocks() { - f.removeDups() // otherwise sorting is unsafe - - // semanticSortForExcludeVersionV is the Go version (plus leading "v") at which - // lines in exclude blocks start to use semantic sort instead of lexicographic sort. - // See go.dev/issue/60028. - const semanticSortForExcludeVersionV = "v1.21" - useSemanticSortForExclude := f.Go != nil && semver.Compare("v"+f.Go.Version, semanticSortForExcludeVersionV) >= 0 - - for _, stmt := range f.Syntax.Stmt { - block, ok := stmt.(*LineBlock) - if !ok { - continue - } - less := compareLine - if block.Token[0] == "exclude" && useSemanticSortForExclude { - less = compareLineExclude - } else if block.Token[0] == "retract" { - less = compareLineRetract - } - slices.SortStableFunc(block.Line, less) - } -} - -// removeDups removes duplicate exclude, replace and tool directives. -// -// Earlier exclude and tool directives take priority. -// -// Later replace directives take priority. -// -// require directives are not de-duplicated. That's left up to higher-level -// logic (MVS). -// -// retract directives are not de-duplicated since comments are -// meaningful, and versions may be retracted multiple times. -func (f *File) removeDups() { - removeDups(f.Syntax, &f.Exclude, &f.Replace, &f.Tool, &f.Ignore) -} - -func removeDups(syntax *FileSyntax, exclude *[]*Exclude, replace *[]*Replace, tool *[]*Tool, ignore *[]*Ignore) { - kill := make(map[*Line]bool) - - // Remove duplicate excludes. - if exclude != nil { - haveExclude := make(map[module.Version]bool) - for _, x := range *exclude { - if haveExclude[x.Mod] { - kill[x.Syntax] = true - continue - } - haveExclude[x.Mod] = true - } - var excl []*Exclude - for _, x := range *exclude { - if !kill[x.Syntax] { - excl = append(excl, x) - } - } - *exclude = excl - } - - // Remove duplicate replacements. - // Later replacements take priority over earlier ones. - haveReplace := make(map[module.Version]bool) - for i := len(*replace) - 1; i >= 0; i-- { - x := (*replace)[i] - if haveReplace[x.Old] { - kill[x.Syntax] = true - continue - } - haveReplace[x.Old] = true - } - var repl []*Replace - for _, x := range *replace { - if !kill[x.Syntax] { - repl = append(repl, x) - } - } - *replace = repl - - if tool != nil { - haveTool := make(map[string]bool) - for _, t := range *tool { - if haveTool[t.Path] { - kill[t.Syntax] = true - continue - } - haveTool[t.Path] = true - } - var newTool []*Tool - for _, t := range *tool { - if !kill[t.Syntax] { - newTool = append(newTool, t) - } - } - *tool = newTool - } - - if ignore != nil { - haveIgnore := make(map[string]bool) - for _, i := range *ignore { - if haveIgnore[i.Path] { - kill[i.Syntax] = true - continue - } - haveIgnore[i.Path] = true - } - var newIgnore []*Ignore - for _, i := range *ignore { - if !kill[i.Syntax] { - newIgnore = append(newIgnore, i) - } - } - *ignore = newIgnore - } - - // Duplicate require and retract directives are not removed. - - // Drop killed statements from the syntax tree. - var stmts []Expr - for _, stmt := range syntax.Stmt { - switch stmt := stmt.(type) { - case *Line: - if kill[stmt] { - continue - } - case *LineBlock: - var lines []*Line - for _, line := range stmt.Line { - if !kill[line] { - lines = append(lines, line) - } - } - stmt.Line = lines - if len(lines) == 0 { - continue - } - } - stmts = append(stmts, stmt) - } - syntax.Stmt = stmts -} - -// compareLine compares li and lj. It sorts lexicographically without assigning -// any special meaning to tokens. -func compareLine(li, lj *Line) int { - for k := 0; k < len(li.Token) && k < len(lj.Token); k++ { - if li.Token[k] != lj.Token[k] { - return cmp.Compare(li.Token[k], lj.Token[k]) - } - } - return cmp.Compare(len(li.Token), len(lj.Token)) -} - -// compareLineExclude compares li and lj for lines in an "exclude" block. -func compareLineExclude(li, lj *Line) int { - if len(li.Token) != 2 || len(lj.Token) != 2 { - // Not a known exclude specification. - // Fall back to sorting lexicographically. - return compareLine(li, lj) - } - // An exclude specification has two tokens: ModulePath and Version. - // Compare module path by string order and version by semver rules. - if pi, pj := li.Token[0], lj.Token[0]; pi != pj { - return cmp.Compare(pi, pj) - } - return semver.Compare(li.Token[1], lj.Token[1]) -} - -// compareLineRetract compares li and lj for lines in a "retract" block. -// It treats each line as a version interval. Single versions are compared as -// if they were intervals with the same low and high version. -// Intervals are sorted in descending order, first by low version, then by -// high version, using [semver.Compare]. -func compareLineRetract(li, lj *Line) int { - interval := func(l *Line) VersionInterval { - if len(l.Token) == 1 { - return VersionInterval{Low: l.Token[0], High: l.Token[0]} - } else if len(l.Token) == 5 && l.Token[0] == "[" && l.Token[2] == "," && l.Token[4] == "]" { - return VersionInterval{Low: l.Token[1], High: l.Token[3]} - } else { - // Line in unknown format. Treat as an invalid version. - return VersionInterval{} - } - } - vii := interval(li) - vij := interval(lj) - if cmp := semver.Compare(vii.Low, vij.Low); cmp != 0 { - return -cmp - } - return -semver.Compare(vii.High, vij.High) -} - -// checkCanonicalVersion returns a non-nil error if vers is not a canonical -// version string or does not match the major version of path. -// -// If path is non-empty, the error text suggests a format with a major version -// corresponding to the path. -func checkCanonicalVersion(path, vers string) error { - _, pathMajor, pathMajorOk := module.SplitPathVersion(path) - - if vers == "" || vers != module.CanonicalVersion(vers) { - if pathMajor == "" { - return &module.InvalidVersionError{ - Version: vers, - Err: fmt.Errorf("must be of the form v1.2.3"), - } - } - return &module.InvalidVersionError{ - Version: vers, - Err: fmt.Errorf("must be of the form %s.2.3", module.PathMajorPrefix(pathMajor)), - } - } - - if pathMajorOk { - if err := module.CheckPathMajor(vers, pathMajor); err != nil { - if pathMajor == "" { - // In this context, the user probably wrote "v2.3.4" when they meant - // "v2.3.4+incompatible". Suggest that instead of "v0 or v1". - return &module.InvalidVersionError{ - Version: vers, - Err: fmt.Errorf("should be %s+incompatible (or module %s/%v)", vers, path, semver.Major(vers)), - } - } - return err - } - } - - return nil -} diff --git a/vendor/golang.org/x/mod/modfile/work.go b/vendor/golang.org/x/mod/modfile/work.go deleted file mode 100644 index 09df5ea3..00000000 --- a/vendor/golang.org/x/mod/modfile/work.go +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package modfile - -import ( - "fmt" - "slices" - "strings" -) - -// A WorkFile is the parsed, interpreted form of a go.work file. -type WorkFile struct { - Go *Go - Toolchain *Toolchain - Godebug []*Godebug - Use []*Use - Replace []*Replace - - Syntax *FileSyntax -} - -// A Use is a single directory statement. -type Use struct { - Path string // Use path of module. - ModulePath string // Module path in the comment. - Syntax *Line -} - -// ParseWork parses and returns a go.work file. -// -// file is the name of the file, used in positions and errors. -// -// data is the content of the file. -// -// fix is an optional function that canonicalizes module versions. -// If fix is nil, all module versions must be canonical ([module.CanonicalVersion] -// must return the same string). -func ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) { - fs, err := parse(file, data) - if err != nil { - return nil, err - } - f := &WorkFile{ - Syntax: fs, - } - var errs ErrorList - - for _, x := range fs.Stmt { - switch x := x.(type) { - case *Line: - f.add(&errs, x, x.Token[0], x.Token[1:], fix) - - case *LineBlock: - if len(x.Token) > 1 { - errs = append(errs, Error{ - Filename: file, - Pos: x.Start, - Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), - }) - continue - } - switch x.Token[0] { - default: - errs = append(errs, Error{ - Filename: file, - Pos: x.Start, - Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), - }) - continue - case "godebug", "use", "replace": - for _, l := range x.Line { - f.add(&errs, l, x.Token[0], l.Token, fix) - } - } - } - } - - if len(errs) > 0 { - return nil, errs - } - return f, nil -} - -// Cleanup cleans up the file f after any edit operations. -// To avoid quadratic behavior, modifications like [WorkFile.DropRequire] -// clear the entry but do not remove it from the slice. -// Cleanup cleans out all the cleared entries. -func (f *WorkFile) Cleanup() { - w := 0 - for _, r := range f.Use { - if r.Path != "" { - f.Use[w] = r - w++ - } - } - f.Use = f.Use[:w] - - w = 0 - for _, r := range f.Replace { - if r.Old.Path != "" { - f.Replace[w] = r - w++ - } - } - f.Replace = f.Replace[:w] - - f.Syntax.Cleanup() -} - -func (f *WorkFile) AddGoStmt(version string) error { - if !GoVersionRE.MatchString(version) { - return fmt.Errorf("invalid language version %q", version) - } - if f.Go == nil { - stmt := &Line{Token: []string{"go", version}} - f.Go = &Go{ - Version: version, - Syntax: stmt, - } - // Find the first non-comment-only block and add - // the go statement before it. That will keep file comments at the top. - i := 0 - for i = 0; i < len(f.Syntax.Stmt); i++ { - if _, ok := f.Syntax.Stmt[i].(*CommentBlock); !ok { - break - } - } - f.Syntax.Stmt = append(append(f.Syntax.Stmt[:i:i], stmt), f.Syntax.Stmt[i:]...) - } else { - f.Go.Version = version - f.Syntax.updateLine(f.Go.Syntax, "go", version) - } - return nil -} - -func (f *WorkFile) AddToolchainStmt(name string) error { - if !ToolchainRE.MatchString(name) { - return fmt.Errorf("invalid toolchain name %q", name) - } - if f.Toolchain == nil { - stmt := &Line{Token: []string{"toolchain", name}} - f.Toolchain = &Toolchain{ - Name: name, - Syntax: stmt, - } - // Find the go line and add the toolchain line after it. - // Or else find the first non-comment-only block and add - // the toolchain line before it. That will keep file comments at the top. - i := 0 - for i = 0; i < len(f.Syntax.Stmt); i++ { - if line, ok := f.Syntax.Stmt[i].(*Line); ok && len(line.Token) > 0 && line.Token[0] == "go" { - i++ - goto Found - } - } - for i = 0; i < len(f.Syntax.Stmt); i++ { - if _, ok := f.Syntax.Stmt[i].(*CommentBlock); !ok { - break - } - } - Found: - f.Syntax.Stmt = append(append(f.Syntax.Stmt[:i:i], stmt), f.Syntax.Stmt[i:]...) - } else { - f.Toolchain.Name = name - f.Syntax.updateLine(f.Toolchain.Syntax, "toolchain", name) - } - return nil -} - -// DropGoStmt deletes the go statement from the file. -func (f *WorkFile) DropGoStmt() { - if f.Go != nil { - f.Go.Syntax.markRemoved() - f.Go = nil - } -} - -// DropToolchainStmt deletes the toolchain statement from the file. -func (f *WorkFile) DropToolchainStmt() { - if f.Toolchain != nil { - f.Toolchain.Syntax.markRemoved() - f.Toolchain = nil - } -} - -// AddGodebug sets the first godebug line for key to value, -// preserving any existing comments for that line and removing all -// other godebug lines for key. -// -// If no line currently exists for key, AddGodebug adds a new line -// at the end of the last godebug block. -func (f *WorkFile) AddGodebug(key, value string) error { - need := true - for _, g := range f.Godebug { - if g.Key == key { - if need { - g.Value = value - f.Syntax.updateLine(g.Syntax, "godebug", key+"="+value) - need = false - } else { - g.Syntax.markRemoved() - *g = Godebug{} - } - } - } - - if need { - f.addNewGodebug(key, value) - } - return nil -} - -// addNewGodebug adds a new godebug key=value line at the end -// of the last godebug block, regardless of any existing godebug lines for key. -func (f *WorkFile) addNewGodebug(key, value string) { - line := f.Syntax.addLine(nil, "godebug", key+"="+value) - g := &Godebug{ - Key: key, - Value: value, - Syntax: line, - } - f.Godebug = append(f.Godebug, g) -} - -func (f *WorkFile) DropGodebug(key string) error { - for _, g := range f.Godebug { - if g.Key == key { - g.Syntax.markRemoved() - *g = Godebug{} - } - } - return nil -} - -func (f *WorkFile) AddUse(diskPath, modulePath string) error { - need := true - for _, d := range f.Use { - if d.Path == diskPath { - if need { - d.ModulePath = modulePath - f.Syntax.updateLine(d.Syntax, "use", AutoQuote(diskPath)) - need = false - } else { - d.Syntax.markRemoved() - *d = Use{} - } - } - } - - if need { - f.AddNewUse(diskPath, modulePath) - } - return nil -} - -func (f *WorkFile) AddNewUse(diskPath, modulePath string) { - line := f.Syntax.addLine(nil, "use", AutoQuote(diskPath)) - f.Use = append(f.Use, &Use{Path: diskPath, ModulePath: modulePath, Syntax: line}) -} - -func (f *WorkFile) SetUse(dirs []*Use) { - need := make(map[string]string) - for _, d := range dirs { - need[d.Path] = d.ModulePath - } - - for _, d := range f.Use { - if modulePath, ok := need[d.Path]; ok { - d.ModulePath = modulePath - } else { - d.Syntax.markRemoved() - *d = Use{} - } - } - - // TODO(#45713): Add module path to comment. - - for diskPath, modulePath := range need { - f.AddNewUse(diskPath, modulePath) - } - f.SortBlocks() -} - -func (f *WorkFile) DropUse(path string) error { - for _, d := range f.Use { - if d.Path == path { - d.Syntax.markRemoved() - *d = Use{} - } - } - return nil -} - -func (f *WorkFile) AddReplace(oldPath, oldVers, newPath, newVers string) error { - return addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers) -} - -func (f *WorkFile) DropReplace(oldPath, oldVers string) error { - for _, r := range f.Replace { - if r.Old.Path == oldPath && r.Old.Version == oldVers { - r.Syntax.markRemoved() - *r = Replace{} - } - } - return nil -} - -func (f *WorkFile) SortBlocks() { - f.removeDups() // otherwise sorting is unsafe - - for _, stmt := range f.Syntax.Stmt { - block, ok := stmt.(*LineBlock) - if !ok { - continue - } - slices.SortStableFunc(block.Line, compareLine) - } -} - -// removeDups removes duplicate replace directives. -// -// Later replace directives take priority. -// -// require directives are not de-duplicated. That's left up to higher-level -// logic (MVS). -// -// retract directives are not de-duplicated since comments are -// meaningful, and versions may be retracted multiple times. -func (f *WorkFile) removeDups() { - removeDups(f.Syntax, nil, &f.Replace, nil, nil) -} diff --git a/vendor/golang.org/x/mod/module/module.go b/vendor/golang.org/x/mod/module/module.go deleted file mode 100644 index 739c13f4..00000000 --- a/vendor/golang.org/x/mod/module/module.go +++ /dev/null @@ -1,840 +0,0 @@ -// Copyright 2018 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 module defines the module.Version type along with support code. -// -// The [module.Version] type is a simple Path, Version pair: -// -// type Version struct { -// Path string -// Version string -// } -// -// There are no restrictions imposed directly by use of this structure, -// but additional checking functions, most notably [Check], verify that -// a particular path, version pair is valid. -// -// # Escaped Paths -// -// Module paths appear as substrings of file system paths -// (in the download cache) and of web server URLs in the proxy protocol. -// In general we cannot rely on file systems to be case-sensitive, -// nor can we rely on web servers, since they read from file systems. -// That is, we cannot rely on the file system to keep rsc.io/QUOTE -// and rsc.io/quote separate. Windows and macOS don't. -// Instead, we must never require two different casings of a file path. -// Because we want the download cache to match the proxy protocol, -// and because we want the proxy protocol to be possible to serve -// from a tree of static files (which might be stored on a case-insensitive -// file system), the proxy protocol must never require two different casings -// of a URL path either. -// -// One possibility would be to make the escaped form be the lowercase -// hexadecimal encoding of the actual path bytes. This would avoid ever -// needing different casings of a file path, but it would be fairly illegible -// to most programmers when those paths appeared in the file system -// (including in file paths in compiler errors and stack traces) -// in web server logs, and so on. Instead, we want a safe escaped form that -// leaves most paths unaltered. -// -// The safe escaped form is to replace every uppercase letter -// with an exclamation mark followed by the letter's lowercase equivalent. -// -// For example, -// -// github.com/Azure/azure-sdk-for-go -> github.com/!azure/azure-sdk-for-go. -// github.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy -// github.com/Sirupsen/logrus -> github.com/!sirupsen/logrus. -// -// Import paths that avoid upper-case letters are left unchanged. -// Note that because import paths are ASCII-only and avoid various -// problematic punctuation (like : < and >), the escaped form is also ASCII-only -// and avoids the same problematic punctuation. -// -// Import paths have never allowed exclamation marks, so there is no -// need to define how to escape a literal !. -// -// # Unicode Restrictions -// -// Today, paths are disallowed from using Unicode. -// -// Although paths are currently disallowed from using Unicode, -// we would like at some point to allow Unicode letters as well, to assume that -// file systems and URLs are Unicode-safe (storing UTF-8), and apply -// the !-for-uppercase convention for escaping them in the file system. -// But there are at least two subtle considerations. -// -// First, note that not all case-fold equivalent distinct runes -// form an upper/lower pair. -// For example, U+004B ('K'), U+006B ('k'), and U+212A ('K' for Kelvin) -// are three distinct runes that case-fold to each other. -// When we do add Unicode letters, we must not assume that upper/lower -// are the only case-equivalent pairs. -// Perhaps the Kelvin symbol would be disallowed entirely, for example. -// Or perhaps it would escape as "!!k", or perhaps as "(212A)". -// -// Second, it would be nice to allow Unicode marks as well as letters, -// but marks include combining marks, and then we must deal not -// only with case folding but also normalization: both U+00E9 ('é') -// and U+0065 U+0301 ('e' followed by combining acute accent) -// look the same on the page and are treated by some file systems -// as the same path. If we do allow Unicode marks in paths, there -// must be some kind of normalization to allow only one canonical -// encoding of any character used in an import path. -package module - -// IMPORTANT NOTE -// -// This file essentially defines the set of valid import paths for the go command. -// There are many subtle considerations, including Unicode ambiguity, -// security, network, and file system representations. -// -// This file also defines the set of valid module path and version combinations, -// another topic with many subtle considerations. -// -// Changes to the semantics in this file require approval from rsc. - -import ( - "cmp" - "errors" - "fmt" - "path" - "slices" - "strings" - "unicode" - "unicode/utf8" - - "golang.org/x/mod/semver" -) - -// A Version (for clients, a module.Version) is defined by a module path and version pair. -// These are stored in their plain (unescaped) form. -type Version struct { - // Path is a module path, like "golang.org/x/text" or "rsc.io/quote/v2". - Path string - - // Version is usually a semantic version in canonical form. - // There are three exceptions to this general rule. - // First, the top-level target of a build has no specific version - // and uses Version = "". - // Second, during MVS calculations the version "none" is used - // to represent the decision to take no version of a given module. - // Third, filesystem paths found in "replace" directives are - // represented by a path with an empty version. - Version string `json:",omitempty"` -} - -// String returns a representation of the Version suitable for logging -// (Path@Version, or just Path if Version is empty). -func (m Version) String() string { - if m.Version == "" { - return m.Path - } - return m.Path + "@" + m.Version -} - -// A ModuleError indicates an error specific to a module. -type ModuleError struct { - Path string - Version string - Err error -} - -// VersionError returns a [ModuleError] derived from a [Version] and error, -// or err itself if it is already such an error. -func VersionError(v Version, err error) error { - var mErr *ModuleError - if errors.As(err, &mErr) && mErr.Path == v.Path && mErr.Version == v.Version { - return err - } - return &ModuleError{ - Path: v.Path, - Version: v.Version, - Err: err, - } -} - -func (e *ModuleError) Error() string { - if v, ok := e.Err.(*InvalidVersionError); ok { - return fmt.Sprintf("%s@%s: invalid %s: %v", e.Path, v.Version, v.noun(), v.Err) - } - if e.Version != "" { - return fmt.Sprintf("%s@%s: %v", e.Path, e.Version, e.Err) - } - return fmt.Sprintf("module %s: %v", e.Path, e.Err) -} - -func (e *ModuleError) Unwrap() error { return e.Err } - -// An InvalidVersionError indicates an error specific to a version, with the -// module path unknown or specified externally. -// -// A [ModuleError] may wrap an InvalidVersionError, but an InvalidVersionError -// must not wrap a ModuleError. -type InvalidVersionError struct { - Version string - Pseudo bool - Err error -} - -// noun returns either "version" or "pseudo-version", depending on whether -// e.Version is a pseudo-version. -func (e *InvalidVersionError) noun() string { - if e.Pseudo { - return "pseudo-version" - } - return "version" -} - -func (e *InvalidVersionError) Error() string { - return fmt.Sprintf("%s %q invalid: %s", e.noun(), e.Version, e.Err) -} - -func (e *InvalidVersionError) Unwrap() error { return e.Err } - -// An InvalidPathError indicates a module, import, or file path doesn't -// satisfy all naming constraints. See [CheckPath], [CheckImportPath], -// and [CheckFilePath] for specific restrictions. -type InvalidPathError struct { - Kind string // "module", "import", or "file" - Path string - Err error -} - -func (e *InvalidPathError) Error() string { - return fmt.Sprintf("malformed %s path %q: %v", e.Kind, e.Path, e.Err) -} - -func (e *InvalidPathError) Unwrap() error { return e.Err } - -// Check checks that a given module path, version pair is valid. -// In addition to the path being a valid module path -// and the version being a valid semantic version, -// the two must correspond. -// For example, the path "yaml/v2" only corresponds to -// semantic versions beginning with "v2.". -func Check(path, version string) error { - if err := CheckPath(path); err != nil { - return err - } - if !semver.IsValid(version) { - return &ModuleError{ - Path: path, - Err: &InvalidVersionError{Version: version, Err: errors.New("not a semantic version")}, - } - } - _, pathMajor, _ := SplitPathVersion(path) - if err := CheckPathMajor(version, pathMajor); err != nil { - return &ModuleError{Path: path, Err: err} - } - return nil -} - -// firstPathOK reports whether r can appear in the first element of a module path. -// The first element of the path must be an LDH domain name, at least for now. -// To avoid case ambiguity, the domain name must be entirely lower case. -func firstPathOK(r rune) bool { - return r == '-' || r == '.' || - '0' <= r && r <= '9' || - 'a' <= r && r <= 'z' -} - -// modPathOK reports whether r can appear in a module path element. -// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~. -// -// This matches what "go get" has historically recognized in import paths, -// and avoids confusing sequences like '%20' or '+' that would change meaning -// if used in a URL. -// -// TODO(rsc): We would like to allow Unicode letters, but that requires additional -// care in the safe encoding (see "escaped paths" above). -func modPathOK(r rune) bool { - if r < utf8.RuneSelf { - return r == '-' || r == '.' || r == '_' || r == '~' || - '0' <= r && r <= '9' || - 'A' <= r && r <= 'Z' || - 'a' <= r && r <= 'z' - } - return false -} - -// importPathOK reports whether r can appear in a package import path element. -// -// Import paths are intermediate between module paths and file paths: we -// disallow characters that would be confusing or ambiguous as arguments to -// 'go get' (such as '@' and ' ' ), but allow certain characters that are -// otherwise-unambiguous on the command line and historically used for some -// binary names (such as '++' as a suffix for compiler binaries and wrappers). -func importPathOK(r rune) bool { - return modPathOK(r) || r == '+' -} - -// fileNameOK reports whether r can appear in a file name. -// For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters. -// If we expand the set of allowed characters here, we have to -// work harder at detecting potential case-folding and normalization collisions. -// See note about "escaped paths" above. -func fileNameOK(r rune) bool { - if r < utf8.RuneSelf { - // Entire set of ASCII punctuation, from which we remove characters: - // ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ - // We disallow some shell special characters: " ' * < > ? ` | - // (Note that some of those are disallowed by the Windows file system as well.) - // We also disallow path separators / : and \ (fileNameOK is only called on path element characters). - // We allow spaces (U+0020) in file names. - const allowed = "!#$%&()+,-.=@[]^_{}~ " - if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' { - return true - } - return strings.ContainsRune(allowed, r) - } - // It may be OK to add more ASCII punctuation here, but only carefully. - // For example Windows disallows < > \, and macOS disallows :, so we must not allow those. - return unicode.IsLetter(r) -} - -// CheckPath checks that a module path is valid. -// A valid module path is a valid import path, as checked by [CheckImportPath], -// with three additional constraints. -// First, the leading path element (up to the first slash, if any), -// by convention a domain name, must contain only lower-case ASCII letters, -// ASCII digits, dots (U+002E), and dashes (U+002D); -// it must contain at least one dot and cannot start with a dash. -// Second, for a final path element of the form /vN, where N looks numeric -// (ASCII digits and dots) must not begin with a leading zero, must not be /v1, -// and must not contain any dots. For paths beginning with "gopkg.in/", -// this second requirement is replaced by a requirement that the path -// follow the gopkg.in server's conventions. -// Third, no path element may begin with a dot. -func CheckPath(path string) (err error) { - defer func() { - if err != nil { - err = &InvalidPathError{Kind: "module", Path: path, Err: err} - } - }() - - if err := checkPath(path, modulePath); err != nil { - return err - } - i := strings.Index(path, "/") - if i < 0 { - i = len(path) - } - if i == 0 { - return fmt.Errorf("leading slash") - } - if !strings.Contains(path[:i], ".") { - return fmt.Errorf("missing dot in first path element") - } - if path[0] == '-' { - return fmt.Errorf("leading dash in first path element") - } - for _, r := range path[:i] { - if !firstPathOK(r) { - return fmt.Errorf("invalid char %q in first path element", r) - } - } - if _, _, ok := SplitPathVersion(path); !ok { - return fmt.Errorf("invalid version") - } - return nil -} - -// CheckImportPath checks that an import path is valid. -// -// A valid import path consists of one or more valid path elements -// separated by slashes (U+002F). (It must not begin with nor end in a slash.) -// -// A valid path element is a non-empty string made up of -// ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~. -// It must not end with a dot (U+002E), nor contain two dots in a row. -// -// The element prefix up to the first dot must not be a reserved file name -// on Windows, regardless of case (CON, com1, NuL, and so on). The element -// must not have a suffix of a tilde followed by one or more ASCII digits -// (to exclude paths elements that look like Windows short-names). -// -// CheckImportPath may be less restrictive in the future, but see the -// top-level package documentation for additional information about -// subtleties of Unicode. -func CheckImportPath(path string) error { - if err := checkPath(path, importPath); err != nil { - return &InvalidPathError{Kind: "import", Path: path, Err: err} - } - return nil -} - -// pathKind indicates what kind of path we're checking. Module paths, -// import paths, and file paths have different restrictions. -type pathKind int - -const ( - modulePath pathKind = iota - importPath - filePath -) - -// checkPath checks that a general path is valid. kind indicates what -// specific constraints should be applied. -// -// checkPath returns an error describing why the path is not valid. -// Because these checks apply to module, import, and file paths, -// and because other checks may be applied, the caller is expected to wrap -// this error with [InvalidPathError]. -func checkPath(path string, kind pathKind) error { - if !utf8.ValidString(path) { - return fmt.Errorf("invalid UTF-8") - } - if path == "" { - return fmt.Errorf("empty string") - } - if path[0] == '-' && kind != filePath { - return fmt.Errorf("leading dash") - } - if strings.Contains(path, "//") { - return fmt.Errorf("double slash") - } - if path[len(path)-1] == '/' { - return fmt.Errorf("trailing slash") - } - elemStart := 0 - for i, r := range path { - if r == '/' { - if err := checkElem(path[elemStart:i], kind); err != nil { - return err - } - elemStart = i + 1 - } - } - if err := checkElem(path[elemStart:], kind); err != nil { - return err - } - return nil -} - -// checkElem checks whether an individual path element is valid. -func checkElem(elem string, kind pathKind) error { - if elem == "" { - return fmt.Errorf("empty path element") - } - if strings.Count(elem, ".") == len(elem) { - return fmt.Errorf("invalid path element %q", elem) - } - if elem[0] == '.' && kind == modulePath { - return fmt.Errorf("leading dot in path element") - } - if elem[len(elem)-1] == '.' { - return fmt.Errorf("trailing dot in path element") - } - for _, r := range elem { - ok := false - switch kind { - case modulePath: - ok = modPathOK(r) - case importPath: - ok = importPathOK(r) - case filePath: - ok = fileNameOK(r) - default: - panic(fmt.Sprintf("internal error: invalid kind %v", kind)) - } - if !ok { - return fmt.Errorf("invalid char %q", r) - } - } - - // Windows disallows a bunch of path elements, sadly. - // See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file - short := elem - if i := strings.Index(short, "."); i >= 0 { - short = short[:i] - } - for _, bad := range badWindowsNames { - if strings.EqualFold(bad, short) { - return fmt.Errorf("%q disallowed as path element component on Windows", short) - } - } - - if kind == filePath { - // don't check for Windows short-names in file names. They're - // only an issue for import paths. - return nil - } - - // Reject path components that look like Windows short-names. - // Those usually end in a tilde followed by one or more ASCII digits. - if tilde := strings.LastIndexByte(short, '~'); tilde >= 0 && tilde < len(short)-1 { - suffix := short[tilde+1:] - suffixIsDigits := true - for _, r := range suffix { - if r < '0' || r > '9' { - suffixIsDigits = false - break - } - } - if suffixIsDigits { - return fmt.Errorf("trailing tilde and digits in path element") - } - } - - return nil -} - -// CheckFilePath checks that a slash-separated file path is valid. -// The definition of a valid file path is the same as the definition -// of a valid import path except that the set of allowed characters is larger: -// all Unicode letters, ASCII digits, the ASCII space character (U+0020), -// and the ASCII punctuation characters -// “!#$%&()+,-.=@[]^_{}~”. -// (The excluded punctuation characters, " * < > ? ` ' | / \ and :, -// have special meanings in certain shells or operating systems.) -// -// CheckFilePath may be less restrictive in the future, but see the -// top-level package documentation for additional information about -// subtleties of Unicode. -func CheckFilePath(path string) error { - if err := checkPath(path, filePath); err != nil { - return &InvalidPathError{Kind: "file", Path: path, Err: err} - } - return nil -} - -// badWindowsNames are the reserved file path elements on Windows. -// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file -var badWindowsNames = []string{ - "CON", - "PRN", - "AUX", - "NUL", - "COM1", - "COM2", - "COM3", - "COM4", - "COM5", - "COM6", - "COM7", - "COM8", - "COM9", - "LPT1", - "LPT2", - "LPT3", - "LPT4", - "LPT5", - "LPT6", - "LPT7", - "LPT8", - "LPT9", -} - -// SplitPathVersion returns prefix and major version such that prefix+pathMajor == path -// and version is either empty or "/vN" for N >= 2. -// As a special case, gopkg.in paths are recognized directly; -// they require ".vN" instead of "/vN", and for all N, not just N >= 2. -// SplitPathVersion returns with ok = false when presented with -// a path whose last path element does not satisfy the constraints -// applied by [CheckPath], such as "example.com/pkg/v1" or "example.com/pkg/v1.2". -func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) { - if strings.HasPrefix(path, "gopkg.in/") { - return splitGopkgIn(path) - } - - i := len(path) - dot := false - for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9' || path[i-1] == '.') { - if path[i-1] == '.' { - dot = true - } - i-- - } - if i <= 1 || i == len(path) || path[i-1] != 'v' || path[i-2] != '/' { - return path, "", true - } - prefix, pathMajor = path[:i-2], path[i-2:] - if dot || len(pathMajor) <= 2 || pathMajor[2] == '0' || pathMajor == "/v1" { - return path, "", false - } - return prefix, pathMajor, true -} - -// splitGopkgIn is like SplitPathVersion but only for gopkg.in paths. -func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) { - if !strings.HasPrefix(path, "gopkg.in/") { - return path, "", false - } - i := len(path) - if strings.HasSuffix(path, "-unstable") { - i -= len("-unstable") - } - for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9') { - i-- - } - if i <= 1 || path[i-1] != 'v' || path[i-2] != '.' { - // All gopkg.in paths must end in vN for some N. - return path, "", false - } - prefix, pathMajor = path[:i-2], path[i-2:] - if len(pathMajor) <= 2 || pathMajor[2] == '0' && pathMajor != ".v0" { - return path, "", false - } - return prefix, pathMajor, true -} - -// MatchPathMajor reports whether the semantic version v -// matches the path major version pathMajor. -// -// MatchPathMajor returns true if and only if [CheckPathMajor] returns nil. -func MatchPathMajor(v, pathMajor string) bool { - return CheckPathMajor(v, pathMajor) == nil -} - -// CheckPathMajor returns a non-nil error if the semantic version v -// does not match the path major version pathMajor. -func CheckPathMajor(v, pathMajor string) error { - // TODO(jayconrod): return errors or panic for invalid inputs. This function - // (and others) was covered by integration tests for cmd/go, and surrounding - // code protected against invalid inputs like non-canonical versions. - if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") { - pathMajor = strings.TrimSuffix(pathMajor, "-unstable") - } - if strings.HasPrefix(v, "v0.0.0-") && pathMajor == ".v1" { - // Allow old bug in pseudo-versions that generated v0.0.0- pseudoversion for gopkg .v1. - // For example, gopkg.in/yaml.v2@v2.2.1's go.mod requires gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405. - return nil - } - m := semver.Major(v) - if pathMajor == "" { - if m == "v0" || m == "v1" || semver.Build(v) == "+incompatible" { - return nil - } - pathMajor = "v0 or v1" - } else if pathMajor[0] == '/' || pathMajor[0] == '.' { - if m == pathMajor[1:] { - return nil - } - pathMajor = pathMajor[1:] - } - return &InvalidVersionError{ - Version: v, - Err: fmt.Errorf("should be %s, not %s", pathMajor, semver.Major(v)), - } -} - -// PathMajorPrefix returns the major-version tag prefix implied by pathMajor. -// An empty PathMajorPrefix allows either v0 or v1. -// -// Note that [MatchPathMajor] may accept some versions that do not actually begin -// with this prefix: namely, it accepts a 'v0.0.0-' prefix for a '.v1' -// pathMajor, even though that pathMajor implies 'v1' tagging. -func PathMajorPrefix(pathMajor string) string { - if pathMajor == "" { - return "" - } - if pathMajor[0] != '/' && pathMajor[0] != '.' { - panic("pathMajor suffix " + pathMajor + " passed to PathMajorPrefix lacks separator") - } - if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") { - pathMajor = strings.TrimSuffix(pathMajor, "-unstable") - } - m := pathMajor[1:] - if m != semver.Major(m) { - panic("pathMajor suffix " + pathMajor + "passed to PathMajorPrefix is not a valid major version") - } - return m -} - -// CanonicalVersion returns the canonical form of the version string v. -// It is the same as [semver.Canonical] except that it preserves the special build suffix "+incompatible". -func CanonicalVersion(v string) string { - cv := semver.Canonical(v) - if semver.Build(v) == "+incompatible" { - cv += "+incompatible" - } - return cv -} - -// Sort sorts the list by Path, breaking ties by comparing [Version] fields. -// The Version fields are interpreted as semantic versions (using [semver.Compare]) -// optionally followed by a tie-breaking suffix introduced by a slash character, -// like in "v0.0.1/go.mod". -func Sort(list []Version) { - slices.SortFunc(list, func(i, j Version) int { - if i.Path != j.Path { - return strings.Compare(i.Path, j.Path) - } - // To help go.sum formatting, allow version/file. - // Compare semver prefix by semver rules, - // file by string order. - vi := i.Version - vj := j.Version - var fi, fj string - if k := strings.Index(vi, "/"); k >= 0 { - vi, fi = vi[:k], vi[k:] - } - if k := strings.Index(vj, "/"); k >= 0 { - vj, fj = vj[:k], vj[k:] - } - if vi != vj { - return semver.Compare(vi, vj) - } - return cmp.Compare(fi, fj) - }) -} - -// EscapePath returns the escaped form of the given module path. -// It fails if the module path is invalid. -func EscapePath(path string) (escaped string, err error) { - if err := CheckPath(path); err != nil { - return "", err - } - - return escapeString(path) -} - -// EscapeVersion returns the escaped form of the given module version. -// Versions are allowed to be in non-semver form but must be valid file names -// and not contain exclamation marks. -func EscapeVersion(v string) (escaped string, err error) { - if err := checkElem(v, filePath); err != nil || strings.Contains(v, "!") { - return "", &InvalidVersionError{ - Version: v, - Err: fmt.Errorf("disallowed version string"), - } - } - return escapeString(v) -} - -func escapeString(s string) (escaped string, err error) { - haveUpper := false - for _, r := range s { - if r == '!' || r >= utf8.RuneSelf { - // This should be disallowed by CheckPath, but diagnose anyway. - // The correctness of the escaping loop below depends on it. - return "", fmt.Errorf("internal error: inconsistency in EscapePath") - } - if 'A' <= r && r <= 'Z' { - haveUpper = true - } - } - - if !haveUpper { - return s, nil - } - - var buf []byte - for _, r := range s { - if 'A' <= r && r <= 'Z' { - buf = append(buf, '!', byte(r+'a'-'A')) - } else { - buf = append(buf, byte(r)) - } - } - return string(buf), nil -} - -// UnescapePath returns the module path for the given escaped path. -// It fails if the escaped path is invalid or describes an invalid path. -func UnescapePath(escaped string) (path string, err error) { - path, ok := unescapeString(escaped) - if !ok { - return "", fmt.Errorf("invalid escaped module path %q", escaped) - } - if err := CheckPath(path); err != nil { - return "", fmt.Errorf("invalid escaped module path %q: %v", escaped, err) - } - return path, nil -} - -// UnescapeVersion returns the version string for the given escaped version. -// It fails if the escaped form is invalid or describes an invalid version. -// Versions are allowed to be in non-semver form but must be valid file names -// and not contain exclamation marks. -func UnescapeVersion(escaped string) (v string, err error) { - v, ok := unescapeString(escaped) - if !ok { - return "", fmt.Errorf("invalid escaped version %q", escaped) - } - if err := checkElem(v, filePath); err != nil { - return "", fmt.Errorf("invalid escaped version %q: %v", v, err) - } - return v, nil -} - -func unescapeString(escaped string) (string, bool) { - var buf []byte - - bang := false - for _, r := range escaped { - if r >= utf8.RuneSelf { - return "", false - } - if bang { - bang = false - if r < 'a' || 'z' < r { - return "", false - } - buf = append(buf, byte(r+'A'-'a')) - continue - } - if r == '!' { - bang = true - continue - } - if 'A' <= r && r <= 'Z' { - return "", false - } - buf = append(buf, byte(r)) - } - if bang { - return "", false - } - return string(buf), true -} - -// MatchPrefixPatterns reports whether any path prefix of target matches one of -// the glob patterns (as defined by [path.Match]) in the comma-separated globs -// list. This implements the algorithm used when matching a module path to the -// GOPRIVATE environment variable, as described by 'go help module-private'. -// -// It ignores any empty or malformed patterns in the list. -// Trailing slashes on patterns are ignored. -func MatchPrefixPatterns(globs, target string) bool { - for globs != "" { - // Extract next non-empty glob in comma-separated list. - var glob string - if before, after, ok := strings.Cut(globs, ","); ok { - glob, globs = before, after - } else { - glob, globs = globs, "" - } - glob = strings.TrimSuffix(glob, "/") - if glob == "" { - continue - } - - // A glob with N+1 path elements (N slashes) needs to be matched - // against the first N+1 path elements of target, - // which end just before the N+1'th slash. - n := strings.Count(glob, "/") - prefix := target - // Walk target, counting slashes, truncating at the N+1'th slash. - for i := 0; i < len(target); i++ { - if target[i] == '/' { - if n == 0 { - prefix = target[:i] - break - } - n-- - } - } - if n > 0 { - // Not enough prefix elements. - continue - } - matched, _ := path.Match(glob, prefix) - if matched { - return true - } - } - return false -} diff --git a/vendor/golang.org/x/mod/module/pseudo.go b/vendor/golang.org/x/mod/module/pseudo.go deleted file mode 100644 index 9cf19d32..00000000 --- a/vendor/golang.org/x/mod/module/pseudo.go +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright 2018 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. - -// Pseudo-versions -// -// Code authors are expected to tag the revisions they want users to use, -// including prereleases. However, not all authors tag versions at all, -// and not all commits a user might want to try will have tags. -// A pseudo-version is a version with a special form that allows us to -// address an untagged commit and order that version with respect to -// other versions we might encounter. -// -// A pseudo-version takes one of the general forms: -// -// (1) vX.0.0-yyyymmddhhmmss-abcdef123456 -// (2) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456 -// (3) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible -// (4) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456 -// (5) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible -// -// If there is no recently tagged version with the right major version vX, -// then form (1) is used, creating a space of pseudo-versions at the bottom -// of the vX version range, less than any tagged version, including the unlikely v0.0.0. -// -// If the most recent tagged version before the target commit is vX.Y.Z or vX.Y.Z+incompatible, -// then the pseudo-version uses form (2) or (3), making it a prerelease for the next -// possible semantic version after vX.Y.Z. The leading 0 segment in the prerelease string -// ensures that the pseudo-version compares less than possible future explicit prereleases -// like vX.Y.(Z+1)-rc1 or vX.Y.(Z+1)-1. -// -// If the most recent tagged version before the target commit is vX.Y.Z-pre or vX.Y.Z-pre+incompatible, -// then the pseudo-version uses form (4) or (5), making it a slightly later prerelease. - -package module - -import ( - "errors" - "fmt" - "strings" - "time" - - "golang.org/x/mod/internal/lazyregexp" - "golang.org/x/mod/semver" -) - -var pseudoVersionRE = lazyregexp.New(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`) - -const PseudoVersionTimestampFormat = "20060102150405" - -// PseudoVersion returns a pseudo-version for the given major version ("v1") -// preexisting older tagged version ("" or "v1.2.3" or "v1.2.3-pre"), revision time, -// and revision identifier (usually a 12-byte commit hash prefix). -func PseudoVersion(major, older string, t time.Time, rev string) string { - if major == "" { - major = "v0" - } - segment := fmt.Sprintf("%s-%s", t.UTC().Format(PseudoVersionTimestampFormat), rev) - build := semver.Build(older) - older = semver.Canonical(older) - if older == "" { - return major + ".0.0-" + segment // form (1) - } - if semver.Prerelease(older) != "" { - return older + ".0." + segment + build // form (4), (5) - } - - // Form (2), (3). - // Extract patch from vMAJOR.MINOR.PATCH - i := strings.LastIndex(older, ".") + 1 - v, patch := older[:i], older[i:] - - // Reassemble. - return v + incDecimal(patch) + "-0." + segment + build -} - -// ZeroPseudoVersion returns a pseudo-version with a zero timestamp and -// revision, which may be used as a placeholder. -func ZeroPseudoVersion(major string) string { - return PseudoVersion(major, "", time.Time{}, "000000000000") -} - -// incDecimal returns the decimal string incremented by 1. -func incDecimal(decimal string) string { - // Scan right to left turning 9s to 0s until you find a digit to increment. - digits := []byte(decimal) - i := len(digits) - 1 - for ; i >= 0 && digits[i] == '9'; i-- { - digits[i] = '0' - } - if i >= 0 { - digits[i]++ - } else { - // digits is all zeros - digits[0] = '1' - digits = append(digits, '0') - } - return string(digits) -} - -// decDecimal returns the decimal string decremented by 1, or the empty string -// if the decimal is all zeroes. -func decDecimal(decimal string) string { - // Scan right to left turning 0s to 9s until you find a digit to decrement. - digits := []byte(decimal) - i := len(digits) - 1 - for ; i >= 0 && digits[i] == '0'; i-- { - digits[i] = '9' - } - if i < 0 { - // decimal is all zeros - return "" - } - if i == 0 && digits[i] == '1' && len(digits) > 1 { - digits = digits[1:] - } else { - digits[i]-- - } - return string(digits) -} - -// IsPseudoVersion reports whether v is a pseudo-version. -func IsPseudoVersion(v string) bool { - return strings.Count(v, "-") >= 2 && semver.IsValid(v) && pseudoVersionRE.MatchString(v) -} - -// IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base, -// timestamp, and revision, as returned by [ZeroPseudoVersion]. -func IsZeroPseudoVersion(v string) bool { - return v == ZeroPseudoVersion(semver.Major(v)) -} - -// PseudoVersionTime returns the time stamp of the pseudo-version v. -// It returns an error if v is not a pseudo-version or if the time stamp -// embedded in the pseudo-version is not a valid time. -func PseudoVersionTime(v string) (time.Time, error) { - _, timestamp, _, _, err := parsePseudoVersion(v) - if err != nil { - return time.Time{}, err - } - t, err := time.Parse("20060102150405", timestamp) - if err != nil { - return time.Time{}, &InvalidVersionError{ - Version: v, - Pseudo: true, - Err: fmt.Errorf("malformed time %q", timestamp), - } - } - return t, nil -} - -// PseudoVersionRev returns the revision identifier of the pseudo-version v. -// It returns an error if v is not a pseudo-version. -func PseudoVersionRev(v string) (rev string, err error) { - _, _, rev, _, err = parsePseudoVersion(v) - return -} - -// PseudoVersionBase returns the canonical parent version, if any, upon which -// the pseudo-version v is based. -// -// If v has no parent version (that is, if it is "vX.0.0-[…]"), -// PseudoVersionBase returns the empty string and a nil error. -func PseudoVersionBase(v string) (string, error) { - base, _, _, build, err := parsePseudoVersion(v) - if err != nil { - return "", err - } - - switch pre := semver.Prerelease(base); pre { - case "": - // vX.0.0-yyyymmddhhmmss-abcdef123456 → "" - if build != "" { - // Pseudo-versions of the form vX.0.0-yyyymmddhhmmss-abcdef123456+incompatible - // are nonsensical: the "vX.0.0-" prefix implies that there is no parent tag, - // but the "+incompatible" suffix implies that the major version of - // the parent tag is not compatible with the module's import path. - // - // There are a few such entries in the index generated by proxy.golang.org, - // but we believe those entries were generated by the proxy itself. - return "", &InvalidVersionError{ - Version: v, - Pseudo: true, - Err: fmt.Errorf("lacks base version, but has build metadata %q", build), - } - } - return "", nil - - case "-0": - // vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z - // vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z+incompatible - base = strings.TrimSuffix(base, pre) - i := strings.LastIndexByte(base, '.') - if i < 0 { - panic("base from parsePseudoVersion missing patch number: " + base) - } - patch := decDecimal(base[i+1:]) - if patch == "" { - // vX.0.0-0 is invalid, but has been observed in the wild in the index - // generated by requests to proxy.golang.org. - // - // NOTE(bcmills): I cannot find a historical bug that accounts for - // pseudo-versions of this form, nor have I seen such versions in any - // actual go.mod files. If we find actual examples of this form and a - // reasonable theory of how they came into existence, it seems fine to - // treat them as equivalent to vX.0.0 (especially since the invalid - // pseudo-versions have lower precedence than the real ones). For now, we - // reject them. - return "", &InvalidVersionError{ - Version: v, - Pseudo: true, - Err: fmt.Errorf("version before %s would have negative patch number", base), - } - } - return base[:i+1] + patch + build, nil - - default: - // vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z-pre - // vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z-pre+incompatible - if !strings.HasSuffix(base, ".0") { - panic(`base from parsePseudoVersion missing ".0" before date: ` + base) - } - return strings.TrimSuffix(base, ".0") + build, nil - } -} - -var errPseudoSyntax = errors.New("syntax error") - -func parsePseudoVersion(v string) (base, timestamp, rev, build string, err error) { - if !IsPseudoVersion(v) { - return "", "", "", "", &InvalidVersionError{ - Version: v, - Pseudo: true, - Err: errPseudoSyntax, - } - } - build = semver.Build(v) - v = strings.TrimSuffix(v, build) - j := strings.LastIndex(v, "-") - v, rev = v[:j], v[j+1:] - i := strings.LastIndex(v, "-") - if j := strings.LastIndex(v, "."); j > i { - base = v[:j] // "vX.Y.Z-pre.0" or "vX.Y.(Z+1)-0" - timestamp = v[j+1:] - } else { - base = v[:i] // "vX.0.0" - timestamp = v[i+1:] - } - return base, timestamp, rev, build, nil -} diff --git a/vendor/golang.org/x/mod/semver/semver.go b/vendor/golang.org/x/mod/semver/semver.go deleted file mode 100644 index 824b282c..00000000 --- a/vendor/golang.org/x/mod/semver/semver.go +++ /dev/null @@ -1,407 +0,0 @@ -// Copyright 2018 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 semver implements comparison of semantic version strings. -// In this package, semantic version strings must begin with a leading "v", -// as in "v1.0.0". -// -// The general form of a semantic version string accepted by this package is -// -// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]] -// -// where square brackets indicate optional parts of the syntax; -// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros; -// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers -// using only alphanumeric characters and hyphens; and -// all-numeric PRERELEASE identifiers must not have leading zeros. -// -// This package follows Semantic Versioning 2.0.0 (see semver.org) -// with two exceptions. First, it requires the "v" prefix. Second, it recognizes -// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes) -// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0. -package semver - -import ( - "slices" - "strings" -) - -// parsed returns the parsed form of a semantic version string. -type parsed struct { - major string - minor string - patch string - short string - prerelease string - build string -} - -// IsValid reports whether v is a valid semantic version string. -func IsValid(v string) bool { - _, ok := parse(v) - return ok -} - -// Canonical returns the canonical formatting of the semantic version v. -// It fills in any missing .MINOR or .PATCH and discards build metadata. -// Two semantic versions compare equal only if their canonical formatting -// is an identical string. -// The canonical invalid semantic version is the empty string. -func Canonical(v string) string { - p, ok := parse(v) - if !ok { - return "" - } - if p.build != "" { - return v[:len(v)-len(p.build)] - } - if p.short != "" { - return v + p.short - } - return v -} - -// Major returns the major version prefix of the semantic version v. -// For example, Major("v2.1.0") == "v2". -// If v is an invalid semantic version string, Major returns the empty string. -func Major(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return v[:1+len(pv.major)] -} - -// MajorMinor returns the major.minor version prefix of the semantic version v. -// For example, MajorMinor("v2.1.0") == "v2.1". -// If v is an invalid semantic version string, MajorMinor returns the empty string. -func MajorMinor(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - i := 1 + len(pv.major) - if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor { - return v[:j] - } - return v[:i] + "." + pv.minor -} - -// Prerelease returns the prerelease suffix of the semantic version v. -// For example, Prerelease("v2.1.0-pre+meta") == "-pre". -// If v is an invalid semantic version string, Prerelease returns the empty string. -func Prerelease(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return pv.prerelease -} - -// Build returns the build suffix of the semantic version v. -// For example, Build("v2.1.0+meta") == "+meta". -// If v is an invalid semantic version string, Build returns the empty string. -func Build(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return pv.build -} - -// Compare returns an integer comparing two versions according to -// semantic version precedence. -// The result will be 0 if v == w, -1 if v < w, or +1 if v > w. -// -// An invalid semantic version string is considered less than a valid one. -// All invalid semantic version strings compare equal to each other. -func Compare(v, w string) int { - pv, ok1 := parse(v) - pw, ok2 := parse(w) - if !ok1 && !ok2 { - return 0 - } - if !ok1 { - return -1 - } - if !ok2 { - return +1 - } - if c := compareInt(pv.major, pw.major); c != 0 { - return c - } - if c := compareInt(pv.minor, pw.minor); c != 0 { - return c - } - if c := compareInt(pv.patch, pw.patch); c != 0 { - return c - } - return comparePrerelease(pv.prerelease, pw.prerelease) -} - -// Max canonicalizes its arguments and then returns the version string -// that compares greater. -// -// Deprecated: use [Compare] instead. In most cases, returning a canonicalized -// version is not expected or desired. -func Max(v, w string) string { - v = Canonical(v) - w = Canonical(w) - if Compare(v, w) > 0 { - return v - } - return w -} - -// ByVersion implements [sort.Interface] for sorting semantic version strings. -type ByVersion []string - -func (vs ByVersion) Len() int { return len(vs) } -func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] } -func (vs ByVersion) Less(i, j int) bool { return compareVersion(vs[i], vs[j]) < 0 } - -// Sort sorts a list of semantic version strings using [Compare] and falls back -// to use [strings.Compare] if both versions are considered equal. -func Sort(list []string) { - slices.SortFunc(list, compareVersion) -} - -func compareVersion(a, b string) int { - cmp := Compare(a, b) - if cmp != 0 { - return cmp - } - return strings.Compare(a, b) -} - -func parse(v string) (p parsed, ok bool) { - if v == "" || v[0] != 'v' { - return - } - p.major, v, ok = parseInt(v[1:]) - if !ok { - return - } - if v == "" { - p.minor = "0" - p.patch = "0" - p.short = ".0.0" - return - } - if v[0] != '.' { - ok = false - return - } - p.minor, v, ok = parseInt(v[1:]) - if !ok { - return - } - if v == "" { - p.patch = "0" - p.short = ".0" - return - } - if v[0] != '.' { - ok = false - return - } - p.patch, v, ok = parseInt(v[1:]) - if !ok { - return - } - if len(v) > 0 && v[0] == '-' { - p.prerelease, v, ok = parsePrerelease(v) - if !ok { - return - } - } - if len(v) > 0 && v[0] == '+' { - p.build, v, ok = parseBuild(v) - if !ok { - return - } - } - if v != "" { - ok = false - return - } - ok = true - return -} - -func parseInt(v string) (t, rest string, ok bool) { - if v == "" { - return - } - if v[0] < '0' || '9' < v[0] { - return - } - i := 1 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - if v[0] == '0' && i != 1 { - return - } - return v[:i], v[i:], true -} - -func parsePrerelease(v string) (t, rest string, ok bool) { - // "A pre-release version MAY be denoted by appending a hyphen and - // a series of dot separated identifiers immediately following the patch version. - // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. - // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes." - if v == "" || v[0] != '-' { - return - } - i := 1 - start := 1 - for i < len(v) && v[i] != '+' { - if !isIdentChar(v[i]) && v[i] != '.' { - return - } - if v[i] == '.' { - if start == i || isBadNum(v[start:i]) { - return - } - start = i + 1 - } - i++ - } - if start == i || isBadNum(v[start:i]) { - return - } - return v[:i], v[i:], true -} - -func parseBuild(v string) (t, rest string, ok bool) { - if v == "" || v[0] != '+' { - return - } - i := 1 - start := 1 - for i < len(v) { - if !isIdentChar(v[i]) && v[i] != '.' { - return - } - if v[i] == '.' { - if start == i { - return - } - start = i + 1 - } - i++ - } - if start == i { - return - } - return v[:i], v[i:], true -} - -func isIdentChar(c byte) bool { - return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' -} - -func isBadNum(v string) bool { - i := 0 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - return i == len(v) && i > 1 && v[0] == '0' -} - -func isNum(v string) bool { - i := 0 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - return i == len(v) -} - -func compareInt(x, y string) int { - if x == y { - return 0 - } - if len(x) < len(y) { - return -1 - } - if len(x) > len(y) { - return +1 - } - if x < y { - return -1 - } else { - return +1 - } -} - -func comparePrerelease(x, y string) int { - // "When major, minor, and patch are equal, a pre-release version has - // lower precedence than a normal version. - // Example: 1.0.0-alpha < 1.0.0. - // Precedence for two pre-release versions with the same major, minor, - // and patch version MUST be determined by comparing each dot separated - // identifier from left to right until a difference is found as follows: - // identifiers consisting of only digits are compared numerically and - // identifiers with letters or hyphens are compared lexically in ASCII - // sort order. Numeric identifiers always have lower precedence than - // non-numeric identifiers. A larger set of pre-release fields has a - // higher precedence than a smaller set, if all of the preceding - // identifiers are equal. - // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < - // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0." - if x == y { - return 0 - } - if x == "" { - return +1 - } - if y == "" { - return -1 - } - for x != "" && y != "" { - x = x[1:] // skip - or . - y = y[1:] // skip - or . - var dx, dy string - dx, x = nextIdent(x) - dy, y = nextIdent(y) - if dx != dy { - ix := isNum(dx) - iy := isNum(dy) - if ix != iy { - if ix { - return -1 - } else { - return +1 - } - } - if ix { - if len(dx) < len(dy) { - return -1 - } - if len(dx) > len(dy) { - return +1 - } - } - if dx < dy { - return -1 - } else { - return +1 - } - } - } - if x == "" { - return -1 - } else { - return +1 - } -} - -func nextIdent(x string) (dx, rest string) { - i := 0 - for i < len(x) && x[i] != '.' { - i++ - } - return x[:i], x[i:] -} diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE deleted file mode 100644 index 2a7cf70d..00000000 --- a/vendor/golang.org/x/tools/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright 2009 The Go Authors. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS deleted file mode 100644 index 73309904..00000000 --- a/vendor/golang.org/x/tools/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google 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, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/tools/cover/profile.go b/vendor/golang.org/x/tools/cover/profile.go deleted file mode 100644 index 47a9a541..00000000 --- a/vendor/golang.org/x/tools/cover/profile.go +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cover provides support for parsing coverage profiles -// generated by "go test -coverprofile=cover.out". -package cover // import "golang.org/x/tools/cover" - -import ( - "bufio" - "errors" - "fmt" - "io" - "math" - "os" - "sort" - "strconv" - "strings" -) - -// Profile represents the profiling data for a specific file. -type Profile struct { - FileName string - Mode string - Blocks []ProfileBlock -} - -// ProfileBlock represents a single block of profiling data. -type ProfileBlock struct { - StartLine, StartCol int - EndLine, EndCol int - NumStmt, Count int -} - -type byFileName []*Profile - -func (p byFileName) Len() int { return len(p) } -func (p byFileName) Less(i, j int) bool { return p[i].FileName < p[j].FileName } -func (p byFileName) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -// ParseProfiles parses profile data in the specified file and returns a -// Profile for each source file described therein. -func ParseProfiles(fileName string) ([]*Profile, error) { - pf, err := os.Open(fileName) - if err != nil { - return nil, err - } - defer pf.Close() - return ParseProfilesFromReader(pf) -} - -// ParseProfilesFromReader parses profile data from the Reader and -// returns a Profile for each source file described therein. -func ParseProfilesFromReader(rd io.Reader) ([]*Profile, error) { - // First line is "mode: foo", where foo is "set", "count", or "atomic". - // Rest of file is in the format - // encoding/base64/base64.go:34.44,37.40 3 1 - // where the fields are: name.go:line.column,line.column numberOfStatements count - files := make(map[string]*Profile) - s := bufio.NewScanner(rd) - mode := "" - for s.Scan() { - line := s.Text() - if mode == "" { - const p = "mode: " - if !strings.HasPrefix(line, p) || line == p { - return nil, fmt.Errorf("bad mode line: %v", line) - } - mode = line[len(p):] - continue - } - fn, b, err := parseLine(line) - if err != nil { - return nil, fmt.Errorf("line %q doesn't match expected format: %v", line, err) - } - p := files[fn] - if p == nil { - p = &Profile{ - FileName: fn, - Mode: mode, - } - files[fn] = p - } - p.Blocks = append(p.Blocks, b) - } - if err := s.Err(); err != nil { - return nil, err - } - for _, p := range files { - sort.Sort(blocksByStart(p.Blocks)) - // Merge samples from the same location. - j := 1 - for i := 1; i < len(p.Blocks); i++ { - b := p.Blocks[i] - last := p.Blocks[j-1] - if b.StartLine == last.StartLine && - b.StartCol == last.StartCol && - b.EndLine == last.EndLine && - b.EndCol == last.EndCol { - if b.NumStmt != last.NumStmt { - return nil, fmt.Errorf("inconsistent NumStmt: changed from %d to %d", last.NumStmt, b.NumStmt) - } - if mode == "set" { - p.Blocks[j-1].Count |= b.Count - } else { - p.Blocks[j-1].Count += b.Count - } - continue - } - p.Blocks[j] = b - j++ - } - p.Blocks = p.Blocks[:j] - } - // Generate a sorted slice. - profiles := make([]*Profile, 0, len(files)) - for _, profile := range files { - profiles = append(profiles, profile) - } - sort.Sort(byFileName(profiles)) - return profiles, nil -} - -// parseLine parses a line from a coverage file. -// It is equivalent to the regex -// ^(.+):([0-9]+)\.([0-9]+),([0-9]+)\.([0-9]+) ([0-9]+) ([0-9]+)$ -// -// However, it is much faster: https://golang.org/cl/179377 -func parseLine(l string) (fileName string, block ProfileBlock, err error) { - end := len(l) - - b := ProfileBlock{} - b.Count, end, err = seekBack(l, ' ', end, "Count") - if err != nil { - return "", b, err - } - b.NumStmt, end, err = seekBack(l, ' ', end, "NumStmt") - if err != nil { - return "", b, err - } - b.EndCol, end, err = seekBack(l, '.', end, "EndCol") - if err != nil { - return "", b, err - } - b.EndLine, end, err = seekBack(l, ',', end, "EndLine") - if err != nil { - return "", b, err - } - b.StartCol, end, err = seekBack(l, '.', end, "StartCol") - if err != nil { - return "", b, err - } - b.StartLine, end, err = seekBack(l, ':', end, "StartLine") - if err != nil { - return "", b, err - } - fn := l[0:end] - if fn == "" { - return "", b, errors.New("a FileName cannot be blank") - } - return fn, b, nil -} - -// seekBack searches backwards from end to find sep in l, then returns the -// value between sep and end as an integer. -// If seekBack fails, the returned error will reference what. -func seekBack(l string, sep byte, end int, what string) (value int, nextSep int, err error) { - // Since we're seeking backwards and we know only ASCII is legal for these values, - // we can ignore the possibility of non-ASCII characters. - for start := end - 1; start >= 0; start-- { - if l[start] == sep { - i, err := strconv.Atoi(l[start+1 : end]) - if err != nil { - return 0, 0, fmt.Errorf("couldn't parse %q: %v", what, err) - } - if i < 0 { - return 0, 0, fmt.Errorf("negative values are not allowed for %s, found %d", what, i) - } - return i, start, nil - } - } - return 0, 0, fmt.Errorf("couldn't find a %s before %s", string(sep), what) -} - -type blocksByStart []ProfileBlock - -func (b blocksByStart) Len() int { return len(b) } -func (b blocksByStart) Swap(i, j int) { b[i], b[j] = b[j], b[i] } -func (b blocksByStart) Less(i, j int) bool { - bi, bj := b[i], b[j] - return bi.StartLine < bj.StartLine || bi.StartLine == bj.StartLine && bi.StartCol < bj.StartCol -} - -// Boundary represents the position in a source file of the beginning or end of a -// block as reported by the coverage profile. In HTML mode, it will correspond to -// the opening or closing of a tag and will be used to colorize the source -type Boundary struct { - Offset int // Location as a byte offset in the source file. - Start bool // Is this the start of a block? - Count int // Event count from the cover profile. - Norm float64 // Count normalized to [0..1]. - Index int // Order in input file. -} - -// Boundaries returns a Profile as a set of Boundary objects within the provided src. -func (p *Profile) Boundaries(src []byte) (boundaries []Boundary) { - // Find maximum count. - max := 0 - for _, b := range p.Blocks { - if b.Count > max { - max = b.Count - } - } - // Divisor for normalization. - divisor := math.Log(float64(max)) - - // boundary returns a Boundary, populating the Norm field with a normalized Count. - index := 0 - boundary := func(offset int, start bool, count int) Boundary { - b := Boundary{Offset: offset, Start: start, Count: count, Index: index} - index++ - if !start || count == 0 { - return b - } - if max <= 1 { - b.Norm = 0.8 // Profile is in"set" mode; we want a heat map. Use cov8 in the CSS. - } else if count > 0 { - b.Norm = math.Log(float64(count)) / divisor - } - return b - } - - line, col := 1, 2 // TODO: Why is this 2? - for si, bi := 0, 0; si < len(src) && bi < len(p.Blocks); { - b := p.Blocks[bi] - if b.StartLine == line && b.StartCol == col { - boundaries = append(boundaries, boundary(si, true, b.Count)) - } - if b.EndLine == line && b.EndCol == col || line > b.EndLine { - boundaries = append(boundaries, boundary(si, false, 0)) - bi++ - continue // Don't advance through src; maybe the next block starts here. - } - if src[si] == '\n' { - line++ - col = 0 - } - col++ - si++ - } - sort.Sort(boundariesByPos(boundaries)) - return -} - -type boundariesByPos []Boundary - -func (b boundariesByPos) Len() int { return len(b) } -func (b boundariesByPos) Swap(i, j int) { b[i], b[j] = b[j], b[i] } -func (b boundariesByPos) Less(i, j int) bool { - if b[i].Offset == b[j].Offset { - // Boundaries at the same offset should be ordered according to - // their original position. - return b[i].Index < b[j].Index - } - return b[i].Offset < b[j].Offset -} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go deleted file mode 100644 index 0fb4e7ee..00000000 --- a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go +++ /dev/null @@ -1,663 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package astutil - -// This file defines utilities for working with source positions. - -import ( - "fmt" - "go/ast" - "go/token" - "sort" -) - -// PathEnclosingInterval returns the node that encloses the source -// interval [start, end), and all its ancestors up to the AST root. -// -// The definition of "enclosing" used by this function considers -// additional whitespace abutting a node to be enclosed by it. -// In this example: -// -// z := x + y // add them -// <-A-> -// <----B-----> -// -// the ast.BinaryExpr(+) node is considered to enclose interval B -// even though its [Pos()..End()) is actually only interval A. -// This behaviour makes user interfaces more tolerant of imperfect -// input. -// -// This function treats tokens as nodes, though they are not included -// in the result. e.g. PathEnclosingInterval("+") returns the -// enclosing ast.BinaryExpr("x + y"). -// -// If start==end, the 1-char interval following start is used instead. -// -// The 'exact' result is true if the interval contains only path[0] -// and perhaps some adjacent whitespace. It is false if the interval -// overlaps multiple children of path[0], or if it contains only -// interior whitespace of path[0]. -// In this example: -// -// z := x + y // add them -// <--C--> <---E--> -// ^ -// D -// -// intervals C, D and E are inexact. C is contained by the -// z-assignment statement, because it spans three of its children (:=, -// x, +). So too is the 1-char interval D, because it contains only -// interior whitespace of the assignment. E is considered interior -// whitespace of the BlockStmt containing the assignment. -// -// The resulting path is never empty; it always contains at least the -// 'root' *ast.File. Ideally PathEnclosingInterval would reject -// intervals that lie wholly or partially outside the range of the -// file, but unfortunately ast.File records only the token.Pos of -// the 'package' keyword, but not of the start of the file itself. -func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) { - // fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging - - // Precondition: node.[Pos..End) and adjoining whitespace contain [start, end). - var visit func(node ast.Node) bool - visit = func(node ast.Node) bool { - path = append(path, node) - - nodePos := node.Pos() - nodeEnd := node.End() - - // fmt.Printf("visit(%T, %d, %d)\n", node, nodePos, nodeEnd) // debugging - - // Intersect [start, end) with interval of node. - if start < nodePos { - start = nodePos - } - if end > nodeEnd { - end = nodeEnd - } - - // Find sole child that contains [start, end). - children := childrenOf(node) - l := len(children) - for i, child := range children { - // [childPos, childEnd) is unaugmented interval of child. - childPos := child.Pos() - childEnd := child.End() - - // [augPos, augEnd) is whitespace-augmented interval of child. - augPos := childPos - augEnd := childEnd - if i > 0 { - augPos = children[i-1].End() // start of preceding whitespace - } - if i < l-1 { - nextChildPos := children[i+1].Pos() - // Does [start, end) lie between child and next child? - if start >= augEnd && end <= nextChildPos { - return false // inexact match - } - augEnd = nextChildPos // end of following whitespace - } - - // fmt.Printf("\tchild %d: [%d..%d)\tcontains interval [%d..%d)?\n", - // i, augPos, augEnd, start, end) // debugging - - // Does augmented child strictly contain [start, end)? - if augPos <= start && end <= augEnd { - if is[tokenNode](child) { - return true - } - - // childrenOf elides the FuncType node beneath FuncDecl. - // Add it back here for TypeParams, Params, Results, - // all FieldLists). But we don't add it back for the "func" token - // even though it is the tree at FuncDecl.Type.Func. - if decl, ok := node.(*ast.FuncDecl); ok { - if fields, ok := child.(*ast.FieldList); ok && fields != decl.Recv { - path = append(path, decl.Type) - } - } - - return visit(child) - } - - // Does [start, end) overlap multiple children? - // i.e. left-augmented child contains start - // but LR-augmented child does not contain end. - if start < childEnd && end > augEnd { - break - } - } - - // No single child contained [start, end), - // so node is the result. Is it exact? - - // (It's tempting to put this condition before the - // child loop, but it gives the wrong result in the - // case where a node (e.g. ExprStmt) and its sole - // child have equal intervals.) - if start == nodePos && end == nodeEnd { - return true // exact match - } - - return false // inexact: overlaps multiple children - } - - // Ensure [start,end) is nondecreasing. - if start > end { - start, end = end, start - } - - if start < root.End() && end > root.Pos() { - if start == end { - end = start + 1 // empty interval => interval of size 1 - } - exact = visit(root) - - // Reverse the path: - for i, l := 0, len(path); i < l/2; i++ { - path[i], path[l-1-i] = path[l-1-i], path[i] - } - } else { - // Selection lies within whitespace preceding the - // first (or following the last) declaration in the file. - // The result nonetheless always includes the ast.File. - path = append(path, root) - } - - return -} - -// tokenNode is a dummy implementation of ast.Node for a single token. -// They are used transiently by PathEnclosingInterval but never escape -// this package. -type tokenNode struct { - pos token.Pos - end token.Pos -} - -func (n tokenNode) Pos() token.Pos { - return n.pos -} - -func (n tokenNode) End() token.Pos { - return n.end -} - -func tok(pos token.Pos, len int) ast.Node { - return tokenNode{pos, pos + token.Pos(len)} -} - -// childrenOf returns the direct non-nil children of ast.Node n. -// It may include fake ast.Node implementations for bare tokens. -// it is not safe to call (e.g.) ast.Walk on such nodes. -func childrenOf(n ast.Node) []ast.Node { - var children []ast.Node - - // First add nodes for all true subtrees. - ast.Inspect(n, func(node ast.Node) bool { - if node == n { // push n - return true // recur - } - if node != nil { // push child - children = append(children, node) - } - return false // no recursion - }) - - // TODO(adonovan): be more careful about missing (!Pos.Valid) - // tokens in trees produced from invalid input. - - // Then add fake Nodes for bare tokens. - switch n := n.(type) { - case *ast.ArrayType: - children = append(children, - tok(n.Lbrack, len("[")), - tok(n.Elt.End(), len("]"))) - - case *ast.AssignStmt: - children = append(children, - tok(n.TokPos, len(n.Tok.String()))) - - case *ast.BasicLit: - children = append(children, - tok(n.ValuePos, len(n.Value))) - - case *ast.BinaryExpr: - children = append(children, tok(n.OpPos, len(n.Op.String()))) - - case *ast.BlockStmt: - if n.Lbrace.IsValid() { - children = append(children, tok(n.Lbrace, len("{"))) - } - if n.Rbrace.IsValid() { - children = append(children, tok(n.Rbrace, len("}"))) - } - - case *ast.BranchStmt: - children = append(children, - tok(n.TokPos, len(n.Tok.String()))) - - case *ast.CallExpr: - children = append(children, - tok(n.Lparen, len("(")), - tok(n.Rparen, len(")"))) - if n.Ellipsis != 0 { - children = append(children, tok(n.Ellipsis, len("..."))) - } - - case *ast.CaseClause: - if n.List == nil { - children = append(children, - tok(n.Case, len("default"))) - } else { - children = append(children, - tok(n.Case, len("case"))) - } - children = append(children, tok(n.Colon, len(":"))) - - case *ast.ChanType: - switch n.Dir { - case ast.RECV: - children = append(children, tok(n.Begin, len("<-chan"))) - case ast.SEND: - children = append(children, tok(n.Begin, len("chan<-"))) - case ast.RECV | ast.SEND: - children = append(children, tok(n.Begin, len("chan"))) - } - - case *ast.CommClause: - if n.Comm == nil { - children = append(children, - tok(n.Case, len("default"))) - } else { - children = append(children, - tok(n.Case, len("case"))) - } - children = append(children, tok(n.Colon, len(":"))) - - case *ast.Comment: - // nop - - case *ast.CommentGroup: - // nop - - case *ast.CompositeLit: - children = append(children, - tok(n.Lbrace, len("{")), - tok(n.Rbrace, len("{"))) - - case *ast.DeclStmt: - // nop - - case *ast.DeferStmt: - children = append(children, - tok(n.Defer, len("defer"))) - - case *ast.Ellipsis: - children = append(children, - tok(n.Ellipsis, len("..."))) - - case *ast.EmptyStmt: - // nop - - case *ast.ExprStmt: - // nop - - case *ast.Field: - // TODO(adonovan): Field.{Doc,Comment,Tag}? - - case *ast.FieldList: - if n.Opening.IsValid() { - children = append(children, tok(n.Opening, len("("))) - } - if n.Closing.IsValid() { - children = append(children, tok(n.Closing, len(")"))) - } - - case *ast.File: - // TODO test: Doc - children = append(children, - tok(n.Package, len("package"))) - - case *ast.ForStmt: - children = append(children, - tok(n.For, len("for"))) - - case *ast.FuncDecl: - // TODO(adonovan): FuncDecl.Comment? - - // Uniquely, FuncDecl breaks the invariant that - // preorder traversal yields tokens in lexical order: - // in fact, FuncDecl.Recv precedes FuncDecl.Type.Func. - // - // As a workaround, we inline the case for FuncType - // here and order things correctly. - // We also need to insert the elided FuncType just - // before the 'visit' recursion. - // - children = nil // discard ast.Walk(FuncDecl) info subtrees - children = append(children, tok(n.Type.Func, len("func"))) - if n.Recv != nil { - children = append(children, n.Recv) - } - children = append(children, n.Name) - if tparams := n.Type.TypeParams; tparams != nil { - children = append(children, tparams) - } - if n.Type.Params != nil { - children = append(children, n.Type.Params) - } - if n.Type.Results != nil { - children = append(children, n.Type.Results) - } - if n.Body != nil { - children = append(children, n.Body) - } - - case *ast.FuncLit: - // nop - - case *ast.FuncType: - if n.Func != 0 { - children = append(children, - tok(n.Func, len("func"))) - } - - case *ast.GenDecl: - children = append(children, - tok(n.TokPos, len(n.Tok.String()))) - if n.Lparen != 0 { - children = append(children, - tok(n.Lparen, len("(")), - tok(n.Rparen, len(")"))) - } - - case *ast.GoStmt: - children = append(children, - tok(n.Go, len("go"))) - - case *ast.Ident: - children = append(children, - tok(n.NamePos, len(n.Name))) - - case *ast.IfStmt: - children = append(children, - tok(n.If, len("if"))) - - case *ast.ImportSpec: - // TODO(adonovan): ImportSpec.{Doc,EndPos}? - - case *ast.IncDecStmt: - children = append(children, - tok(n.TokPos, len(n.Tok.String()))) - - case *ast.IndexExpr: - children = append(children, - tok(n.Lbrack, len("[")), - tok(n.Rbrack, len("]"))) - - case *ast.IndexListExpr: - children = append(children, - tok(n.Lbrack, len("[")), - tok(n.Rbrack, len("]"))) - - case *ast.InterfaceType: - children = append(children, - tok(n.Interface, len("interface"))) - - case *ast.KeyValueExpr: - children = append(children, - tok(n.Colon, len(":"))) - - case *ast.LabeledStmt: - children = append(children, - tok(n.Colon, len(":"))) - - case *ast.MapType: - children = append(children, - tok(n.Map, len("map"))) - - case *ast.ParenExpr: - children = append(children, - tok(n.Lparen, len("(")), - tok(n.Rparen, len(")"))) - - case *ast.RangeStmt: - children = append(children, - tok(n.For, len("for")), - tok(n.TokPos, len(n.Tok.String()))) - - case *ast.ReturnStmt: - children = append(children, - tok(n.Return, len("return"))) - - case *ast.SelectStmt: - children = append(children, - tok(n.Select, len("select"))) - - case *ast.SelectorExpr: - // nop - - case *ast.SendStmt: - children = append(children, - tok(n.Arrow, len("<-"))) - - case *ast.SliceExpr: - children = append(children, - tok(n.Lbrack, len("[")), - tok(n.Rbrack, len("]"))) - - case *ast.StarExpr: - children = append(children, tok(n.Star, len("*"))) - - case *ast.StructType: - children = append(children, tok(n.Struct, len("struct"))) - - case *ast.SwitchStmt: - children = append(children, tok(n.Switch, len("switch"))) - - case *ast.TypeAssertExpr: - children = append(children, - tok(n.Lparen-1, len(".")), - tok(n.Lparen, len("(")), - tok(n.Rparen, len(")"))) - - case *ast.TypeSpec: - // TODO(adonovan): TypeSpec.{Doc,Comment}? - - case *ast.TypeSwitchStmt: - children = append(children, tok(n.Switch, len("switch"))) - - case *ast.UnaryExpr: - children = append(children, tok(n.OpPos, len(n.Op.String()))) - - case *ast.ValueSpec: - // TODO(adonovan): ValueSpec.{Doc,Comment}? - - case *ast.BadDecl, *ast.BadExpr, *ast.BadStmt: - // nop - } - - // TODO(adonovan): opt: merge the logic of ast.Inspect() into - // the switch above so we can make interleaved callbacks for - // both Nodes and Tokens in the right order and avoid the need - // to sort. - sort.Sort(byPos(children)) - - return children -} - -type byPos []ast.Node - -func (sl byPos) Len() int { - return len(sl) -} -func (sl byPos) Less(i, j int) bool { - return sl[i].Pos() < sl[j].Pos() -} -func (sl byPos) Swap(i, j int) { - sl[i], sl[j] = sl[j], sl[i] -} - -// NodeDescription returns a description of the concrete type of n suitable -// for a user interface. -// -// TODO(adonovan): in some cases (e.g. Field, FieldList, Ident, -// StarExpr) we could be much more specific given the path to the AST -// root. Perhaps we should do that. -func NodeDescription(n ast.Node) string { - switch n := n.(type) { - case *ast.ArrayType: - return "array type" - case *ast.AssignStmt: - return "assignment" - case *ast.BadDecl: - return "bad declaration" - case *ast.BadExpr: - return "bad expression" - case *ast.BadStmt: - return "bad statement" - case *ast.BasicLit: - return "basic literal" - case *ast.BinaryExpr: - return fmt.Sprintf("binary %s operation", n.Op) - case *ast.BlockStmt: - return "block" - case *ast.BranchStmt: - switch n.Tok { - case token.BREAK: - return "break statement" - case token.CONTINUE: - return "continue statement" - case token.GOTO: - return "goto statement" - case token.FALLTHROUGH: - return "fall-through statement" - } - case *ast.CallExpr: - if len(n.Args) == 1 && !n.Ellipsis.IsValid() { - return "function call (or conversion)" - } - return "function call" - case *ast.CaseClause: - return "case clause" - case *ast.ChanType: - return "channel type" - case *ast.CommClause: - return "communication clause" - case *ast.Comment: - return "comment" - case *ast.CommentGroup: - return "comment group" - case *ast.CompositeLit: - return "composite literal" - case *ast.DeclStmt: - return NodeDescription(n.Decl) + " statement" - case *ast.DeferStmt: - return "defer statement" - case *ast.Ellipsis: - return "ellipsis" - case *ast.EmptyStmt: - return "empty statement" - case *ast.ExprStmt: - return "expression statement" - case *ast.Field: - // Can be any of these: - // struct {x, y int} -- struct field(s) - // struct {T} -- anon struct field - // interface {I} -- interface embedding - // interface {f()} -- interface method - // func (A) func(B) C -- receiver, param(s), result(s) - return "field/method/parameter" - case *ast.FieldList: - return "field/method/parameter list" - case *ast.File: - return "source file" - case *ast.ForStmt: - return "for loop" - case *ast.FuncDecl: - return "function declaration" - case *ast.FuncLit: - return "function literal" - case *ast.FuncType: - return "function type" - case *ast.GenDecl: - switch n.Tok { - case token.IMPORT: - return "import declaration" - case token.CONST: - return "constant declaration" - case token.TYPE: - return "type declaration" - case token.VAR: - return "variable declaration" - } - case *ast.GoStmt: - return "go statement" - case *ast.Ident: - return "identifier" - case *ast.IfStmt: - return "if statement" - case *ast.ImportSpec: - return "import specification" - case *ast.IncDecStmt: - if n.Tok == token.INC { - return "increment statement" - } - return "decrement statement" - case *ast.IndexExpr: - return "index expression" - case *ast.IndexListExpr: - return "index list expression" - case *ast.InterfaceType: - return "interface type" - case *ast.KeyValueExpr: - return "key/value association" - case *ast.LabeledStmt: - return "statement label" - case *ast.MapType: - return "map type" - case *ast.Package: - return "package" - case *ast.ParenExpr: - return "parenthesized " + NodeDescription(n.X) - case *ast.RangeStmt: - return "range loop" - case *ast.ReturnStmt: - return "return statement" - case *ast.SelectStmt: - return "select statement" - case *ast.SelectorExpr: - return "selector" - case *ast.SendStmt: - return "channel send" - case *ast.SliceExpr: - return "slice expression" - case *ast.StarExpr: - return "*-operation" // load/store expr or pointer type - case *ast.StructType: - return "struct type" - case *ast.SwitchStmt: - return "switch statement" - case *ast.TypeAssertExpr: - return "type assertion" - case *ast.TypeSpec: - return "type specification" - case *ast.TypeSwitchStmt: - return "type switch" - case *ast.UnaryExpr: - return fmt.Sprintf("unary %s operation", n.Op) - case *ast.ValueSpec: - return "value specification" - - } - panic(fmt.Sprintf("unexpected node type: %T", n)) -} - -func is[T any](x any) bool { - _, ok := x.(T) - return ok -} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go deleted file mode 100644 index adb47110..00000000 --- a/vendor/golang.org/x/tools/go/ast/astutil/imports.go +++ /dev/null @@ -1,487 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package astutil contains common utilities for working with the Go AST. -package astutil // import "golang.org/x/tools/go/ast/astutil" - -import ( - "fmt" - "go/ast" - "go/token" - "reflect" - "slices" - "strconv" - "strings" -) - -// AddImport adds the import path to the file f, if absent. -func AddImport(fset *token.FileSet, f *ast.File, path string) (added bool) { - return AddNamedImport(fset, f, "", path) -} - -// AddNamedImport adds the import with the given name and path to the file f, if absent. -// If name is not empty, it is used to rename the import. -// -// For example, calling -// -// AddNamedImport(fset, f, "pathpkg", "path") -// -// adds -// -// import pathpkg "path" -func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added bool) { - if imports(f, name, path) { - return false - } - - newImport := &ast.ImportSpec{ - Path: &ast.BasicLit{ - Kind: token.STRING, - Value: strconv.Quote(path), - }, - } - if name != "" { - newImport.Name = &ast.Ident{Name: name} - } - - // Find an import decl to add to. - // The goal is to find an existing import - // whose import path has the longest shared - // prefix with path. - var ( - bestMatch = -1 // length of longest shared prefix - lastImport = -1 // index in f.Decls of the file's final import decl - impDecl *ast.GenDecl // import decl containing the best match - impIndex = -1 // spec index in impDecl containing the best match - - isThirdPartyPath = isThirdParty(path) - ) - for i, decl := range f.Decls { - gen, ok := decl.(*ast.GenDecl) - if ok && gen.Tok == token.IMPORT { - lastImport = i - // Do not add to import "C", to avoid disrupting the - // association with its doc comment, breaking cgo. - if declImports(gen, "C") { - continue - } - - // Match an empty import decl if that's all that is available. - if len(gen.Specs) == 0 && bestMatch == -1 { - impDecl = gen - } - - // Compute longest shared prefix with imports in this group and find best - // matched import spec. - // 1. Always prefer import spec with longest shared prefix. - // 2. While match length is 0, - // - for stdlib package: prefer first import spec. - // - for third party package: prefer first third party import spec. - // We cannot use last import spec as best match for third party package - // because grouped imports are usually placed last by goimports -local - // flag. - // See issue #19190. - seenAnyThirdParty := false - for j, spec := range gen.Specs { - impspec := spec.(*ast.ImportSpec) - p := importPath(impspec) - n := matchLen(p, path) - if n > bestMatch || (bestMatch == 0 && !seenAnyThirdParty && isThirdPartyPath) { - bestMatch = n - impDecl = gen - impIndex = j - } - seenAnyThirdParty = seenAnyThirdParty || isThirdParty(p) - } - } - } - - // If no import decl found, add one after the last import. - if impDecl == nil { - impDecl = &ast.GenDecl{ - Tok: token.IMPORT, - } - if lastImport >= 0 { - impDecl.TokPos = f.Decls[lastImport].End() - } else { - // There are no existing imports. - // Our new import, preceded by a blank line, goes after the package declaration - // and after the comment, if any, that starts on the same line as the - // package declaration. - impDecl.TokPos = f.Package - - file := fset.File(f.Package) - pkgLine := file.Line(f.Package) - for _, c := range f.Comments { - if file.Line(c.Pos()) > pkgLine { - break - } - // +2 for a blank line - impDecl.TokPos = c.End() + 2 - } - } - f.Decls = append(f.Decls, nil) - copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:]) - f.Decls[lastImport+1] = impDecl - } - - // Insert new import at insertAt. - insertAt := 0 - if impIndex >= 0 { - // insert after the found import - insertAt = impIndex + 1 - } - impDecl.Specs = append(impDecl.Specs, nil) - copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:]) - impDecl.Specs[insertAt] = newImport - pos := impDecl.Pos() - if insertAt > 0 { - // If there is a comment after an existing import, preserve the comment - // position by adding the new import after the comment. - if spec, ok := impDecl.Specs[insertAt-1].(*ast.ImportSpec); ok && spec.Comment != nil { - pos = spec.Comment.End() - } else { - // Assign same position as the previous import, - // so that the sorter sees it as being in the same block. - pos = impDecl.Specs[insertAt-1].Pos() - } - } - if newImport.Name != nil { - newImport.Name.NamePos = pos - } - updateBasicLitPos(newImport.Path, pos) - newImport.EndPos = pos - - // Clean up parens. impDecl contains at least one spec. - if len(impDecl.Specs) == 1 { - // Remove unneeded parens. - impDecl.Lparen = token.NoPos - } else if !impDecl.Lparen.IsValid() { - // impDecl needs parens added. - impDecl.Lparen = impDecl.Specs[0].Pos() - } - - f.Imports = append(f.Imports, newImport) - - if len(f.Decls) <= 1 { - return true - } - - // Merge all the import declarations into the first one. - var first *ast.GenDecl - for i := 0; i < len(f.Decls); i++ { - decl := f.Decls[i] - gen, ok := decl.(*ast.GenDecl) - if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") { - continue - } - if first == nil { - first = gen - continue // Don't touch the first one. - } - // We now know there is more than one package in this import - // declaration. Ensure that it ends up parenthesized. - first.Lparen = first.Pos() - // Move the imports of the other import declaration to the first one. - for _, spec := range gen.Specs { - updateBasicLitPos(spec.(*ast.ImportSpec).Path, first.Pos()) - first.Specs = append(first.Specs, spec) - } - f.Decls = slices.Delete(f.Decls, i, i+1) - i-- - } - - return true -} - -func isThirdParty(importPath string) bool { - // Third party package import path usually contains "." (".com", ".org", ...) - // This logic is taken from golang.org/x/tools/imports package. - return strings.Contains(importPath, ".") -} - -// DeleteImport deletes the import path from the file f, if present. -// If there are duplicate import declarations, all matching ones are deleted. -func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) { - return DeleteNamedImport(fset, f, "", path) -} - -// DeleteNamedImport deletes the import with the given name and path from the file f, if present. -// If there are duplicate import declarations, all matching ones are deleted. -func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) { - var ( - delspecs = make(map[*ast.ImportSpec]bool) - delcomments = make(map[*ast.CommentGroup]bool) - ) - - // Find the import nodes that import path, if any. - for i := 0; i < len(f.Decls); i++ { - gen, ok := f.Decls[i].(*ast.GenDecl) - if !ok || gen.Tok != token.IMPORT { - continue - } - for j := 0; j < len(gen.Specs); j++ { - impspec := gen.Specs[j].(*ast.ImportSpec) - if importName(impspec) != name || importPath(impspec) != path { - continue - } - - // We found an import spec that imports path. - // Delete it. - delspecs[impspec] = true - deleted = true - gen.Specs = slices.Delete(gen.Specs, j, j+1) - - // If this was the last import spec in this decl, - // delete the decl, too. - if len(gen.Specs) == 0 { - f.Decls = slices.Delete(f.Decls, i, i+1) - i-- - break - } else if len(gen.Specs) == 1 { - if impspec.Doc != nil { - delcomments[impspec.Doc] = true - } - if impspec.Comment != nil { - delcomments[impspec.Comment] = true - } - for _, cg := range f.Comments { - // Found comment on the same line as the import spec. - if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line { - delcomments[cg] = true - break - } - } - - spec := gen.Specs[0].(*ast.ImportSpec) - - // Move the documentation right after the import decl. - if spec.Doc != nil { - for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Doc.Pos()).Line { - fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line) - } - } - for _, cg := range f.Comments { - if cg.End() < spec.Pos() && fset.Position(cg.End()).Line == fset.Position(spec.Pos()).Line { - for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Pos()).Line { - fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line) - } - break - } - } - } - if j > 0 { - lastImpspec := gen.Specs[j-1].(*ast.ImportSpec) - lastLine := fset.PositionFor(lastImpspec.Path.ValuePos, false).Line - line := fset.PositionFor(impspec.Path.ValuePos, false).Line - - // We deleted an entry but now there may be - // a blank line-sized hole where the import was. - if line-lastLine > 1 || !gen.Rparen.IsValid() { - // There was a blank line immediately preceding the deleted import, - // so there's no need to close the hole. The right parenthesis is - // invalid after AddImport to an import statement without parenthesis. - // Do nothing. - } else if line != fset.File(gen.Rparen).LineCount() { - // There was no blank line. Close the hole. - fset.File(gen.Rparen).MergeLine(line) - } - } - j-- - } - } - - // Delete imports from f.Imports. - before := len(f.Imports) - f.Imports = slices.DeleteFunc(f.Imports, func(imp *ast.ImportSpec) bool { - _, ok := delspecs[imp] - return ok - }) - if len(f.Imports)+len(delspecs) != before { - // This can happen when the AST is invalid (i.e. imports differ between f.Decls and f.Imports). - panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs)) - } - - // Delete comments from f.Comments. - f.Comments = slices.DeleteFunc(f.Comments, func(cg *ast.CommentGroup) bool { - _, ok := delcomments[cg] - return ok - }) - - return -} - -// RewriteImport rewrites any import of path oldPath to path newPath. -func RewriteImport(fset *token.FileSet, f *ast.File, oldPath, newPath string) (rewrote bool) { - for _, imp := range f.Imports { - if importPath(imp) == oldPath { - rewrote = true - // record old End, because the default is to compute - // it using the length of imp.Path.Value. - imp.EndPos = imp.End() - imp.Path.Value = strconv.Quote(newPath) - } - } - return -} - -// UsesImport reports whether a given import is used. -// The provided File must have been parsed with syntactic object resolution -// (not using go/parser.SkipObjectResolution). -func UsesImport(f *ast.File, path string) (used bool) { - if f.Scope == nil { - panic("file f was not parsed with syntactic object resolution") - } - spec := importSpec(f, path) - if spec == nil { - return - } - - name := spec.Name.String() - switch name { - case "": - // If the package name is not explicitly specified, - // make an educated guess. This is not guaranteed to be correct. - lastSlash := strings.LastIndex(path, "/") - if lastSlash == -1 { - name = path - } else { - name = path[lastSlash+1:] - } - case "_", ".": - // Not sure if this import is used - err on the side of caution. - return true - } - - ast.Walk(visitFn(func(n ast.Node) { - sel, ok := n.(*ast.SelectorExpr) - if ok && isTopName(sel.X, name) { - used = true - } - }), f) - - return -} - -type visitFn func(node ast.Node) - -func (fn visitFn) Visit(node ast.Node) ast.Visitor { - fn(node) - return fn -} - -// imports reports whether f has an import with the specified name and path. -func imports(f *ast.File, name, path string) bool { - for _, s := range f.Imports { - if importName(s) == name && importPath(s) == path { - return true - } - } - return false -} - -// importSpec returns the import spec if f imports path, -// or nil otherwise. -func importSpec(f *ast.File, path string) *ast.ImportSpec { - for _, s := range f.Imports { - if importPath(s) == path { - return s - } - } - return nil -} - -// importName returns the name of s, -// or "" if the import is not named. -func importName(s *ast.ImportSpec) string { - if s.Name == nil { - return "" - } - return s.Name.Name -} - -// importPath returns the unquoted import path of s, -// or "" if the path is not properly quoted. -func importPath(s *ast.ImportSpec) string { - t, err := strconv.Unquote(s.Path.Value) - if err != nil { - return "" - } - return t -} - -// declImports reports whether gen contains an import of path. -func declImports(gen *ast.GenDecl, path string) bool { - if gen.Tok != token.IMPORT { - return false - } - for _, spec := range gen.Specs { - impspec := spec.(*ast.ImportSpec) - if importPath(impspec) == path { - return true - } - } - return false -} - -// matchLen returns the length of the longest path segment prefix shared by x and y. -func matchLen(x, y string) int { - n := 0 - for i := 0; i < len(x) && i < len(y) && x[i] == y[i]; i++ { - if x[i] == '/' { - n++ - } - } - return n -} - -// isTopName returns true if n is a top-level unresolved identifier with the given name. -func isTopName(n ast.Expr, name string) bool { - id, ok := n.(*ast.Ident) - return ok && id.Name == name && id.Obj == nil -} - -// Imports returns the file imports grouped by paragraph. -func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec { - var groups [][]*ast.ImportSpec - - for _, decl := range f.Decls { - genDecl, ok := decl.(*ast.GenDecl) - if !ok || genDecl.Tok != token.IMPORT { - break - } - - group := []*ast.ImportSpec{} - - var lastLine int - for _, spec := range genDecl.Specs { - importSpec := spec.(*ast.ImportSpec) - pos := importSpec.Path.ValuePos - line := fset.Position(pos).Line - if lastLine > 0 && pos > 0 && line-lastLine > 1 { - groups = append(groups, group) - group = []*ast.ImportSpec{} - } - group = append(group, importSpec) - lastLine = line - } - groups = append(groups, group) - } - - return groups -} - -// updateBasicLitPos updates lit.Pos, -// ensuring that lit.End (if set) is displaced by the same amount. -// (See https://go.dev/issue/76395.) -func updateBasicLitPos(lit *ast.BasicLit, pos token.Pos) { - len := lit.End() - lit.Pos() - lit.ValuePos = pos - // TODO(adonovan): after go1.26, simplify to: - // lit.ValueEnd = pos + len - v := reflect.ValueOf(lit).Elem().FieldByName("ValueEnd") - if v.IsValid() && v.Int() != 0 { - v.SetInt(int64(pos + len)) - } -} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go b/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go deleted file mode 100644 index 4ad05493..00000000 --- a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go +++ /dev/null @@ -1,490 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package astutil - -import ( - "fmt" - "go/ast" - "reflect" - "sort" -) - -// An ApplyFunc is invoked by Apply for each node n, even if n is nil, -// before and/or after the node's children, using a Cursor describing -// the current node and providing operations on it. -// -// The return value of ApplyFunc controls the syntax tree traversal. -// See Apply for details. -type ApplyFunc func(*Cursor) bool - -// Apply traverses a syntax tree recursively, starting with root, -// and calling pre and post for each node as described below. -// Apply returns the syntax tree, possibly modified. -// -// If pre is not nil, it is called for each node before the node's -// children are traversed (pre-order). If pre returns false, no -// children are traversed, and post is not called for that node. -// -// If post is not nil, and a prior call of pre didn't return false, -// post is called for each node after its children are traversed -// (post-order). If post returns false, traversal is terminated and -// Apply returns immediately. -// -// Only fields that refer to AST nodes are considered children; -// i.e., token.Pos, Scopes, Objects, and fields of basic types -// (strings, etc.) are ignored. -// -// Children are traversed in the order in which they appear in the -// respective node's struct definition. A package's files are -// traversed in the filenames' alphabetical order. -func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node) { - parent := &struct{ ast.Node }{root} - defer func() { - if r := recover(); r != nil && r != abort { - panic(r) - } - result = parent.Node - }() - a := &application{pre: pre, post: post} - a.apply(parent, "Node", nil, root) - return -} - -var abort = new(int) // singleton, to signal termination of Apply - -// A Cursor describes a node encountered during Apply. -// Information about the node and its parent is available -// from the Node, Parent, Name, and Index methods. -// -// If p is a variable of type and value of the current parent node -// c.Parent(), and f is the field identifier with name c.Name(), -// the following invariants hold: -// -// p.f == c.Node() if c.Index() < 0 -// p.f[c.Index()] == c.Node() if c.Index() >= 0 -// -// The methods Replace, Delete, InsertBefore, and InsertAfter -// can be used to change the AST without disrupting Apply. -// -// This type is not to be confused with [inspector.Cursor] from -// package [golang.org/x/tools/go/ast/inspector], which provides -// stateless navigation of immutable syntax trees. -type Cursor struct { - parent ast.Node - name string - iter *iterator // valid if non-nil - node ast.Node -} - -// Node returns the current Node. -func (c *Cursor) Node() ast.Node { return c.node } - -// Parent returns the parent of the current Node. -func (c *Cursor) Parent() ast.Node { return c.parent } - -// Name returns the name of the parent Node field that contains the current Node. -// If the parent is a *ast.Package and the current Node is a *ast.File, Name returns -// the filename for the current Node. -func (c *Cursor) Name() string { return c.name } - -// Index reports the index >= 0 of the current Node in the slice of Nodes that -// contains it, or a value < 0 if the current Node is not part of a slice. -// The index of the current node changes if InsertBefore is called while -// processing the current node. -func (c *Cursor) Index() int { - if c.iter != nil { - return c.iter.index - } - return -1 -} - -// field returns the current node's parent field value. -func (c *Cursor) field() reflect.Value { - return reflect.Indirect(reflect.ValueOf(c.parent)).FieldByName(c.name) -} - -// Replace replaces the current Node with n. -// The replacement node is not walked by Apply. -func (c *Cursor) Replace(n ast.Node) { - if _, ok := c.node.(*ast.File); ok { - file, ok := n.(*ast.File) - if !ok { - panic("attempt to replace *ast.File with non-*ast.File") - } - c.parent.(*ast.Package).Files[c.name] = file - return - } - - v := c.field() - if i := c.Index(); i >= 0 { - v = v.Index(i) - } - v.Set(reflect.ValueOf(n)) -} - -// Delete deletes the current Node from its containing slice. -// If the current Node is not part of a slice, Delete panics. -// As a special case, if the current node is a package file, -// Delete removes it from the package's Files map. -func (c *Cursor) Delete() { - if _, ok := c.node.(*ast.File); ok { - delete(c.parent.(*ast.Package).Files, c.name) - return - } - - i := c.Index() - if i < 0 { - panic("Delete node not contained in slice") - } - v := c.field() - l := v.Len() - reflect.Copy(v.Slice(i, l), v.Slice(i+1, l)) - v.Index(l - 1).Set(reflect.Zero(v.Type().Elem())) - v.SetLen(l - 1) - c.iter.step-- -} - -// InsertAfter inserts n after the current Node in its containing slice. -// If the current Node is not part of a slice, InsertAfter panics. -// Apply does not walk n. -func (c *Cursor) InsertAfter(n ast.Node) { - i := c.Index() - if i < 0 { - panic("InsertAfter node not contained in slice") - } - v := c.field() - v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) - l := v.Len() - reflect.Copy(v.Slice(i+2, l), v.Slice(i+1, l)) - v.Index(i + 1).Set(reflect.ValueOf(n)) - c.iter.step++ -} - -// InsertBefore inserts n before the current Node in its containing slice. -// If the current Node is not part of a slice, InsertBefore panics. -// Apply will not walk n. -func (c *Cursor) InsertBefore(n ast.Node) { - i := c.Index() - if i < 0 { - panic("InsertBefore node not contained in slice") - } - v := c.field() - v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) - l := v.Len() - reflect.Copy(v.Slice(i+1, l), v.Slice(i, l)) - v.Index(i).Set(reflect.ValueOf(n)) - c.iter.index++ -} - -// application carries all the shared data so we can pass it around cheaply. -type application struct { - pre, post ApplyFunc - cursor Cursor - iter iterator -} - -func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.Node) { - // convert typed nil into untyped nil - if v := reflect.ValueOf(n); v.Kind() == reflect.Pointer && v.IsNil() { - n = nil - } - - // avoid heap-allocating a new cursor for each apply call; reuse a.cursor instead - saved := a.cursor - a.cursor.parent = parent - a.cursor.name = name - a.cursor.iter = iter - a.cursor.node = n - - if a.pre != nil && !a.pre(&a.cursor) { - a.cursor = saved - return - } - - // walk children - // (the order of the cases matches the order of the corresponding node types in go/ast) - switch n := n.(type) { - case nil: - // nothing to do - - // Comments and fields - case *ast.Comment: - // nothing to do - - case *ast.CommentGroup: - if n != nil { - a.applyList(n, "List") - } - - case *ast.Field: - a.apply(n, "Doc", nil, n.Doc) - a.applyList(n, "Names") - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Tag", nil, n.Tag) - a.apply(n, "Comment", nil, n.Comment) - - case *ast.FieldList: - a.applyList(n, "List") - - // Expressions - case *ast.BadExpr, *ast.Ident, *ast.BasicLit: - // nothing to do - - case *ast.Ellipsis: - a.apply(n, "Elt", nil, n.Elt) - - case *ast.FuncLit: - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Body", nil, n.Body) - - case *ast.CompositeLit: - a.apply(n, "Type", nil, n.Type) - a.applyList(n, "Elts") - - case *ast.ParenExpr: - a.apply(n, "X", nil, n.X) - - case *ast.SelectorExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Sel", nil, n.Sel) - - case *ast.IndexExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Index", nil, n.Index) - - case *ast.IndexListExpr: - a.apply(n, "X", nil, n.X) - a.applyList(n, "Indices") - - case *ast.SliceExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Low", nil, n.Low) - a.apply(n, "High", nil, n.High) - a.apply(n, "Max", nil, n.Max) - - case *ast.TypeAssertExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Type", nil, n.Type) - - case *ast.CallExpr: - a.apply(n, "Fun", nil, n.Fun) - a.applyList(n, "Args") - - case *ast.StarExpr: - a.apply(n, "X", nil, n.X) - - case *ast.UnaryExpr: - a.apply(n, "X", nil, n.X) - - case *ast.BinaryExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Y", nil, n.Y) - - case *ast.KeyValueExpr: - a.apply(n, "Key", nil, n.Key) - a.apply(n, "Value", nil, n.Value) - - // Types - case *ast.ArrayType: - a.apply(n, "Len", nil, n.Len) - a.apply(n, "Elt", nil, n.Elt) - - case *ast.StructType: - a.apply(n, "Fields", nil, n.Fields) - - case *ast.FuncType: - if tparams := n.TypeParams; tparams != nil { - a.apply(n, "TypeParams", nil, tparams) - } - a.apply(n, "Params", nil, n.Params) - a.apply(n, "Results", nil, n.Results) - - case *ast.InterfaceType: - a.apply(n, "Methods", nil, n.Methods) - - case *ast.MapType: - a.apply(n, "Key", nil, n.Key) - a.apply(n, "Value", nil, n.Value) - - case *ast.ChanType: - a.apply(n, "Value", nil, n.Value) - - // Statements - case *ast.BadStmt: - // nothing to do - - case *ast.DeclStmt: - a.apply(n, "Decl", nil, n.Decl) - - case *ast.EmptyStmt: - // nothing to do - - case *ast.LabeledStmt: - a.apply(n, "Label", nil, n.Label) - a.apply(n, "Stmt", nil, n.Stmt) - - case *ast.ExprStmt: - a.apply(n, "X", nil, n.X) - - case *ast.SendStmt: - a.apply(n, "Chan", nil, n.Chan) - a.apply(n, "Value", nil, n.Value) - - case *ast.IncDecStmt: - a.apply(n, "X", nil, n.X) - - case *ast.AssignStmt: - a.applyList(n, "Lhs") - a.applyList(n, "Rhs") - - case *ast.GoStmt: - a.apply(n, "Call", nil, n.Call) - - case *ast.DeferStmt: - a.apply(n, "Call", nil, n.Call) - - case *ast.ReturnStmt: - a.applyList(n, "Results") - - case *ast.BranchStmt: - a.apply(n, "Label", nil, n.Label) - - case *ast.BlockStmt: - a.applyList(n, "List") - - case *ast.IfStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Cond", nil, n.Cond) - a.apply(n, "Body", nil, n.Body) - a.apply(n, "Else", nil, n.Else) - - case *ast.CaseClause: - a.applyList(n, "List") - a.applyList(n, "Body") - - case *ast.SwitchStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Tag", nil, n.Tag) - a.apply(n, "Body", nil, n.Body) - - case *ast.TypeSwitchStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Assign", nil, n.Assign) - a.apply(n, "Body", nil, n.Body) - - case *ast.CommClause: - a.apply(n, "Comm", nil, n.Comm) - a.applyList(n, "Body") - - case *ast.SelectStmt: - a.apply(n, "Body", nil, n.Body) - - case *ast.ForStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Cond", nil, n.Cond) - a.apply(n, "Post", nil, n.Post) - a.apply(n, "Body", nil, n.Body) - - case *ast.RangeStmt: - a.apply(n, "Key", nil, n.Key) - a.apply(n, "Value", nil, n.Value) - a.apply(n, "X", nil, n.X) - a.apply(n, "Body", nil, n.Body) - - // Declarations - case *ast.ImportSpec: - a.apply(n, "Doc", nil, n.Doc) - a.apply(n, "Name", nil, n.Name) - a.apply(n, "Path", nil, n.Path) - a.apply(n, "Comment", nil, n.Comment) - - case *ast.ValueSpec: - a.apply(n, "Doc", nil, n.Doc) - a.applyList(n, "Names") - a.apply(n, "Type", nil, n.Type) - a.applyList(n, "Values") - a.apply(n, "Comment", nil, n.Comment) - - case *ast.TypeSpec: - a.apply(n, "Doc", nil, n.Doc) - a.apply(n, "Name", nil, n.Name) - if tparams := n.TypeParams; tparams != nil { - a.apply(n, "TypeParams", nil, tparams) - } - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Comment", nil, n.Comment) - - case *ast.BadDecl: - // nothing to do - - case *ast.GenDecl: - a.apply(n, "Doc", nil, n.Doc) - a.applyList(n, "Specs") - - case *ast.FuncDecl: - a.apply(n, "Doc", nil, n.Doc) - a.apply(n, "Recv", nil, n.Recv) - a.apply(n, "Name", nil, n.Name) - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Body", nil, n.Body) - - // Files and packages - case *ast.File: - a.apply(n, "Doc", nil, n.Doc) - a.apply(n, "Name", nil, n.Name) - a.applyList(n, "Decls") - // Don't walk n.Comments; they have either been walked already if - // they are Doc comments, or they can be easily walked explicitly. - - case *ast.Package: - // collect and sort names for reproducible behavior - var names []string - for name := range n.Files { - names = append(names, name) - } - sort.Strings(names) - for _, name := range names { - a.apply(n, name, nil, n.Files[name]) - } - - default: - panic(fmt.Sprintf("Apply: unexpected node type %T", n)) - } - - if a.post != nil && !a.post(&a.cursor) { - panic(abort) - } - - a.cursor = saved -} - -// An iterator controls iteration over a slice of nodes. -type iterator struct { - index, step int -} - -func (a *application) applyList(parent ast.Node, name string) { - // avoid heap-allocating a new iterator for each applyList call; reuse a.iter instead - saved := a.iter - a.iter.index = 0 - for { - // must reload parent.name each time, since cursor modifications might change it - v := reflect.Indirect(reflect.ValueOf(parent)).FieldByName(name) - if a.iter.index >= v.Len() { - break - } - - // element x may be nil in a bad AST - be cautious - var x ast.Node - if e := v.Index(a.iter.index); e.IsValid() { - x = e.Interface().(ast.Node) - } - - a.iter.step = 1 - a.apply(parent, name, &a.iter, x) - a.iter.index += a.iter.step - } - a.iter = saved -} diff --git a/vendor/golang.org/x/tools/go/ast/astutil/util.go b/vendor/golang.org/x/tools/go/ast/astutil/util.go deleted file mode 100644 index c820b208..00000000 --- a/vendor/golang.org/x/tools/go/ast/astutil/util.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package astutil - -import "go/ast" - -// Unparen returns e with any enclosing parentheses stripped. -// Deprecated: use [ast.Unparen]. -// -//go:fix inline -func Unparen(e ast.Expr) ast.Expr { return ast.Unparen(e) } diff --git a/vendor/golang.org/x/tools/go/ast/edge/edge.go b/vendor/golang.org/x/tools/go/ast/edge/edge.go deleted file mode 100644 index 4f6ccfd6..00000000 --- a/vendor/golang.org/x/tools/go/ast/edge/edge.go +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright 2025 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 edge defines identifiers for each field of an ast.Node -// struct type that refers to another Node. -package edge - -import ( - "fmt" - "go/ast" - "reflect" -) - -// A Kind describes a field of an ast.Node struct. -type Kind uint8 - -// String returns a description of the edge kind. -func (k Kind) String() string { - if k == Invalid { - return "" - } - info := fieldInfos[k] - return fmt.Sprintf("%v.%s", info.nodeType.Elem().Name(), info.name) -} - -// NodeType returns the pointer-to-struct type of the ast.Node implementation. -func (k Kind) NodeType() reflect.Type { return fieldInfos[k].nodeType } - -// FieldName returns the name of the field. -func (k Kind) FieldName() string { return fieldInfos[k].name } - -// FieldType returns the declared type of the field. -func (k Kind) FieldType() reflect.Type { return fieldInfos[k].fieldType } - -// Get returns the direct child of n identified by (k, idx). -// n's type must match k.NodeType(). -// idx must be a valid slice index, or -1 for a non-slice. -func (k Kind) Get(n ast.Node, idx int) ast.Node { - if k.NodeType() != reflect.TypeOf(n) { - panic(fmt.Sprintf("%v.Get(%T): invalid node type", k, n)) - } - v := reflect.ValueOf(n).Elem().Field(fieldInfos[k].index) - if idx != -1 { - v = v.Index(idx) // asserts valid index - } else { - // (The type assertion below asserts that v is not a slice.) - } - return v.Interface().(ast.Node) // may be nil -} - -const ( - Invalid Kind = iota // for nodes at the root of the traversal - - // Kinds are sorted alphabetically. - // Numbering is not stable. - // Each is named Type_Field, where Type is the - // ast.Node struct type and Field is the name of the field - - ArrayType_Elt - ArrayType_Len - AssignStmt_Lhs - AssignStmt_Rhs - BinaryExpr_X - BinaryExpr_Y - BlockStmt_List - BranchStmt_Label - CallExpr_Args - CallExpr_Fun - CaseClause_Body - CaseClause_List - ChanType_Value - CommClause_Body - CommClause_Comm - CommentGroup_List - CompositeLit_Elts - CompositeLit_Type - DeclStmt_Decl - DeferStmt_Call - Ellipsis_Elt - ExprStmt_X - FieldList_List - Field_Comment - Field_Doc - Field_Names - Field_Tag - Field_Type - File_Decls - File_Doc - File_Name - ForStmt_Body - ForStmt_Cond - ForStmt_Init - ForStmt_Post - FuncDecl_Body - FuncDecl_Doc - FuncDecl_Name - FuncDecl_Recv - FuncDecl_Type - FuncLit_Body - FuncLit_Type - FuncType_Params - FuncType_Results - FuncType_TypeParams - GenDecl_Doc - GenDecl_Specs - GoStmt_Call - IfStmt_Body - IfStmt_Cond - IfStmt_Else - IfStmt_Init - ImportSpec_Comment - ImportSpec_Doc - ImportSpec_Name - ImportSpec_Path - IncDecStmt_X - IndexExpr_Index - IndexExpr_X - IndexListExpr_Indices - IndexListExpr_X - InterfaceType_Methods - KeyValueExpr_Key - KeyValueExpr_Value - LabeledStmt_Label - LabeledStmt_Stmt - MapType_Key - MapType_Value - ParenExpr_X - RangeStmt_Body - RangeStmt_Key - RangeStmt_Value - RangeStmt_X - ReturnStmt_Results - SelectStmt_Body - SelectorExpr_Sel - SelectorExpr_X - SendStmt_Chan - SendStmt_Value - SliceExpr_High - SliceExpr_Low - SliceExpr_Max - SliceExpr_X - StarExpr_X - StructType_Fields - SwitchStmt_Body - SwitchStmt_Init - SwitchStmt_Tag - TypeAssertExpr_Type - TypeAssertExpr_X - TypeSpec_Comment - TypeSpec_Doc - TypeSpec_Name - TypeSpec_Type - TypeSpec_TypeParams - TypeSwitchStmt_Assign - TypeSwitchStmt_Body - TypeSwitchStmt_Init - UnaryExpr_X - ValueSpec_Comment - ValueSpec_Doc - ValueSpec_Names - ValueSpec_Type - ValueSpec_Values - - maxKind -) - -// Assert that the encoding fits in 7 bits, -// as the inspector relies on this. -// (We are currently at 104.) -var _ = [1 << 7]struct{}{}[maxKind] - -type fieldInfo struct { - nodeType reflect.Type // pointer-to-struct type of ast.Node implementation - name string - index int - fieldType reflect.Type -} - -func info[N ast.Node](fieldName string) fieldInfo { - nodePtrType := reflect.TypeFor[N]() - f, ok := nodePtrType.Elem().FieldByName(fieldName) - if !ok { - panic(fieldName) - } - return fieldInfo{nodePtrType, fieldName, f.Index[0], f.Type} -} - -var fieldInfos = [...]fieldInfo{ - Invalid: {}, - ArrayType_Elt: info[*ast.ArrayType]("Elt"), - ArrayType_Len: info[*ast.ArrayType]("Len"), - AssignStmt_Lhs: info[*ast.AssignStmt]("Lhs"), - AssignStmt_Rhs: info[*ast.AssignStmt]("Rhs"), - BinaryExpr_X: info[*ast.BinaryExpr]("X"), - BinaryExpr_Y: info[*ast.BinaryExpr]("Y"), - BlockStmt_List: info[*ast.BlockStmt]("List"), - BranchStmt_Label: info[*ast.BranchStmt]("Label"), - CallExpr_Args: info[*ast.CallExpr]("Args"), - CallExpr_Fun: info[*ast.CallExpr]("Fun"), - CaseClause_Body: info[*ast.CaseClause]("Body"), - CaseClause_List: info[*ast.CaseClause]("List"), - ChanType_Value: info[*ast.ChanType]("Value"), - CommClause_Body: info[*ast.CommClause]("Body"), - CommClause_Comm: info[*ast.CommClause]("Comm"), - CommentGroup_List: info[*ast.CommentGroup]("List"), - CompositeLit_Elts: info[*ast.CompositeLit]("Elts"), - CompositeLit_Type: info[*ast.CompositeLit]("Type"), - DeclStmt_Decl: info[*ast.DeclStmt]("Decl"), - DeferStmt_Call: info[*ast.DeferStmt]("Call"), - Ellipsis_Elt: info[*ast.Ellipsis]("Elt"), - ExprStmt_X: info[*ast.ExprStmt]("X"), - FieldList_List: info[*ast.FieldList]("List"), - Field_Comment: info[*ast.Field]("Comment"), - Field_Doc: info[*ast.Field]("Doc"), - Field_Names: info[*ast.Field]("Names"), - Field_Tag: info[*ast.Field]("Tag"), - Field_Type: info[*ast.Field]("Type"), - File_Decls: info[*ast.File]("Decls"), - File_Doc: info[*ast.File]("Doc"), - File_Name: info[*ast.File]("Name"), - ForStmt_Body: info[*ast.ForStmt]("Body"), - ForStmt_Cond: info[*ast.ForStmt]("Cond"), - ForStmt_Init: info[*ast.ForStmt]("Init"), - ForStmt_Post: info[*ast.ForStmt]("Post"), - FuncDecl_Body: info[*ast.FuncDecl]("Body"), - FuncDecl_Doc: info[*ast.FuncDecl]("Doc"), - FuncDecl_Name: info[*ast.FuncDecl]("Name"), - FuncDecl_Recv: info[*ast.FuncDecl]("Recv"), - FuncDecl_Type: info[*ast.FuncDecl]("Type"), - FuncLit_Body: info[*ast.FuncLit]("Body"), - FuncLit_Type: info[*ast.FuncLit]("Type"), - FuncType_Params: info[*ast.FuncType]("Params"), - FuncType_Results: info[*ast.FuncType]("Results"), - FuncType_TypeParams: info[*ast.FuncType]("TypeParams"), - GenDecl_Doc: info[*ast.GenDecl]("Doc"), - GenDecl_Specs: info[*ast.GenDecl]("Specs"), - GoStmt_Call: info[*ast.GoStmt]("Call"), - IfStmt_Body: info[*ast.IfStmt]("Body"), - IfStmt_Cond: info[*ast.IfStmt]("Cond"), - IfStmt_Else: info[*ast.IfStmt]("Else"), - IfStmt_Init: info[*ast.IfStmt]("Init"), - ImportSpec_Comment: info[*ast.ImportSpec]("Comment"), - ImportSpec_Doc: info[*ast.ImportSpec]("Doc"), - ImportSpec_Name: info[*ast.ImportSpec]("Name"), - ImportSpec_Path: info[*ast.ImportSpec]("Path"), - IncDecStmt_X: info[*ast.IncDecStmt]("X"), - IndexExpr_Index: info[*ast.IndexExpr]("Index"), - IndexExpr_X: info[*ast.IndexExpr]("X"), - IndexListExpr_Indices: info[*ast.IndexListExpr]("Indices"), - IndexListExpr_X: info[*ast.IndexListExpr]("X"), - InterfaceType_Methods: info[*ast.InterfaceType]("Methods"), - KeyValueExpr_Key: info[*ast.KeyValueExpr]("Key"), - KeyValueExpr_Value: info[*ast.KeyValueExpr]("Value"), - LabeledStmt_Label: info[*ast.LabeledStmt]("Label"), - LabeledStmt_Stmt: info[*ast.LabeledStmt]("Stmt"), - MapType_Key: info[*ast.MapType]("Key"), - MapType_Value: info[*ast.MapType]("Value"), - ParenExpr_X: info[*ast.ParenExpr]("X"), - RangeStmt_Body: info[*ast.RangeStmt]("Body"), - RangeStmt_Key: info[*ast.RangeStmt]("Key"), - RangeStmt_Value: info[*ast.RangeStmt]("Value"), - RangeStmt_X: info[*ast.RangeStmt]("X"), - ReturnStmt_Results: info[*ast.ReturnStmt]("Results"), - SelectStmt_Body: info[*ast.SelectStmt]("Body"), - SelectorExpr_Sel: info[*ast.SelectorExpr]("Sel"), - SelectorExpr_X: info[*ast.SelectorExpr]("X"), - SendStmt_Chan: info[*ast.SendStmt]("Chan"), - SendStmt_Value: info[*ast.SendStmt]("Value"), - SliceExpr_High: info[*ast.SliceExpr]("High"), - SliceExpr_Low: info[*ast.SliceExpr]("Low"), - SliceExpr_Max: info[*ast.SliceExpr]("Max"), - SliceExpr_X: info[*ast.SliceExpr]("X"), - StarExpr_X: info[*ast.StarExpr]("X"), - StructType_Fields: info[*ast.StructType]("Fields"), - SwitchStmt_Body: info[*ast.SwitchStmt]("Body"), - SwitchStmt_Init: info[*ast.SwitchStmt]("Init"), - SwitchStmt_Tag: info[*ast.SwitchStmt]("Tag"), - TypeAssertExpr_Type: info[*ast.TypeAssertExpr]("Type"), - TypeAssertExpr_X: info[*ast.TypeAssertExpr]("X"), - TypeSpec_Comment: info[*ast.TypeSpec]("Comment"), - TypeSpec_Doc: info[*ast.TypeSpec]("Doc"), - TypeSpec_Name: info[*ast.TypeSpec]("Name"), - TypeSpec_Type: info[*ast.TypeSpec]("Type"), - TypeSpec_TypeParams: info[*ast.TypeSpec]("TypeParams"), - TypeSwitchStmt_Assign: info[*ast.TypeSwitchStmt]("Assign"), - TypeSwitchStmt_Body: info[*ast.TypeSwitchStmt]("Body"), - TypeSwitchStmt_Init: info[*ast.TypeSwitchStmt]("Init"), - UnaryExpr_X: info[*ast.UnaryExpr]("X"), - ValueSpec_Comment: info[*ast.ValueSpec]("Comment"), - ValueSpec_Doc: info[*ast.ValueSpec]("Doc"), - ValueSpec_Names: info[*ast.ValueSpec]("Names"), - ValueSpec_Type: info[*ast.ValueSpec]("Type"), - ValueSpec_Values: info[*ast.ValueSpec]("Values"), -} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go deleted file mode 100644 index 239b10c4..00000000 --- a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go +++ /dev/null @@ -1,551 +0,0 @@ -// Copyright 2025 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 inspector - -import ( - "fmt" - "go/ast" - "go/token" - "iter" - "reflect" - - "golang.org/x/tools/go/ast/edge" -) - -// A Cursor represents an [ast.Node]. It is immutable. -// -// Two Cursors compare equal if they represent the same node. -// -// The zero value of Cursor is not valid. -// -// Call [Inspector.Root] to obtain a cursor for the virtual root node -// of the traversal. This is the sole valid cursor for which [Cursor.Node] -// returns nil. -// -// Use the following methods to navigate efficiently around the tree: -// - for ancestors, use [Cursor.Parent] and [Cursor.Enclosing]; -// - for children, use [Cursor.Child], [Cursor.Children], -// [Cursor.FirstChild], and [Cursor.LastChild]; -// - for siblings, use [Cursor.PrevSibling] and [Cursor.NextSibling]; -// - for descendants, use [Cursor.FindByPos], [Cursor.FindNode], -// [Cursor.Inspect], and [Cursor.Preorder]. -// -// Use the [Cursor.ChildAt] and [Cursor.ParentEdge] methods for -// information about the edges in a tree: which field (and slice -// element) of the parent node holds the child. -type Cursor struct { - in *Inspector - index int32 // index of push node; -1 for virtual root node -} - -// Root returns a valid cursor for the virtual root node, -// whose children are the files provided to [New]. -// -// Its [Cursor.Node] method return nil. -func (in *Inspector) Root() Cursor { - return Cursor{in, -1} -} - -// At returns the cursor at the specified index in the traversal, -// which must have been obtained from [Cursor.Index] on a Cursor -// belonging to the same Inspector (see [Cursor.Inspector]). -func (in *Inspector) At(index int32) Cursor { - if index < 0 { - panic("negative index") - } - if int(index) >= len(in.events) { - panic("index out of range for this inspector") - } - if in.events[index].index < index { - panic("invalid index") // (a push, not a pop) - } - return Cursor{in, index} -} - -// Valid reports whether the cursor is valid. -// The zero value of cursor is invalid. -// Unless otherwise documented, it is not safe to call -// any other method on an invalid cursor. -func (c Cursor) Valid() bool { - return c.in != nil -} - -// Inspector returns the cursor's Inspector. -// It returns nil if the Cursor is not valid. -func (c Cursor) Inspector() *Inspector { return c.in } - -// Index returns the index of this cursor position within the package. -// -// Clients should not assume anything about the numeric Index value -// except that it increases monotonically throughout the traversal. -// It is provided for use with [Inspector.At]. -// -// Index must not be called on the Root node. -func (c Cursor) Index() int32 { - if c.index < 0 { - panic("Index called on Root node") - } - return c.index -} - -// Node returns the node at the current cursor position, -// or nil for the cursor returned by [Inspector.Root]. -func (c Cursor) Node() ast.Node { - if c.index < 0 { - return nil - } - return c.in.events[c.index].node -} - -// String returns information about the cursor's node, if any. -func (c Cursor) String() string { - if !c.Valid() { - return "(invalid)" - } - if c.index < 0 { - return "(root)" - } - return reflect.TypeOf(c.Node()).String() -} - -// indices return the [start, end) half-open interval of event indices. -func (c Cursor) indices() (int32, int32) { - if c.index < 0 { - return 0, int32(len(c.in.events)) // root: all events - } else { - return c.index, c.in.events[c.index].index + 1 // just one subtree - } -} - -// Preorder returns an iterator over the nodes of the subtree -// represented by c in depth-first order. Each node in the sequence is -// represented by a Cursor that allows access to the Node, but may -// also be used to start a new traversal, or to obtain the stack of -// nodes enclosing the cursor. -// -// The traversal sequence is determined by [ast.Inspect]. The types -// argument, if non-empty, enables type-based filtering of events. The -// function f if is called only for nodes whose type matches an -// element of the types slice. -// -// If you need control over descent into subtrees, -// or need both pre- and post-order notifications, use [Cursor.Inspect] -func (c Cursor) Preorder(types ...ast.Node) iter.Seq[Cursor] { - mask := maskOf(types) - - return func(yield func(Cursor) bool) { - events := c.in.events - - for i, limit := c.indices(); i < limit; { - ev := events[i] - if ev.index > i { // push? - if ev.typ&mask != 0 && !yield(Cursor{c.in, i}) { - break - } - pop := ev.index - if events[pop].typ&mask == 0 { - // Subtree does not contain types: skip. - i = pop + 1 - continue - } - } - i++ - } - } -} - -// Inspect visits the nodes of the subtree represented by c in -// depth-first order. It calls f(n) for each node n before it -// visits n's children. If f returns true, Inspect invokes f -// recursively for each of the non-nil children of the node. -// -// Each node is represented by a Cursor that allows access to the -// Node, but may also be used to start a new traversal, or to obtain -// the stack of nodes enclosing the cursor. -// -// The complete traversal sequence is determined by [ast.Inspect]. -// The types argument, if non-empty, enables type-based filtering of -// events. The function f if is called only for nodes whose type -// matches an element of the types slice. -func (c Cursor) Inspect(types []ast.Node, f func(c Cursor) (descend bool)) { - mask := maskOf(types) - events := c.in.events - for i, limit := c.indices(); i < limit; { - ev := events[i] - if ev.index > i { - // push - pop := ev.index - if ev.typ&mask != 0 && !f(Cursor{c.in, i}) || - events[pop].typ&mask == 0 { - // The user opted not to descend, or the - // subtree does not contain types: - // skip past the pop. - i = pop + 1 - continue - } - } - i++ - } -} - -// Enclosing returns an iterator over the nodes enclosing the current -// current node, starting with the Cursor itself. -// -// Enclosing must not be called on the Root node (whose [Cursor.Node] returns nil). -// -// The types argument, if non-empty, enables type-based filtering of -// events: the sequence includes only enclosing nodes whose type -// matches an element of the types slice. -func (c Cursor) Enclosing(types ...ast.Node) iter.Seq[Cursor] { - if c.index < 0 { - panic("Cursor.Enclosing called on Root node") - } - - mask := maskOf(types) - - return func(yield func(Cursor) bool) { - events := c.in.events - for i := c.index; i >= 0; i = events[i].parent { - if events[i].typ&mask != 0 && !yield(Cursor{c.in, i}) { - break - } - } - } -} - -// Parent returns the parent of the current node. -// -// Parent must not be called on the Root node (whose [Cursor.Node] returns nil). -func (c Cursor) Parent() Cursor { - if c.index < 0 { - panic("Cursor.Parent called on Root node") - } - - return Cursor{c.in, c.in.events[c.index].parent} -} - -// ParentEdge returns the identity of the field in the parent node -// that holds this cursor's node, and if it is a list, the index within it. -// -// For example, f(x, y) is a CallExpr whose three children are Idents. -// f has edge kind [edge.CallExpr_Fun] and index -1. -// x and y have kind [edge.CallExpr_Args] and indices 0 and 1, respectively. -// -// If called on a child of the Root node, it returns ([edge.Invalid], -1). -// -// ParentEdge must not be called on the Root node (whose [Cursor.Node] returns nil). -func (c Cursor) ParentEdge() (edge.Kind, int) { - if c.index < 0 { - panic("Cursor.ParentEdge called on Root node") - } - events := c.in.events - pop := events[c.index].index - return unpackEdgeKindAndIndex(events[pop].parent) -} - -// ParentEdgeKind returns the kind component of the result of [Cursor.ParentEdge]. -func (c Cursor) ParentEdgeKind() edge.Kind { - ek, _ := c.ParentEdge() - return ek -} - -// ParentEdgeIndex returns the index component of the result of [Cursor.ParentEdge]. -func (c Cursor) ParentEdgeIndex() int { - _, index := c.ParentEdge() - return index -} - -// ChildAt returns the cursor for the child of the -// current node identified by its edge and index. -// The index must be -1 if the edge.Kind is not a slice. -// The indicated child node must exist. -// -// ChildAt must not be called on the Root node (whose [Cursor.Node] returns nil). -// -// Invariant: c.Parent().ChildAt(c.ParentEdge()) == c. -func (c Cursor) ChildAt(k edge.Kind, idx int) Cursor { - target := packEdgeKindAndIndex(k, idx) - - // Unfortunately there's no shortcut to looping. - events := c.in.events - i := c.index + 1 - for { - pop := events[i].index - if pop < i { - break - } - if events[pop].parent == target { - return Cursor{c.in, i} - } - i = pop + 1 - } - panic(fmt.Sprintf("ChildAt(%v, %d): no such child of %v", k, idx, c)) -} - -// Child returns the cursor for n, which must be a direct child of c's Node. -// -// Child must not be called on the Root node (whose [Cursor.Node] returns nil). -func (c Cursor) Child(n ast.Node) Cursor { - if c.index < 0 { - panic("Cursor.Child called on Root node") - } - - if false { - // reference implementation - for child := range c.Children() { - if child.Node() == n { - return child - } - } - - } else { - // optimized implementation - events := c.in.events - for i := c.index + 1; events[i].index > i; i = events[i].index + 1 { - if events[i].node == n { - return Cursor{c.in, i} - } - } - } - panic(fmt.Sprintf("Child(%T): not a child of %v", n, c)) -} - -// NextSibling returns the cursor for the next sibling node in the same list -// (for example, of files, decls, specs, statements, fields, or expressions) as -// the current node. It returns (zero, false) if the node is the last node in -// the list, or is not part of a list. -// -// NextSibling must not be called on the Root node. -// -// See note at [Cursor.Children]. -func (c Cursor) NextSibling() (Cursor, bool) { - if c.index < 0 { - panic("Cursor.NextSibling called on Root node") - } - - events := c.in.events - i := events[c.index].index + 1 // after corresponding pop - if i < int32(len(events)) { - if events[i].index > i { // push? - return Cursor{c.in, i}, true - } - } - return Cursor{}, false -} - -// PrevSibling returns the cursor for the previous sibling node in the -// same list (for example, of files, decls, specs, statements, fields, -// or expressions) as the current node. It returns zero if the node is -// the first node in the list, or is not part of a list. -// -// It must not be called on the Root node. -// -// See note at [Cursor.Children]. -func (c Cursor) PrevSibling() (Cursor, bool) { - if c.index < 0 { - panic("Cursor.PrevSibling called on Root node") - } - - events := c.in.events - i := c.index - 1 - if i >= 0 { - if j := events[i].index; j < i { // pop? - return Cursor{c.in, j}, true - } - } - return Cursor{}, false -} - -// FirstChild returns the first direct child of the current node, -// or zero if it has no children. -func (c Cursor) FirstChild() (Cursor, bool) { - events := c.in.events - i := c.index + 1 // i=0 if c is root - if i < int32(len(events)) && events[i].index > i { // push? - return Cursor{c.in, i}, true - } - return Cursor{}, false -} - -// LastChild returns the last direct child of the current node, -// or zero if it has no children. -func (c Cursor) LastChild() (Cursor, bool) { - events := c.in.events - if c.index < 0 { // root? - if len(events) > 0 { - // return push of final event (a pop) - return Cursor{c.in, events[len(events)-1].index}, true - } - } else { - j := events[c.index].index - 1 // before corresponding pop - // Inv: j == c.index if c has no children - // or j is last child's pop. - if j > c.index { // c has children - return Cursor{c.in, events[j].index}, true - } - } - return Cursor{}, false -} - -// Children returns an iterator over the direct children of the -// current node, if any. -// -// When using Children, NextChild, and PrevChild, bear in mind that a -// Node's children may come from different fields, some of which may -// be lists of nodes without a distinguished intervening container -// such as [ast.BlockStmt]. -// -// For example, [ast.CaseClause] has a field List of expressions and a -// field Body of statements, so the children of a CaseClause are a mix -// of expressions and statements. Other nodes that have "uncontained" -// list fields include: -// -// - [ast.ValueSpec] (Names, Values) -// - [ast.CompositeLit] (Type, Elts) -// - [ast.IndexListExpr] (X, Indices) -// - [ast.CallExpr] (Fun, Args) -// - [ast.AssignStmt] (Lhs, Rhs) -// -// So, do not assume that the previous sibling of an ast.Stmt is also -// an ast.Stmt, or if it is, that they are executed sequentially, -// unless you have established that, say, its parent is a BlockStmt -// or its [Cursor.ParentEdge] is [edge.BlockStmt_List]. -// For example, given "for S1; ; S2 {}", the predecessor of S2 is S1, -// even though they are not executed in sequence. -func (c Cursor) Children() iter.Seq[Cursor] { - return func(yield func(Cursor) bool) { - c, ok := c.FirstChild() - for ok && yield(c) { - c, ok = c.NextSibling() - } - } -} - -// Contains reports whether c contains or is equal to c2. -// -// Both Cursors must belong to the same [Inspector]; -// neither may be its Root node. -func (c Cursor) Contains(c2 Cursor) bool { - if c.in != c2.in { - panic("different inspectors") - } - events := c.in.events - return c.index <= c2.index && events[c2.index].index <= events[c.index].index -} - -// FindNode returns the cursor for node n if it belongs to the subtree -// rooted at c. It returns zero if n is not found. -func (c Cursor) FindNode(n ast.Node) (Cursor, bool) { - - // FindNode is equivalent to this code, - // but more convenient and 15-20% faster: - if false { - for candidate := range c.Preorder(n) { - if candidate.Node() == n { - return candidate, true - } - } - return Cursor{}, false - } - - // TODO(adonovan): opt: should we assume Node.Pos is accurate - // and combine type-based filtering with position filtering - // like FindByPos? - - mask := maskOf([]ast.Node{n}) - events := c.in.events - - for i, limit := c.indices(); i < limit; i++ { - ev := events[i] - if ev.index > i { // push? - if ev.typ&mask != 0 && ev.node == n { - return Cursor{c.in, i}, true - } - pop := ev.index - if events[pop].typ&mask == 0 { - // Subtree does not contain type of n: skip. - i = pop - } - } - } - return Cursor{}, false -} - -// FindByPos returns the cursor for the innermost node n in the tree -// rooted at c such that n.Pos() <= start && end <= n.End(). -// (For an *ast.File, it uses the bounds n.FileStart-n.FileEnd.) -// -// An empty range (start == end) between two adjacent nodes is -// considered to belong to the first node. -// -// It returns zero if none is found. -// Precondition: start <= end. -// -// See also [astutil.PathEnclosingInterval], which -// tolerates adjoining whitespace. -func (c Cursor) FindByPos(start, end token.Pos) (Cursor, bool) { - if end < start { - panic("end < start") - } - events := c.in.events - - // This algorithm could be implemented using c.Inspect, - // but it is about 2.5x slower. - - // best is the push-index of the latest (=innermost) node containing range. - // (Beware: latest is not always innermost because FuncDecl.{Name,Type} overlap.) - best := int32(-1) - for i, limit := c.indices(); i < limit; i++ { - ev := events[i] - if ev.index > i { // push? - n := ev.node - var nodeEnd token.Pos - if file, ok := n.(*ast.File); ok { - nodeEnd = file.FileEnd - // Note: files may be out of Pos order. - if file.FileStart > start { - i = ev.index // disjoint, after; skip to next file - continue - } - } else { - // Edge case: FuncDecl.Name and .Type overlap: - // Don't update best from Name to FuncDecl.Type. - // - // The condition can be read as: - // - n is FuncType - // - n.parent is FuncDecl - // - best is strictly beneath the FuncDecl - if ev.typ == 1< ev.parent { - continue - } - - nodeEnd = n.End() - if n.Pos() > start { - break // disjoint, after; stop - } - } - - // Inv: node.{Pos,FileStart} <= start - if end <= nodeEnd { - // node fully contains target range - best = i - - // Don't search beyond end of the first match. - // This is important only for an empty range (start=end) - // between two adjoining nodes, which would otherwise - // match both nodes; we want to match only the first. - limit = ev.index - } else if nodeEnd < start { - i = ev.index // disjoint, before; skip forward - } - } - } - if best >= 0 { - return Cursor{c.in, best}, true - } - return Cursor{}, false -} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/inspector.go b/vendor/golang.org/x/tools/go/ast/inspector/inspector.go deleted file mode 100644 index b414d17e..00000000 --- a/vendor/golang.org/x/tools/go/ast/inspector/inspector.go +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2018 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 inspector provides helper functions for traversal over the -// syntax trees of a package, including node filtering by type, and -// materialization of the traversal stack. -// -// During construction, the inspector does a complete traversal and -// builds a list of push/pop events and their node type. Subsequent -// method calls that request a traversal scan this list, rather than walk -// the AST, and perform type filtering using efficient bit sets. -// This representation is sometimes called a "balanced parenthesis tree." -// -// Experiments suggest the inspector's traversals are about 2.5x faster -// than [ast.Inspect], but it may take around 5 traversals for this -// benefit to amortize the inspector's construction cost. -// If efficiency is the primary concern, do not use Inspector for -// one-off traversals. -// -// The [Cursor] type provides a more flexible API for efficient -// navigation of syntax trees in all four "cardinal directions". For -// example, traversals may be nested, so you can find each node of -// type A and then search within it for nodes of type B. Or you can -// traverse from a node to its immediate neighbors: its parent, its -// previous and next sibling, or its first and last child. We -// recommend using methods of Cursor in preference to Inspector where -// possible. -package inspector - -// There are four orthogonal features in a traversal: -// 1 type filtering -// 2 pruning -// 3 postorder calls to f -// 4 stack -// Rather than offer all of them in the API, -// only a few combinations are exposed: -// - Preorder is the fastest and has fewest features, -// but is the most commonly needed traversal. -// - Nodes and WithStack both provide pruning and postorder calls, -// even though few clients need it, because supporting two versions -// is not justified. -// More combinations could be supported by expressing them as -// wrappers around a more generic traversal, but this was measured -// and found to degrade performance significantly (30%). - -import ( - "go/ast" - - "golang.org/x/tools/go/ast/edge" -) - -// An Inspector provides methods for inspecting -// (traversing) the syntax trees of a package. -type Inspector struct { - events []event -} - -func packEdgeKindAndIndex(ek edge.Kind, index int) int32 { - return int32(uint32(index+1)<<7 | uint32(ek)) -} - -// unpackEdgeKindAndIndex unpacks the edge kind and edge index (within -// an []ast.Node slice) from the parent field of a pop event. -func unpackEdgeKindAndIndex(x int32) (edge.Kind, int) { - // The "parent" field of a pop node holds the - // edge Kind in the lower 7 bits and the index+1 - // in the upper 25. - return edge.Kind(x & 0x7f), int(x>>7) - 1 -} - -// New returns an Inspector for the specified syntax trees. -func New(files []*ast.File) *Inspector { - return &Inspector{traverse(files)} -} - -// An event represents a push or a pop -// of an ast.Node during a traversal. -type event struct { - node ast.Node - typ uint64 // typeOf(node) on push event, or union of typ strictly between push and pop events on pop events - index int32 // index of corresponding push or pop event - parent int32 // index of parent's push node (push nodes only), or packed edge kind/index (pop nodes only) -} - -// TODO: Experiment with storing only the second word of event.node (unsafe.Pointer). -// Type can be recovered from the sole bit in typ. -// [Tried this, wasn't faster. --adonovan] - -// Preorder visits all the nodes of the files supplied to [New] in -// depth-first order. It calls f(n) for each node n before it visits -// n's children. -// -// The complete traversal sequence is determined by [ast.Inspect]. -// The types argument, if non-empty, enables type-based filtering of -// events. The function f is called only for nodes whose type -// matches an element of the types slice. -// -// The [Cursor.Preorder] method provides a richer alternative interface. -// Example: -// -// for c := range in.Root().Preorder(types) { ... } -func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) { - // Because it avoids postorder calls to f, and the pruning - // check, Preorder is almost twice as fast as Nodes. The two - // features seem to contribute similar slowdowns (~1.4x each). - - // This function is equivalent to the PreorderSeq call below, - // but to avoid the additional dynamic call (which adds 13-35% - // to the benchmarks), we expand it out. - // - // in.PreorderSeq(types...)(func(n ast.Node) bool { - // f(n) - // return true - // }) - - mask := maskOf(types) - for i := int32(0); i < int32(len(in.events)); { - ev := in.events[i] - if ev.index > i { - // push - if ev.typ&mask != 0 { - f(ev.node) - } - pop := ev.index - if in.events[pop].typ&mask == 0 { - // Subtrees do not contain types: skip them and pop. - i = pop + 1 - continue - } - } - i++ - } -} - -// Nodes visits the nodes of the files supplied to [New] in depth-first -// order. It calls f(n, true) for each node n before it visits n's -// children. If f returns true, Nodes invokes f recursively for each -// of the non-nil children of the node, followed by a call of -// f(n, false). -// -// The complete traversal sequence is determined by [ast.Inspect]. -// The types argument, if non-empty, enables type-based filtering of -// events. The function f if is called only for nodes whose type -// matches an element of the types slice. -// -// The [Cursor.Inspect] method provides a richer alternative interface. -// Example: -// -// in.Root().Inspect(types, func(c Cursor) bool { -// ... -// return true -// } -func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) { - mask := maskOf(types) - for i := int32(0); i < int32(len(in.events)); { - ev := in.events[i] - if ev.index > i { - // push - pop := ev.index - if ev.typ&mask != 0 { - if !f(ev.node, true) { - i = pop + 1 // jump to corresponding pop + 1 - continue - } - } - if in.events[pop].typ&mask == 0 { - // Subtrees do not contain types: skip them. - i = pop - continue - } - } else { - // pop - push := ev.index - if in.events[push].typ&mask != 0 { - f(ev.node, false) - } - } - i++ - } -} - -// WithStack visits nodes in a similar manner to Nodes, but it -// supplies each call to f an additional argument, the current -// traversal stack. The stack's first element is the outermost node, -// an *ast.File; its last is the innermost, n. -// -// The [Cursor.Inspect] method provides a richer alternative interface. -// Example: -// -// in.Root().Inspect(types, func(c Cursor) bool { -// stack := slices.Collect(c.Enclosing()) -// ... -// return true -// }) -func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) { - mask := maskOf(types) - var stack []ast.Node - for i := int32(0); i < int32(len(in.events)); { - ev := in.events[i] - if ev.index > i { - // push - pop := ev.index - stack = append(stack, ev.node) - if ev.typ&mask != 0 { - if !f(ev.node, true, stack) { - i = pop + 1 - stack = stack[:len(stack)-1] - continue - } - } - if in.events[pop].typ&mask == 0 { - // Subtrees does not contain types: skip them. - i = pop - continue - } - } else { - // pop - push := ev.index - if in.events[push].typ&mask != 0 { - f(ev.node, false, stack) - } - stack = stack[:len(stack)-1] - } - i++ - } -} - -// traverse builds the table of events representing a traversal. -func traverse(files []*ast.File) []event { - // Preallocate approximate number of events - // based on source file extent of the declarations. - // (We use End-Pos not FileStart-FileEnd to neglect - // the effect of long doc comments.) - // This makes traverse faster by 4x (!). - var extent int - for _, f := range files { - extent += int(f.End() - f.Pos()) - } - // This estimate is based on the net/http package. - capacity := min(extent*33/100, 1e6) // impose some reasonable maximum (1M) - - v := &visitor{ - events: make([]event, 0, capacity), - stack: []item{{index: -1}}, // include an extra event so file nodes have a parent - } - for _, file := range files { - walk(v, edge.Invalid, -1, file) - } - return v.events -} - -type visitor struct { - events []event - stack []item -} - -type item struct { - index int32 // index of current node's push event - parentIndex int32 // index of parent node's push event - typAccum uint64 // accumulated type bits of current node's descendants - edgeKindAndIndex int32 // edge.Kind and index, bit packed -} - -func (v *visitor) push(ek edge.Kind, eindex int, node ast.Node) { - var ( - index = int32(len(v.events)) - parentIndex = v.stack[len(v.stack)-1].index - ) - v.events = append(v.events, event{ - node: node, - parent: parentIndex, - typ: typeOf(node), - index: 0, // (pop index is set later by visitor.pop) - }) - v.stack = append(v.stack, item{ - index: index, - parentIndex: parentIndex, - edgeKindAndIndex: packEdgeKindAndIndex(ek, eindex), - }) - - // 2B nodes ought to be enough for anyone! - if int32(len(v.events)) < 0 { - panic("event index exceeded int32") - } - - // 32M elements in an []ast.Node ought to be enough for anyone! - if ek2, eindex2 := unpackEdgeKindAndIndex(packEdgeKindAndIndex(ek, eindex)); ek2 != ek || eindex2 != eindex { - panic("Node slice index exceeded uint25") - } -} - -func (v *visitor) pop(node ast.Node) { - top := len(v.stack) - 1 - current := v.stack[top] - - push := &v.events[current.index] - parent := &v.stack[top-1] - - push.index = int32(len(v.events)) // make push event refer to pop - parent.typAccum |= current.typAccum | push.typ // accumulate type bits into parent - - v.stack = v.stack[:top] - - v.events = append(v.events, event{ - node: node, - typ: current.typAccum, - index: current.index, - parent: current.edgeKindAndIndex, // see [unpackEdgeKindAndIndex] - }) -} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/iter.go b/vendor/golang.org/x/tools/go/ast/inspector/iter.go deleted file mode 100644 index b68c553d..00000000 --- a/vendor/golang.org/x/tools/go/ast/inspector/iter.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.23 - -package inspector - -import ( - "go/ast" - "iter" -) - -// PreorderSeq returns an iterator that visits all the -// nodes of the files supplied to [New] in depth-first order. -// It visits each node n before n's children. -// The complete traversal sequence is determined by ast.Inspect. -// -// The types argument, if non-empty, enables type-based filtering: -// only nodes whose type matches an element of the types slice are -// included in the sequence. -// -// Example: -// -// for call := range in.PreorderSeq((*ast.CallExpr)(nil)) { ... } -// -// The [All] function is more convenient if there is exactly one node type: -// -// for call := range All[*ast.CallExpr](in) { ... } -// -// See also the newer and more flexible [Cursor] API, which lets you -// start the traversal at an arbitrary node, and reports each matching -// node by its Cursor, enabling easier navigation. -// The above example would be written thus: -// -// for curCall := range in.Root().Preorder((*ast.CallExpr)(nil)) { -// call := curCall.Node().(*ast.CallExpr) -// ... -// } -func (in *Inspector) PreorderSeq(types ...ast.Node) iter.Seq[ast.Node] { - - // This implementation is identical to Preorder, - // except that it supports breaking out of the loop. - - return func(yield func(ast.Node) bool) { - mask := maskOf(types) - for i := int32(0); i < int32(len(in.events)); { - ev := in.events[i] - if ev.index > i { - // push - if ev.typ&mask != 0 { - if !yield(ev.node) { - break - } - } - pop := ev.index - if in.events[pop].typ&mask == 0 { - // Subtrees do not contain types: skip them and pop. - i = pop + 1 - continue - } - } - i++ - } - } -} - -// All[N] returns an iterator over all the nodes of type N. -// N must be a pointer-to-struct type that implements ast.Node. -// -// Example: -// -// for call := range All[*ast.CallExpr](in) { ... } -// -// See also the newer and more flexible [Cursor] API, which lets you -// start the traversal at an arbitrary node, and reports each matching -// node by its Cursor, enabling easier navigation. -// The above example would be written thus: -// -// for curCall := range in.Root().Preorder((*ast.CallExpr)(nil)) { -// call := curCall.Node().(*ast.CallExpr) -// ... -// } -func All[N interface { - *S - ast.Node -}, S any](in *Inspector) iter.Seq[N] { - - // To avoid additional dynamic call overheads, - // we duplicate rather than call the logic of PreorderSeq. - - mask := typeOf((N)(nil)) - return func(yield func(N) bool) { - for i := int32(0); i < int32(len(in.events)); { - ev := in.events[i] - if ev.index > i { - // push - if ev.typ&mask != 0 { - if !yield(ev.node.(N)) { - break - } - } - pop := ev.index - if in.events[pop].typ&mask == 0 { - // Subtrees do not contain types: skip them and pop. - i = pop + 1 - continue - } - } - i++ - } - } -} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/typeof.go b/vendor/golang.org/x/tools/go/ast/inspector/typeof.go deleted file mode 100644 index 9852331a..00000000 --- a/vendor/golang.org/x/tools/go/ast/inspector/typeof.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2018 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 inspector - -// This file defines func typeOf(ast.Node) uint64. -// -// The initial map-based implementation was too slow; -// see https://go-review.googlesource.com/c/tools/+/135655/1/go/ast/inspector/inspector.go#196 - -import ( - "go/ast" - "math" -) - -const ( - nArrayType = iota - nAssignStmt - nBadDecl - nBadExpr - nBadStmt - nBasicLit - nBinaryExpr - nBlockStmt - nBranchStmt - nCallExpr - nCaseClause - nChanType - nCommClause - nComment - nCommentGroup - nCompositeLit - nDeclStmt - nDeferStmt - nEllipsis - nEmptyStmt - nExprStmt - nField - nFieldList - nFile - nForStmt - nFuncDecl - nFuncLit - nFuncType - nGenDecl - nGoStmt - nIdent - nIfStmt - nImportSpec - nIncDecStmt - nIndexExpr - nIndexListExpr - nInterfaceType - nKeyValueExpr - nLabeledStmt - nMapType - nPackage - nParenExpr - nRangeStmt - nReturnStmt - nSelectStmt - nSelectorExpr - nSendStmt - nSliceExpr - nStarExpr - nStructType - nSwitchStmt - nTypeAssertExpr - nTypeSpec - nTypeSwitchStmt - nUnaryExpr - nValueSpec -) - -// typeOf returns a distinct single-bit value that represents the type of n. -// -// Various implementations were benchmarked with BenchmarkNewInspector: -// -// GOGC=off -// - type switch 4.9-5.5ms 2.1ms -// - binary search over a sorted list of types 5.5-5.9ms 2.5ms -// - linear scan, frequency-ordered list 5.9-6.1ms 2.7ms -// - linear scan, unordered list 6.4ms 2.7ms -// - hash table 6.5ms 3.1ms -// -// A perfect hash seemed like overkill. -// -// The compiler's switch statement is the clear winner -// as it produces a binary tree in code, -// with constant conditions and good branch prediction. -// (Sadly it is the most verbose in source code.) -// Binary search suffered from poor branch prediction. -func typeOf(n ast.Node) uint64 { - // Fast path: nearly half of all nodes are identifiers. - if _, ok := n.(*ast.Ident); ok { - return 1 << nIdent - } - - // These cases include all nodes encountered by ast.Inspect. - switch n.(type) { - case *ast.ArrayType: - return 1 << nArrayType - case *ast.AssignStmt: - return 1 << nAssignStmt - case *ast.BadDecl: - return 1 << nBadDecl - case *ast.BadExpr: - return 1 << nBadExpr - case *ast.BadStmt: - return 1 << nBadStmt - case *ast.BasicLit: - return 1 << nBasicLit - case *ast.BinaryExpr: - return 1 << nBinaryExpr - case *ast.BlockStmt: - return 1 << nBlockStmt - case *ast.BranchStmt: - return 1 << nBranchStmt - case *ast.CallExpr: - return 1 << nCallExpr - case *ast.CaseClause: - return 1 << nCaseClause - case *ast.ChanType: - return 1 << nChanType - case *ast.CommClause: - return 1 << nCommClause - case *ast.Comment: - return 1 << nComment - case *ast.CommentGroup: - return 1 << nCommentGroup - case *ast.CompositeLit: - return 1 << nCompositeLit - case *ast.DeclStmt: - return 1 << nDeclStmt - case *ast.DeferStmt: - return 1 << nDeferStmt - case *ast.Ellipsis: - return 1 << nEllipsis - case *ast.EmptyStmt: - return 1 << nEmptyStmt - case *ast.ExprStmt: - return 1 << nExprStmt - case *ast.Field: - return 1 << nField - case *ast.FieldList: - return 1 << nFieldList - case *ast.File: - return 1 << nFile - case *ast.ForStmt: - return 1 << nForStmt - case *ast.FuncDecl: - return 1 << nFuncDecl - case *ast.FuncLit: - return 1 << nFuncLit - case *ast.FuncType: - return 1 << nFuncType - case *ast.GenDecl: - return 1 << nGenDecl - case *ast.GoStmt: - return 1 << nGoStmt - case *ast.Ident: - return 1 << nIdent - case *ast.IfStmt: - return 1 << nIfStmt - case *ast.ImportSpec: - return 1 << nImportSpec - case *ast.IncDecStmt: - return 1 << nIncDecStmt - case *ast.IndexExpr: - return 1 << nIndexExpr - case *ast.IndexListExpr: - return 1 << nIndexListExpr - case *ast.InterfaceType: - return 1 << nInterfaceType - case *ast.KeyValueExpr: - return 1 << nKeyValueExpr - case *ast.LabeledStmt: - return 1 << nLabeledStmt - case *ast.MapType: - return 1 << nMapType - case *ast.Package: - return 1 << nPackage - case *ast.ParenExpr: - return 1 << nParenExpr - case *ast.RangeStmt: - return 1 << nRangeStmt - case *ast.ReturnStmt: - return 1 << nReturnStmt - case *ast.SelectStmt: - return 1 << nSelectStmt - case *ast.SelectorExpr: - return 1 << nSelectorExpr - case *ast.SendStmt: - return 1 << nSendStmt - case *ast.SliceExpr: - return 1 << nSliceExpr - case *ast.StarExpr: - return 1 << nStarExpr - case *ast.StructType: - return 1 << nStructType - case *ast.SwitchStmt: - return 1 << nSwitchStmt - case *ast.TypeAssertExpr: - return 1 << nTypeAssertExpr - case *ast.TypeSpec: - return 1 << nTypeSpec - case *ast.TypeSwitchStmt: - return 1 << nTypeSwitchStmt - case *ast.UnaryExpr: - return 1 << nUnaryExpr - case *ast.ValueSpec: - return 1 << nValueSpec - } - return 0 -} - -func maskOf(nodes []ast.Node) uint64 { - if len(nodes) == 0 { - return math.MaxUint64 // match all node types - } - var mask uint64 - for _, n := range nodes { - mask |= typeOf(n) - } - return mask -} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/walk.go b/vendor/golang.org/x/tools/go/ast/inspector/walk.go deleted file mode 100644 index 5f1c93c8..00000000 --- a/vendor/golang.org/x/tools/go/ast/inspector/walk.go +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright 2025 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 inspector - -// This file is a fork of ast.Inspect to reduce unnecessary dynamic -// calls and to gather edge information. -// -// Consistency with the original is ensured by TestInspectAllNodes. - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/ast/edge" -) - -func walkList[N ast.Node](v *visitor, ek edge.Kind, list []N) { - for i, node := range list { - walk(v, ek, i, node) - } -} - -func walk(v *visitor, ek edge.Kind, index int, node ast.Node) { - v.push(ek, index, node) - - // walk children - // (the order of the cases matches the order - // of the corresponding node types in ast.go) - switch n := node.(type) { - // Comments and fields - case *ast.Comment: - // nothing to do - - case *ast.CommentGroup: - walkList(v, edge.CommentGroup_List, n.List) - - case *ast.Field: - if n.Doc != nil { - walk(v, edge.Field_Doc, -1, n.Doc) - } - walkList(v, edge.Field_Names, n.Names) - if n.Type != nil { - walk(v, edge.Field_Type, -1, n.Type) - } - if n.Tag != nil { - walk(v, edge.Field_Tag, -1, n.Tag) - } - if n.Comment != nil { - walk(v, edge.Field_Comment, -1, n.Comment) - } - - case *ast.FieldList: - walkList(v, edge.FieldList_List, n.List) - - // Expressions - case *ast.BadExpr, *ast.Ident, *ast.BasicLit: - // nothing to do - - case *ast.Ellipsis: - if n.Elt != nil { - walk(v, edge.Ellipsis_Elt, -1, n.Elt) - } - - case *ast.FuncLit: - walk(v, edge.FuncLit_Type, -1, n.Type) - walk(v, edge.FuncLit_Body, -1, n.Body) - - case *ast.CompositeLit: - if n.Type != nil { - walk(v, edge.CompositeLit_Type, -1, n.Type) - } - walkList(v, edge.CompositeLit_Elts, n.Elts) - - case *ast.ParenExpr: - walk(v, edge.ParenExpr_X, -1, n.X) - - case *ast.SelectorExpr: - walk(v, edge.SelectorExpr_X, -1, n.X) - walk(v, edge.SelectorExpr_Sel, -1, n.Sel) - - case *ast.IndexExpr: - walk(v, edge.IndexExpr_X, -1, n.X) - walk(v, edge.IndexExpr_Index, -1, n.Index) - - case *ast.IndexListExpr: - walk(v, edge.IndexListExpr_X, -1, n.X) - walkList(v, edge.IndexListExpr_Indices, n.Indices) - - case *ast.SliceExpr: - walk(v, edge.SliceExpr_X, -1, n.X) - if n.Low != nil { - walk(v, edge.SliceExpr_Low, -1, n.Low) - } - if n.High != nil { - walk(v, edge.SliceExpr_High, -1, n.High) - } - if n.Max != nil { - walk(v, edge.SliceExpr_Max, -1, n.Max) - } - - case *ast.TypeAssertExpr: - walk(v, edge.TypeAssertExpr_X, -1, n.X) - if n.Type != nil { - walk(v, edge.TypeAssertExpr_Type, -1, n.Type) - } - - case *ast.CallExpr: - walk(v, edge.CallExpr_Fun, -1, n.Fun) - walkList(v, edge.CallExpr_Args, n.Args) - - case *ast.StarExpr: - walk(v, edge.StarExpr_X, -1, n.X) - - case *ast.UnaryExpr: - walk(v, edge.UnaryExpr_X, -1, n.X) - - case *ast.BinaryExpr: - walk(v, edge.BinaryExpr_X, -1, n.X) - walk(v, edge.BinaryExpr_Y, -1, n.Y) - - case *ast.KeyValueExpr: - walk(v, edge.KeyValueExpr_Key, -1, n.Key) - walk(v, edge.KeyValueExpr_Value, -1, n.Value) - - // Types - case *ast.ArrayType: - if n.Len != nil { - walk(v, edge.ArrayType_Len, -1, n.Len) - } - walk(v, edge.ArrayType_Elt, -1, n.Elt) - - case *ast.StructType: - walk(v, edge.StructType_Fields, -1, n.Fields) - - case *ast.FuncType: - if n.TypeParams != nil { - walk(v, edge.FuncType_TypeParams, -1, n.TypeParams) - } - if n.Params != nil { - walk(v, edge.FuncType_Params, -1, n.Params) - } - if n.Results != nil { - walk(v, edge.FuncType_Results, -1, n.Results) - } - - case *ast.InterfaceType: - walk(v, edge.InterfaceType_Methods, -1, n.Methods) - - case *ast.MapType: - walk(v, edge.MapType_Key, -1, n.Key) - walk(v, edge.MapType_Value, -1, n.Value) - - case *ast.ChanType: - walk(v, edge.ChanType_Value, -1, n.Value) - - // Statements - case *ast.BadStmt: - // nothing to do - - case *ast.DeclStmt: - walk(v, edge.DeclStmt_Decl, -1, n.Decl) - - case *ast.EmptyStmt: - // nothing to do - - case *ast.LabeledStmt: - walk(v, edge.LabeledStmt_Label, -1, n.Label) - walk(v, edge.LabeledStmt_Stmt, -1, n.Stmt) - - case *ast.ExprStmt: - walk(v, edge.ExprStmt_X, -1, n.X) - - case *ast.SendStmt: - walk(v, edge.SendStmt_Chan, -1, n.Chan) - walk(v, edge.SendStmt_Value, -1, n.Value) - - case *ast.IncDecStmt: - walk(v, edge.IncDecStmt_X, -1, n.X) - - case *ast.AssignStmt: - walkList(v, edge.AssignStmt_Lhs, n.Lhs) - walkList(v, edge.AssignStmt_Rhs, n.Rhs) - - case *ast.GoStmt: - walk(v, edge.GoStmt_Call, -1, n.Call) - - case *ast.DeferStmt: - walk(v, edge.DeferStmt_Call, -1, n.Call) - - case *ast.ReturnStmt: - walkList(v, edge.ReturnStmt_Results, n.Results) - - case *ast.BranchStmt: - if n.Label != nil { - walk(v, edge.BranchStmt_Label, -1, n.Label) - } - - case *ast.BlockStmt: - walkList(v, edge.BlockStmt_List, n.List) - - case *ast.IfStmt: - if n.Init != nil { - walk(v, edge.IfStmt_Init, -1, n.Init) - } - walk(v, edge.IfStmt_Cond, -1, n.Cond) - walk(v, edge.IfStmt_Body, -1, n.Body) - if n.Else != nil { - walk(v, edge.IfStmt_Else, -1, n.Else) - } - - case *ast.CaseClause: - walkList(v, edge.CaseClause_List, n.List) - walkList(v, edge.CaseClause_Body, n.Body) - - case *ast.SwitchStmt: - if n.Init != nil { - walk(v, edge.SwitchStmt_Init, -1, n.Init) - } - if n.Tag != nil { - walk(v, edge.SwitchStmt_Tag, -1, n.Tag) - } - walk(v, edge.SwitchStmt_Body, -1, n.Body) - - case *ast.TypeSwitchStmt: - if n.Init != nil { - walk(v, edge.TypeSwitchStmt_Init, -1, n.Init) - } - walk(v, edge.TypeSwitchStmt_Assign, -1, n.Assign) - walk(v, edge.TypeSwitchStmt_Body, -1, n.Body) - - case *ast.CommClause: - if n.Comm != nil { - walk(v, edge.CommClause_Comm, -1, n.Comm) - } - walkList(v, edge.CommClause_Body, n.Body) - - case *ast.SelectStmt: - walk(v, edge.SelectStmt_Body, -1, n.Body) - - case *ast.ForStmt: - if n.Init != nil { - walk(v, edge.ForStmt_Init, -1, n.Init) - } - if n.Cond != nil { - walk(v, edge.ForStmt_Cond, -1, n.Cond) - } - if n.Post != nil { - walk(v, edge.ForStmt_Post, -1, n.Post) - } - walk(v, edge.ForStmt_Body, -1, n.Body) - - case *ast.RangeStmt: - if n.Key != nil { - walk(v, edge.RangeStmt_Key, -1, n.Key) - } - if n.Value != nil { - walk(v, edge.RangeStmt_Value, -1, n.Value) - } - walk(v, edge.RangeStmt_X, -1, n.X) - walk(v, edge.RangeStmt_Body, -1, n.Body) - - // Declarations - case *ast.ImportSpec: - if n.Doc != nil { - walk(v, edge.ImportSpec_Doc, -1, n.Doc) - } - if n.Name != nil { - walk(v, edge.ImportSpec_Name, -1, n.Name) - } - walk(v, edge.ImportSpec_Path, -1, n.Path) - if n.Comment != nil { - walk(v, edge.ImportSpec_Comment, -1, n.Comment) - } - - case *ast.ValueSpec: - if n.Doc != nil { - walk(v, edge.ValueSpec_Doc, -1, n.Doc) - } - walkList(v, edge.ValueSpec_Names, n.Names) - if n.Type != nil { - walk(v, edge.ValueSpec_Type, -1, n.Type) - } - walkList(v, edge.ValueSpec_Values, n.Values) - if n.Comment != nil { - walk(v, edge.ValueSpec_Comment, -1, n.Comment) - } - - case *ast.TypeSpec: - if n.Doc != nil { - walk(v, edge.TypeSpec_Doc, -1, n.Doc) - } - walk(v, edge.TypeSpec_Name, -1, n.Name) - if n.TypeParams != nil { - walk(v, edge.TypeSpec_TypeParams, -1, n.TypeParams) - } - walk(v, edge.TypeSpec_Type, -1, n.Type) - if n.Comment != nil { - walk(v, edge.TypeSpec_Comment, -1, n.Comment) - } - - case *ast.BadDecl: - // nothing to do - - case *ast.GenDecl: - if n.Doc != nil { - walk(v, edge.GenDecl_Doc, -1, n.Doc) - } - walkList(v, edge.GenDecl_Specs, n.Specs) - - case *ast.FuncDecl: - if n.Doc != nil { - walk(v, edge.FuncDecl_Doc, -1, n.Doc) - } - if n.Recv != nil { - walk(v, edge.FuncDecl_Recv, -1, n.Recv) - } - walk(v, edge.FuncDecl_Name, -1, n.Name) - walk(v, edge.FuncDecl_Type, -1, n.Type) - if n.Body != nil { - walk(v, edge.FuncDecl_Body, -1, n.Body) - } - - case *ast.File: - if n.Doc != nil { - walk(v, edge.File_Doc, -1, n.Doc) - } - walk(v, edge.File_Name, -1, n.Name) - walkList(v, edge.File_Decls, n.Decls) - // don't walk n.Comments - they have been - // visited already through the individual - // nodes - - default: - // (includes *ast.Package) - panic(fmt.Sprintf("Walk: unexpected node type %T", n)) - } - - v.pop(node) -} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go deleted file mode 100644 index 7b90bc92..00000000 --- a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package gcexportdata provides functions for reading and writing -// export data, which is a serialized description of the API of a Go -// package including the names, kinds, types, and locations of all -// exported declarations. -// -// The standard Go compiler (cmd/compile) writes an export data file -// for each package it compiles, which it later reads when compiling -// packages that import the earlier one. The compiler must thus -// contain logic to both write and read export data. -// (See the "Export" section in the cmd/compile/README file.) -// -// The [Read] function in this package can read files produced by the -// compiler, producing [go/types] data structures. As a matter of -// policy, Read supports export data files produced by only the last -// two Go releases plus tip; see https://go.dev/issue/68898. The -// export data files produced by the compiler contain additional -// details related to generics, inlining, and other optimizations that -// cannot be decoded by the [Read] function. -// -// In files written by the compiler, the export data is not at the -// start of the file. Before calling Read, use [NewReader] to locate -// the desired portion of the file. -// -// The [Write] function in this package encodes the exported API of a -// Go package ([types.Package]) as a file. Such files can be later -// decoded by Read, but cannot be consumed by the compiler. -// -// # Future changes -// -// Although Read supports the formats written by both Write and the -// compiler, the two are quite different, and there is an open -// proposal (https://go.dev/issue/69491) to separate these APIs. -// -// Under that proposal, this package would ultimately provide only the -// Read operation for compiler export data, which must be defined in -// this module (golang.org/x/tools), not in the standard library, to -// avoid version skew for developer tools that need to read compiler -// export data both before and after a Go release, such as from Go -// 1.23 to Go 1.24. Because this package lives in the tools module, -// clients can update their version of the module some time before the -// Go 1.24 release and rebuild and redeploy their tools, which will -// then be able to consume both Go 1.23 and Go 1.24 export data files, -// so they will work before and after the Go update. (See discussion -// at https://go.dev/issue/15651.) -// -// The operations to import and export [go/types] data structures -// would be defined in the go/types package as Import and Export. -// [Write] would (eventually) delegate to Export, -// and [Read], when it detects a file produced by Export, -// would delegate to Import. -// -// # Deprecations -// -// The [NewImporter] and [Find] functions are deprecated and should -// not be used in new code. The [WriteBundle] and [ReadBundle] -// functions are experimental, and there is an open proposal to -// deprecate them (https://go.dev/issue/69573). -package gcexportdata - -import ( - "bufio" - "bytes" - "encoding/json" - "fmt" - "go/token" - "go/types" - "io" - "os/exec" - - "golang.org/x/tools/internal/gcimporter" -) - -// Find returns the name of an object (.o) or archive (.a) file -// containing type information for the specified import path, -// using the go command. -// If no file was found, an empty filename is returned. -// -// A relative srcDir is interpreted relative to the current working directory. -// -// Find also returns the package's resolved (canonical) import path, -// reflecting the effects of srcDir and vendoring on importPath. -// -// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, -// which is more efficient. -func Find(importPath, srcDir string) (filename, path string) { - cmd := exec.Command("go", "list", "-json", "-export", "--", importPath) - cmd.Dir = srcDir - out, err := cmd.Output() - if err != nil { - return "", "" - } - var data struct { - ImportPath string - Export string - } - json.Unmarshal(out, &data) - return data.Export, data.ImportPath -} - -// NewReader returns a reader for the export data section of an object -// (.o) or archive (.a) file read from r. The new reader may provide -// additional trailing data beyond the end of the export data. -func NewReader(r io.Reader) (io.Reader, error) { - buf := bufio.NewReader(r) - size, err := gcimporter.FindExportData(buf) - if err != nil { - return nil, err - } - - // We were given an archive and found the __.PKGDEF in it. - // This tells us the size of the export data, and we don't - // need to return the entire file. - return &io.LimitedReader{ - R: buf, - N: size, - }, nil -} - -// readAll works the same way as io.ReadAll, but avoids allocations and copies -// by preallocating a byte slice of the necessary size if the size is known up -// front. This is always possible when the input is an archive. In that case, -// NewReader will return the known size using an io.LimitedReader. -func readAll(r io.Reader) ([]byte, error) { - if lr, ok := r.(*io.LimitedReader); ok { - data := make([]byte, lr.N) - _, err := io.ReadFull(lr, data) - return data, err - } - return io.ReadAll(r) -} - -// Read reads export data from in, decodes it, and returns type -// information for the package. -// -// Read is capable of reading export data produced by [Write] at the -// same source code version, or by the last two Go releases (plus tip) -// of the standard Go compiler. Reading files from older compilers may -// produce an error. -// -// The package path (effectively its linker symbol prefix) is -// specified by path, since unlike the package name, this information -// may not be recorded in the export data. -// -// File position information is added to fset. -// -// Read may inspect and add to the imports map to ensure that references -// within the export data to other packages are consistent. The caller -// must ensure that imports[path] does not exist, or exists but is -// incomplete (see types.Package.Complete), and Read inserts the -// resulting package into this map entry. -// -// On return, the state of the reader is undefined. -func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { - data, err := readAll(in) - if err != nil { - return nil, fmt.Errorf("reading export data for %q: %v", path, err) - } - - if bytes.HasPrefix(data, []byte("!")) { - return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path) - } - - // The indexed export format starts with an 'i'; the older - // binary export format starts with a 'c', 'd', or 'v' - // (from "version"). Select appropriate importer. - if len(data) > 0 { - switch data[0] { - case 'v', 'c', 'd': - // binary, produced by cmd/compile till go1.10 - return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0]) - - case 'i': - // indexed, produced by cmd/compile till go1.19, - // and also by [Write]. - // - // If proposal #69491 is accepted, go/types - // serialization will be implemented by - // types.Export, to which Write would eventually - // delegate (explicitly dropping any pretence at - // inter-version Write-Read compatibility). - // This [Read] function would delegate to types.Import - // when it detects that the file was produced by Export. - _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) - return pkg, err - - case 'u': - // unified, produced by cmd/compile since go1.20 - _, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path) - return pkg, err - - default: - l := min(len(data), 10) - return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path) - } - } - return nil, fmt.Errorf("empty export data for %s", path) -} - -// Write writes encoded type information for the specified package to out. -// The FileSet provides file position information for named objects. -func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { - if _, err := io.WriteString(out, "i"); err != nil { - return err - } - return gcimporter.IExportData(out, fset, pkg) -} - -// ReadBundle reads an export bundle from in, decodes it, and returns type -// information for the packages. -// File position information is added to fset. -// -// ReadBundle may inspect and add to the imports map to ensure that references -// within the export bundle to other packages are consistent. -// -// On return, the state of the reader is undefined. -// -// Experimental: This API is experimental and may change in the future. -func ReadBundle(in io.Reader, fset *token.FileSet, imports map[string]*types.Package) ([]*types.Package, error) { - data, err := readAll(in) - if err != nil { - return nil, fmt.Errorf("reading export bundle: %v", err) - } - return gcimporter.IImportBundle(fset, imports, data) -} - -// WriteBundle writes encoded type information for the specified packages to out. -// The FileSet provides file position information for named objects. -// -// Experimental: This API is experimental and may change in the future. -func WriteBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { - return gcimporter.IExportBundle(out, fset, pkgs) -} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go deleted file mode 100644 index 37a7247e..00000000 --- a/vendor/golang.org/x/tools/go/gcexportdata/importer.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gcexportdata - -import ( - "fmt" - "go/token" - "go/types" - "os" -) - -// NewImporter returns a new instance of the types.Importer interface -// that reads type information from export data files written by gc. -// The Importer also satisfies types.ImporterFrom. -// -// Export data files are located using "go build" workspace conventions -// and the build.Default context. -// -// Use this importer instead of go/importer.For("gc", ...) to avoid the -// version-skew problems described in the documentation of this package, -// or to control the FileSet or access the imports map populated during -// package loading. -// -// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, -// which is more efficient. -func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { - return importer{fset, imports} -} - -type importer struct { - fset *token.FileSet - imports map[string]*types.Package -} - -func (imp importer) Import(importPath string) (*types.Package, error) { - return imp.ImportFrom(importPath, "", 0) -} - -func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { - filename, path := Find(importPath, srcDir) - if filename == "" { - if importPath == "unsafe" { - // Even for unsafe, call Find first in case - // the package was vendored. - return types.Unsafe, nil - } - return nil, fmt.Errorf("can't find import: %s", importPath) - } - - if pkg, ok := imp.imports[path]; ok && pkg.Complete() { - return pkg, nil // cache hit - } - - // open file - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer func() { - f.Close() - if err != nil { - // add file name to error - err = fmt.Errorf("reading export data: %s: %v", filename, err) - } - }() - - r, err := NewReader(f) - if err != nil { - return nil, err - } - - return Read(r, imp.fset, imp.imports, path) -} diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go deleted file mode 100644 index 366aab6b..00000000 --- a/vendor/golang.org/x/tools/go/packages/doc.go +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright 2018 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 packages loads Go packages for inspection and analysis. - -The [Load] function takes as input a list of patterns and returns a -list of [Package] values describing individual packages matched by those -patterns. -A [Config] specifies configuration options, the most important of which is -the [LoadMode], which controls the amount of detail in the loaded packages. - -Load passes most patterns directly to the underlying build tool. -The default build tool is the go command. -Its supported patterns are described at -https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns. -Other build systems may be supported by providing a "driver"; -see [The driver protocol]. - -All patterns with the prefix "query=", where query is a -non-empty string of letters from [a-z], are reserved and may be -interpreted as query operators. - -Two query operators are currently supported: "file" and "pattern". - -The query "file=path/to/file.go" matches the package or packages enclosing -the Go source file path/to/file.go. For example "file=~/go/src/fmt/print.go" -might return the packages "fmt" and "fmt [fmt.test]". - -The query "pattern=string" causes "string" to be passed directly to -the underlying build tool. In most cases this is unnecessary, -but an application can use Load("pattern=" + x) as an escaping mechanism -to ensure that x is not interpreted as a query operator if it contains '='. - -All other query operators are reserved for future use and currently -cause Load to report an error. - -The Package struct provides basic information about the package, including - - - ID, a unique identifier for the package in the returned set; - - GoFiles, the names of the package's Go source files; - - Imports, a map from source import strings to the Packages they name; - - Types, the type information for the package's exported symbols; - - Syntax, the parsed syntax trees for the package's source code; and - - TypesInfo, the result of a complete type-check of the package syntax trees. - -(See the documentation for type Package for the complete list of fields -and more detailed descriptions.) - -For example, - - Load(nil, "bytes", "unicode...") - -returns four Package structs describing the standard library packages -bytes, unicode, unicode/utf16, and unicode/utf8. Note that one pattern -can match multiple packages and that a package might be matched by -multiple patterns: in general it is not possible to determine which -packages correspond to which patterns. - -Note that the list returned by Load contains only the packages matched -by the patterns. Their dependencies can be found by walking the import -graph using the Imports fields. - -The Load function can be configured by passing a pointer to a Config as -the first argument. A nil Config is equivalent to the zero Config, which -causes Load to run in [LoadFiles] mode, collecting minimal information. -See the documentation for type Config for details. - -As noted earlier, the Config.Mode controls the amount of detail -reported about the loaded packages. See the documentation for type LoadMode -for details. - -Most tools should pass their command-line arguments (after any flags) -uninterpreted to Load, so that it can interpret them -according to the conventions of the underlying build system. - -See the Example function for typical usage. -See also [golang.org/x/tools/go/packages/internal/linecount] -for an example application. - -# The driver protocol - -Load may be used to load Go packages even in Go projects that use -alternative build systems, by installing an appropriate "driver" -program for the build system and specifying its location in the -GOPACKAGESDRIVER environment variable. -For example, -https://github.com/bazelbuild/rules_go/wiki/Editor-and-tool-integration -explains how to use the driver for Bazel. - -The driver program is responsible for interpreting patterns in its -preferred notation and reporting information about the packages that -those patterns identify. Drivers must also support the special "file=" -and "pattern=" patterns described above. - -The patterns are provided as positional command-line arguments. A -JSON-encoded [DriverRequest] message providing additional information -is written to the driver's standard input. The driver must write a -JSON-encoded [DriverResponse] message to its standard output. (This -message differs from the JSON schema produced by 'go list'.) - -The value of the PWD environment variable seen by the driver process -is the preferred name of its working directory. (The working directory -may have other aliases due to symbolic links; see the comment on the -Dir field of [exec.Cmd] for related information.) -When the driver process emits in its response the name of a file -that is a descendant of this directory, it must use an absolute path -that has the value of PWD as a prefix, to ensure that the returned -filenames satisfy the original query. -*/ -package packages // import "golang.org/x/tools/go/packages" - -/* - -Motivation and design considerations - -The new package's design solves problems addressed by two existing -packages: go/build, which locates and describes packages, and -golang.org/x/tools/go/loader, which loads, parses and type-checks them. -The go/build.Package structure encodes too much of the 'go build' way -of organizing projects, leaving us in need of a data type that describes a -package of Go source code independent of the underlying build system. -We wanted something that works equally well with go build and vgo, and -also other build systems such as Bazel and Blaze, making it possible to -construct analysis tools that work in all these environments. -Tools such as errcheck and staticcheck were essentially unavailable to -the Go community at Google, and some of Google's internal tools for Go -are unavailable externally. -This new package provides a uniform way to obtain package metadata by -querying each of these build systems, optionally supporting their -preferred command-line notations for packages, so that tools integrate -neatly with users' build environments. The Metadata query function -executes an external query tool appropriate to the current workspace. - -Loading packages always returns the complete import graph "all the way down", -even if all you want is information about a single package, because the query -mechanisms of all the build systems we currently support ({go,vgo} list, and -blaze/bazel aspect-based query) cannot provide detailed information -about one package without visiting all its dependencies too, so there is -no additional asymptotic cost to providing transitive information. -(This property might not be true of a hypothetical 5th build system.) - -In calls to TypeCheck, all initial packages, and any package that -transitively depends on one of them, must be loaded from source. -Consider A->B->C->D->E: if A,C are initial, A,B,C must be loaded from -source; D may be loaded from export data, and E may not be loaded at all -(though it's possible that D's export data mentions it, so a -types.Package may be created for it and exposed.) - -The old loader had a feature to suppress type-checking of function -bodies on a per-package basis, primarily intended to reduce the work of -obtaining type information for imported packages. Now that imports are -satisfied by export data, the optimization no longer seems necessary. - -Despite some early attempts, the old loader did not exploit export data, -instead always using the equivalent of WholeProgram mode. This was due -to the complexity of mixing source and export data packages (now -resolved by the upward traversal mentioned above), and because export data -files were nearly always missing or stale. Now that 'go build' supports -caching, all the underlying build systems can guarantee to produce -export data in a reasonable (amortized) time. - -Test "main" packages synthesized by the build system are now reported as -first-class packages, avoiding the need for clients (such as go/ssa) to -reinvent this generation logic. - -One way in which go/packages is simpler than the old loader is in its -treatment of in-package tests. In-package tests are packages that -consist of all the files of the library under test, plus the test files. -The old loader constructed in-package tests by a two-phase process of -mutation called "augmentation": first it would construct and type check -all the ordinary library packages and type-check the packages that -depend on them; then it would add more (test) files to the package and -type-check again. This two-phase approach had four major problems: -1) in processing the tests, the loader modified the library package, - leaving no way for a client application to see both the test - package and the library package; one would mutate into the other. -2) because test files can declare additional methods on types defined in - the library portion of the package, the dispatch of method calls in - the library portion was affected by the presence of the test files. - This should have been a clue that the packages were logically - different. -3) this model of "augmentation" assumed at most one in-package test - per library package, which is true of projects using 'go build', - but not other build systems. -4) because of the two-phase nature of test processing, all packages that - import the library package had to be processed before augmentation, - forcing a "one-shot" API and preventing the client from calling Load - in several times in sequence as is now possible in WholeProgram mode. - (TypeCheck mode has a similar one-shot restriction for a different reason.) - -Early drafts of this package supported "multi-shot" operation. -Although it allowed clients to make a sequence of calls (or concurrent -calls) to Load, building up the graph of Packages incrementally, -it was of marginal value: it complicated the API -(since it allowed some options to vary across calls but not others), -it complicated the implementation, -it cannot be made to work in Types mode, as explained above, -and it was less efficient than making one combined call (when this is possible). -Among the clients we have inspected, none made multiple calls to load -but could not be easily and satisfactorily modified to make only a single call. -However, applications changes may be required. -For example, the ssadump command loads the user-specified packages -and in addition the runtime package. It is tempting to simply append -"runtime" to the user-provided list, but that does not work if the user -specified an ad-hoc package such as [a.go b.go]. -Instead, ssadump no longer requests the runtime package, -but seeks it among the dependencies of the user-specified packages, -and emits an error if it is not found. - -Questions & Tasks - -- Add GOARCH/GOOS? - They are not portable concepts, but could be made portable. - Our goal has been to allow users to express themselves using the conventions - of the underlying build system: if the build system honors GOARCH - during a build and during a metadata query, then so should - applications built atop that query mechanism. - Conversely, if the target architecture of the build is determined by - command-line flags, the application can pass the relevant - flags through to the build system using a command such as: - myapp -query_flag="--cpu=amd64" -query_flag="--os=darwin" - However, this approach is low-level, unwieldy, and non-portable. - GOOS and GOARCH seem important enough to warrant a dedicated option. - -- How should we handle partial failures such as a mixture of good and - malformed patterns, existing and non-existent packages, successful and - failed builds, import failures, import cycles, and so on, in a call to - Load? - -- Support bazel, blaze, and go1.10 list, not just go1.11 list. - -- Handle (and test) various partial success cases, e.g. - a mixture of good packages and: - invalid patterns - nonexistent packages - empty packages - packages with malformed package or import declarations - unreadable files - import cycles - other parse errors - type errors - Make sure we record errors at the correct place in the graph. - -- Missing packages among initial arguments are not reported. - Return bogus packages for them, like golist does. - -- "undeclared name" errors (for example) are reported out of source file - order. I suspect this is due to the breadth-first resolution now used - by go/types. Is that a bug? Discuss with gri. - -*/ diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go deleted file mode 100644 index f37bc651..00000000 --- a/vendor/golang.org/x/tools/go/packages/external.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2018 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 packages - -// This file defines the protocol that enables an external "driver" -// tool to supply package metadata in place of 'go list'. - -import ( - "bytes" - "encoding/json" - "fmt" - "os" - "os/exec" - "slices" - "strings" -) - -// DriverRequest defines the schema of a request for package metadata -// from an external driver program. The JSON-encoded DriverRequest -// message is provided to the driver program's standard input. The -// query patterns are provided as command-line arguments. -// -// See the package documentation for an overview. -type DriverRequest struct { - Mode LoadMode `json:"mode"` - - // Env specifies the environment the underlying build system should be run in. - Env []string `json:"env"` - - // BuildFlags are flags that should be passed to the underlying build system. - BuildFlags []string `json:"build_flags"` - - // Tests specifies whether the patterns should also return test packages. - Tests bool `json:"tests"` - - // Overlay maps file paths (relative to the driver's working directory) - // to the contents of overlay files (see Config.Overlay). - Overlay map[string][]byte `json:"overlay"` -} - -// DriverResponse defines the schema of a response from an external -// driver program, providing the results of a query for package -// metadata. The driver program must write a JSON-encoded -// DriverResponse message to its standard output. -// -// See the package documentation for an overview. -type DriverResponse struct { - // NotHandled is returned if the request can't be handled by the current - // driver. If an external driver returns a response with NotHandled, the - // rest of the DriverResponse is ignored, and go/packages will fallback - // to the next driver. If go/packages is extended in the future to support - // lists of multiple drivers, go/packages will fall back to the next driver. - NotHandled bool - - // Compiler and Arch are the arguments pass of types.SizesFor - // to get a types.Sizes to use when type checking. - Compiler string - Arch string - - // Roots is the set of package IDs that make up the root packages. - // We have to encode this separately because when we encode a single package - // we cannot know if it is one of the roots as that requires knowledge of the - // graph it is part of. - Roots []string `json:",omitempty"` - - // Packages is the full set of packages in the graph. - // The packages are not connected into a graph. - // The Imports if populated will be stubs that only have their ID set. - // Imports will be connected and then type and syntax information added in a - // later pass (see refine). - Packages []*Package - - // GoVersion is the minor version number used by the driver - // (e.g. the go command on the PATH) when selecting .go files. - // Zero means unknown. - GoVersion int -} - -// driver is the type for functions that query the build system for the -// packages named by the patterns. -type driver func(cfg *Config, patterns []string) (*DriverResponse, error) - -// findExternalDriver returns the file path of a tool that supplies -// the build system package structure, or "" if not found. -// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its -// value, otherwise it searches for a binary named gopackagesdriver on the PATH. -func findExternalDriver(cfg *Config) driver { - const toolPrefix = "GOPACKAGESDRIVER=" - tool := "" - for _, env := range cfg.Env { - if val, ok := strings.CutPrefix(env, toolPrefix); ok { - tool = val - } - } - if tool != "" && tool == "off" { - return nil - } - if tool == "" { - var err error - tool, err = exec.LookPath("gopackagesdriver") - if err != nil { - return nil - } - } - return func(cfg *Config, patterns []string) (*DriverResponse, error) { - req, err := json.Marshal(DriverRequest{ - Mode: cfg.Mode, - Env: cfg.Env, - BuildFlags: cfg.BuildFlags, - Tests: cfg.Tests, - Overlay: cfg.Overlay, - }) - if err != nil { - return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) - } - - buf := new(bytes.Buffer) - stderr := new(bytes.Buffer) - cmd := exec.CommandContext(cfg.Context, tool, patterns...) - cmd.Dir = cfg.Dir - // The cwd gets resolved to the real path. On Darwin, where - // /tmp is a symlink, this breaks anything that expects the - // working directory to keep the original path, including the - // go command when dealing with modules. - // - // os.Getwd stdlib has a special feature where if the - // cwd and the PWD are the same node then it trusts - // the PWD, so by setting it in the env for the child - // process we fix up all the paths returned by the go - // command. - // - // (See similar trick in Invocation.run in ../../internal/gocommand/invoke.go) - cmd.Env = append(slices.Clip(cfg.Env), "PWD="+cfg.Dir) - cmd.Stdin = bytes.NewReader(req) - cmd.Stdout = buf - cmd.Stderr = stderr - - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) - } - if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" { - fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr) - } - - var response DriverResponse - if err := json.Unmarshal(buf.Bytes(), &response); err != nil { - return nil, err - } - return &response, nil - } -} diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go deleted file mode 100644 index a6c17cf6..00000000 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ /dev/null @@ -1,1117 +0,0 @@ -// Copyright 2018 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 packages - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "log" - "os" - "os/exec" - "path" - "path/filepath" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "unicode" - - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/packagesinternal" -) - -// debug controls verbose logging. -var debug, _ = strconv.ParseBool(os.Getenv("GOPACKAGESDEBUG")) - -// A goTooOldError reports that the go command -// found by exec.LookPath is too old to use the new go list behavior. -type goTooOldError struct { - error -} - -// responseDeduper wraps a DriverResponse, deduplicating its contents. -type responseDeduper struct { - seenRoots map[string]bool - seenPackages map[string]*Package - dr *DriverResponse -} - -func newDeduper() *responseDeduper { - return &responseDeduper{ - dr: &DriverResponse{}, - seenRoots: map[string]bool{}, - seenPackages: map[string]*Package{}, - } -} - -// addAll fills in r with a DriverResponse. -func (r *responseDeduper) addAll(dr *DriverResponse) { - for _, pkg := range dr.Packages { - r.addPackage(pkg) - } - for _, root := range dr.Roots { - r.addRoot(root) - } - r.dr.GoVersion = dr.GoVersion -} - -func (r *responseDeduper) addPackage(p *Package) { - if prev := r.seenPackages[p.ID]; prev != nil { - // Package already seen in a previous response. Merge the file lists, - // removing duplicates. This can happen when the same package appears - // in multiple driver responses that are being merged together. - prev.GoFiles = appendUniqueStrings(prev.GoFiles, p.GoFiles) - prev.CompiledGoFiles = appendUniqueStrings(prev.CompiledGoFiles, p.CompiledGoFiles) - prev.OtherFiles = appendUniqueStrings(prev.OtherFiles, p.OtherFiles) - prev.IgnoredFiles = appendUniqueStrings(prev.IgnoredFiles, p.IgnoredFiles) - prev.EmbedFiles = appendUniqueStrings(prev.EmbedFiles, p.EmbedFiles) - prev.EmbedPatterns = appendUniqueStrings(prev.EmbedPatterns, p.EmbedPatterns) - return - } - r.seenPackages[p.ID] = p - r.dr.Packages = append(r.dr.Packages, p) -} - -// appendUniqueStrings appends elements from src to dst, skipping duplicates. -func appendUniqueStrings(dst, src []string) []string { - if len(src) == 0 { - return dst - } - - seen := make(map[string]bool, len(dst)) - for _, s := range dst { - seen[s] = true - } - - for _, s := range src { - if !seen[s] { - dst = append(dst, s) - } - } - - return dst -} - -func (r *responseDeduper) addRoot(id string) { - if r.seenRoots[id] { - return - } - r.seenRoots[id] = true - r.dr.Roots = append(r.dr.Roots, id) -} - -type golistState struct { - cfg *Config - ctx context.Context - - runner *gocommand.Runner - - // overlay is the JSON file that encodes the Config.Overlay - // mapping, used by 'go list -overlay=...'. - overlay string - - envOnce sync.Once - goEnvError error - goEnv map[string]string - - rootsOnce sync.Once - rootDirsError error - rootDirs map[string]string - - goVersionOnce sync.Once - goVersionError error - goVersion int // The X in Go 1.X. - - // vendorDirs caches the (non)existence of vendor directories. - vendorDirs map[string]bool -} - -// getEnv returns Go environment variables. Only specific variables are -// populated -- computing all of them is slow. -func (state *golistState) getEnv() (map[string]string, error) { - state.envOnce.Do(func() { - var b *bytes.Buffer - b, state.goEnvError = state.invokeGo("env", "-json", "GOMOD", "GOPATH") - if state.goEnvError != nil { - return - } - - state.goEnv = make(map[string]string) - decoder := json.NewDecoder(b) - if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil { - return - } - }) - return state.goEnv, state.goEnvError -} - -// mustGetEnv is a convenience function that can be used if getEnv has already succeeded. -func (state *golistState) mustGetEnv() map[string]string { - env, err := state.getEnv() - if err != nil { - panic(fmt.Sprintf("mustGetEnv: %v", err)) - } - return env -} - -// goListDriver uses the go list command to interpret the patterns and produce -// the build system package structure. -// See driver for more details. -// -// overlay is the JSON file that encodes the cfg.Overlay -// mapping, used by 'go list -overlay=...' -func goListDriver(cfg *Config, runner *gocommand.Runner, overlay string, patterns []string) (_ *DriverResponse, err error) { - // Make sure that any asynchronous go commands are killed when we return. - parentCtx := cfg.Context - if parentCtx == nil { - parentCtx = context.Background() - } - ctx, cancel := context.WithCancel(parentCtx) - defer cancel() - - response := newDeduper() - - state := &golistState{ - cfg: cfg, - ctx: ctx, - vendorDirs: map[string]bool{}, - overlay: overlay, - runner: runner, - } - - // Fill in response.Sizes asynchronously if necessary. - if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 { - errCh := make(chan error) - go func() { - compiler, arch, err := getSizesForArgs(ctx, state.cfgInvocation(), runner) - response.dr.Compiler = compiler - response.dr.Arch = arch - errCh <- err - }() - defer func() { - if sizesErr := <-errCh; sizesErr != nil { - err = sizesErr - } - }() - } - - // Determine files requested in contains patterns - var containFiles []string - restPatterns := make([]string, 0, len(patterns)) - // Extract file= and other [querytype]= patterns. Report an error if querytype - // doesn't exist. -extractQueries: - for _, pattern := range patterns { - eqidx := strings.Index(pattern, "=") - if eqidx < 0 { - restPatterns = append(restPatterns, pattern) - } else { - query, value := pattern[:eqidx], pattern[eqidx+len("="):] - switch query { - case "file": - containFiles = append(containFiles, value) - case "pattern": - restPatterns = append(restPatterns, value) - case "": // not a reserved query - restPatterns = append(restPatterns, pattern) - default: - for _, rune := range query { - if rune < 'a' || rune > 'z' { // not a reserved query - restPatterns = append(restPatterns, pattern) - continue extractQueries - } - } - // Reject all other patterns containing "=" - return nil, fmt.Errorf("invalid query type %q in query pattern %q", query, pattern) - } - } - } - - // See if we have any patterns to pass through to go list. Zero initial - // patterns also requires a go list call, since it's the equivalent of - // ".". - if len(restPatterns) > 0 || len(patterns) == 0 { - dr, err := state.createDriverResponse(restPatterns...) - if err != nil { - return nil, err - } - response.addAll(dr) - } - - if len(containFiles) != 0 { - if err := state.runContainsQueries(response, containFiles); err != nil { - return nil, err - } - } - - // (We may yet return an error due to defer.) - return response.dr, nil -} - -// abs returns an absolute representation of path, based on cfg.Dir. -func (cfg *Config) abs(path string) (string, error) { - if filepath.IsAbs(path) { - return path, nil - } - // In case cfg.Dir is relative, pass it to filepath.Abs. - return filepath.Abs(filepath.Join(cfg.Dir, path)) -} - -func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error { - for _, query := range queries { - // TODO(matloob): Do only one query per directory. - fdir := filepath.Dir(query) - // Pass absolute path of directory to go list so that it knows to treat it as a directory, - // not a package path. - pattern, err := state.cfg.abs(fdir) - if err != nil { - return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err) - } - dirResponse, err := state.createDriverResponse(pattern) - - // If there was an error loading the package, or no packages are returned, - // or the package is returned with errors, try to load the file as an - // ad-hoc package. - // Usually the error will appear in a returned package, but may not if we're - // in module mode and the ad-hoc is located outside a module. - if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && - len(dirResponse.Packages[0].Errors) == 1 { - var queryErr error - if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil { - return err // return the original error - } - } - isRoot := make(map[string]bool, len(dirResponse.Roots)) - for _, root := range dirResponse.Roots { - isRoot[root] = true - } - for _, pkg := range dirResponse.Packages { - // Add any new packages to the main set - // We don't bother to filter packages that will be dropped by the changes of roots, - // that will happen anyway during graph construction outside this function. - // Over-reporting packages is not a problem. - response.addPackage(pkg) - // if the package was not a root one, it cannot have the file - if !isRoot[pkg.ID] { - continue - } - for _, pkgFile := range pkg.GoFiles { - if filepath.Base(query) == filepath.Base(pkgFile) { - response.addRoot(pkg.ID) - break - } - } - } - } - return nil -} - -// adhocPackage attempts to load or construct an ad-hoc package for a given -// query, if the original call to the driver produced inadequate results. -func (state *golistState) adhocPackage(pattern, query string) (*DriverResponse, error) { - response, err := state.createDriverResponse(query) - if err != nil { - return nil, err - } - // If we get nothing back from `go list`, - // try to make this file into its own ad-hoc package. - // TODO(rstambler): Should this check against the original response? - if len(response.Packages) == 0 { - response.Packages = append(response.Packages, &Package{ - ID: "command-line-arguments", - PkgPath: query, - GoFiles: []string{query}, - CompiledGoFiles: []string{query}, - Imports: make(map[string]*Package), - }) - response.Roots = append(response.Roots, "command-line-arguments") - } - // Handle special cases. - if len(response.Packages) == 1 { - // golang/go#33482: If this is a file= query for ad-hoc packages where - // the file only exists on an overlay, and exists outside of a module, - // add the file to the package and remove the errors. - if response.Packages[0].ID == "command-line-arguments" || - filepath.ToSlash(response.Packages[0].PkgPath) == filepath.ToSlash(query) { - if len(response.Packages[0].GoFiles) == 0 { - filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath - // TODO(matloob): check if the file is outside of a root dir? - for path := range state.cfg.Overlay { - if path == filename { - response.Packages[0].Errors = nil - response.Packages[0].GoFiles = []string{path} - response.Packages[0].CompiledGoFiles = []string{path} - } - } - } - } - } - return response, nil -} - -// Fields must match go list; -// see $GOROOT/src/cmd/go/internal/load/pkg.go. -type jsonPackage struct { - ImportPath string - Dir string - Name string - Target string - Export string - GoFiles []string - CompiledGoFiles []string - IgnoredGoFiles []string - IgnoredOtherFiles []string - EmbedPatterns []string - EmbedFiles []string - CFiles []string - CgoFiles []string - CXXFiles []string - MFiles []string - HFiles []string - FFiles []string - SFiles []string - SwigFiles []string - SwigCXXFiles []string - SysoFiles []string - Imports []string - ImportMap map[string]string - Deps []string - Module *Module - TestGoFiles []string - TestImports []string - XTestGoFiles []string - XTestImports []string - ForTest string // q in a "p [q.test]" package, else "" - DepOnly bool - - Error *packagesinternal.PackageError - DepsErrors []*packagesinternal.PackageError -} - -func otherFiles(p *jsonPackage) [][]string { - return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles} -} - -// createDriverResponse uses the "go list" command to expand the pattern -// words and return a response for the specified packages. -func (state *golistState) createDriverResponse(words ...string) (*DriverResponse, error) { - // go list uses the following identifiers in ImportPath and Imports: - // - // "p" -- importable package or main (command) - // "q.test" -- q's test executable - // "p [q.test]" -- variant of p as built for q's test executable - // "q_test [q.test]" -- q's external test package - // - // The packages p that are built differently for a test q.test - // are q itself, plus any helpers used by the external test q_test, - // typically including "testing" and all its dependencies. - - // Run "go list" for complete - // information on the specified packages. - goVersion, err := state.getGoVersion() - if err != nil { - return nil, err - } - buf, err := state.invokeGo("list", golistargs(state.cfg, words, goVersion)...) - if err != nil { - return nil, err - } - - seen := make(map[string]*jsonPackage) - pkgs := make(map[string]*Package) - additionalErrors := make(map[string][]Error) - // Decode the JSON and convert it to Package form. - response := &DriverResponse{ - GoVersion: goVersion, - } - for dec := json.NewDecoder(buf); dec.More(); { - p := new(jsonPackage) - if err := dec.Decode(p); err != nil { - return nil, fmt.Errorf("JSON decoding failed: %v", err) - } - - if p.ImportPath == "" { - // The documentation for go list says that “[e]rroneous packages will have - // a non-empty ImportPath”. If for some reason it comes back empty, we - // prefer to error out rather than silently discarding data or handing - // back a package without any way to refer to it. - if p.Error != nil { - return nil, Error{ - Pos: p.Error.Pos, - Msg: p.Error.Err, - } - } - return nil, fmt.Errorf("package missing import path: %+v", p) - } - - // Work around https://golang.org/issue/33157: - // go list -e, when given an absolute path, will find the package contained at - // that directory. But when no package exists there, it will return a fake package - // with an error and the ImportPath set to the absolute path provided to go list. - // Try to convert that absolute path to what its package path would be if it's - // contained in a known module or GOPATH entry. This will allow the package to be - // properly "reclaimed" when overlays are processed. - if filepath.IsAbs(p.ImportPath) && p.Error != nil { - pkgPath, ok, err := state.getPkgPath(p.ImportPath) - if err != nil { - return nil, err - } - if ok { - p.ImportPath = pkgPath - } - } - - if old, found := seen[p.ImportPath]; found { - // If one version of the package has an error, and the other doesn't, assume - // that this is a case where go list is reporting a fake dependency variant - // of the imported package: When a package tries to invalidly import another - // package, go list emits a variant of the imported package (with the same - // import path, but with an error on it, and the package will have a - // DepError set on it). An example of when this can happen is for imports of - // main packages: main packages can not be imported, but they may be - // separately matched and listed by another pattern. - // See golang.org/issue/36188 for more details. - - // The plan is that eventually, hopefully in Go 1.15, the error will be - // reported on the importing package rather than the duplicate "fake" - // version of the imported package. Once all supported versions of Go - // have the new behavior this logic can be deleted. - // TODO(matloob): delete the workaround logic once all supported versions of - // Go return the errors on the proper package. - - // There should be exactly one version of a package that doesn't have an - // error. - if old.Error == nil && p.Error == nil { - if !reflect.DeepEqual(p, old) { - return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath) - } - continue - } - - // Determine if this package's error needs to be bubbled up. - // This is a hack, and we expect for go list to eventually set the error - // on the package. - if old.Error != nil { - var errkind string - if strings.Contains(old.Error.Err, "not an importable package") { - errkind = "not an importable package" - } else if strings.Contains(old.Error.Err, "use of internal package") && strings.Contains(old.Error.Err, "not allowed") { - errkind = "use of internal package not allowed" - } - if errkind != "" { - if len(old.Error.ImportStack) < 1 { - return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind) - } - importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1] - if importingPkg == old.ImportPath { - // Using an older version of Go which put this package itself on top of import - // stack, instead of the importer. Look for importer in second from top - // position. - if len(old.Error.ImportStack) < 2 { - return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind) - } - importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2] - } - additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{ - Pos: old.Error.Pos, - Msg: old.Error.Err, - Kind: ListError, - }) - } - } - - // Make sure that if there's a version of the package without an error, - // that's the one reported to the user. - if old.Error == nil { - continue - } - - // This package will replace the old one at the end of the loop. - } - seen[p.ImportPath] = p - - pkg := &Package{ - Name: p.Name, - ID: p.ImportPath, - Dir: p.Dir, - Target: p.Target, - GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), - CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles), - OtherFiles: absJoin(p.Dir, otherFiles(p)...), - EmbedFiles: absJoin(p.Dir, p.EmbedFiles), - EmbedPatterns: absJoin(p.Dir, p.EmbedPatterns), - IgnoredFiles: absJoin(p.Dir, p.IgnoredGoFiles, p.IgnoredOtherFiles), - ForTest: p.ForTest, - depsErrors: p.DepsErrors, - Module: p.Module, - } - - if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 { - if len(p.CompiledGoFiles) > len(p.GoFiles) { - // We need the cgo definitions, which are in the first - // CompiledGoFile after the non-cgo ones. This is a hack but there - // isn't currently a better way to find it. We also need the pure - // Go files and unprocessed cgo files, all of which are already - // in pkg.GoFiles. - cgoTypes := p.CompiledGoFiles[len(p.GoFiles)] - pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...) - } else { - // golang/go#38990: go list silently fails to do cgo processing - pkg.CompiledGoFiles = nil - pkg.Errors = append(pkg.Errors, Error{ - Msg: "go list failed to return CompiledGoFiles. This may indicate failure to perform cgo processing; try building at the command line. See https://golang.org/issue/38990.", - Kind: ListError, - }) - } - } - - // Work around https://golang.org/issue/28749: - // cmd/go puts assembly, C, and C++ files in CompiledGoFiles. - // Remove files from CompiledGoFiles that are non-go files - // (or are not files that look like they are from the cache). - if len(pkg.CompiledGoFiles) > 0 { - out := pkg.CompiledGoFiles[:0] - for _, f := range pkg.CompiledGoFiles { - if ext := filepath.Ext(f); ext != ".go" && ext != "" { // ext == "" means the file is from the cache, so probably cgo-processed file - continue - } - out = append(out, f) - } - pkg.CompiledGoFiles = out - } - - // Extract the PkgPath from the package's ID. - if i := strings.IndexByte(pkg.ID, ' '); i >= 0 { - pkg.PkgPath = pkg.ID[:i] - } else { - pkg.PkgPath = pkg.ID - } - - if pkg.PkgPath == "unsafe" { - pkg.CompiledGoFiles = nil // ignore fake unsafe.go file (#59929) - } else if len(pkg.CompiledGoFiles) == 0 { - // Work around for pre-go.1.11 versions of go list. - // TODO(matloob): they should be handled by the fallback. - // Can we delete this? - pkg.CompiledGoFiles = pkg.GoFiles - } - - // Assume go list emits only absolute paths for Dir. - if p.Dir != "" && !filepath.IsAbs(p.Dir) { - log.Fatalf("internal error: go list returned non-absolute Package.Dir: %s", p.Dir) - } - - if p.Export != "" && !filepath.IsAbs(p.Export) { - pkg.ExportFile = filepath.Join(p.Dir, p.Export) - } else { - pkg.ExportFile = p.Export - } - - // imports - // - // Imports contains the IDs of all imported packages. - // ImportsMap records (path, ID) only where they differ. - ids := make(map[string]bool) - for _, id := range p.Imports { - ids[id] = true - } - pkg.Imports = make(map[string]*Package) - for path, id := range p.ImportMap { - pkg.Imports[path] = &Package{ID: id} // non-identity import - delete(ids, id) - } - for id := range ids { - if id == "C" { - continue - } - - pkg.Imports[id] = &Package{ID: id} // identity import - } - if !p.DepOnly { - response.Roots = append(response.Roots, pkg.ID) - } - - // Temporary work-around for golang/go#39986. Parse filenames out of - // error messages. This happens if there are unrecoverable syntax - // errors in the source, so we can't match on a specific error message. - // - // TODO(rfindley): remove this heuristic, in favor of considering - // InvalidGoFiles from the list driver. - if err := p.Error; err != nil && state.shouldAddFilenameFromError(p) { - addFilenameFromPos := func(pos string) bool { - split := strings.Split(pos, ":") - if len(split) < 1 { - return false - } - filename := strings.TrimSpace(split[0]) - if filename == "" { - return false - } - if !filepath.IsAbs(filename) { - filename = filepath.Join(state.cfg.Dir, filename) - } - info, _ := os.Stat(filename) - if info == nil { - return false - } - pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename) - pkg.GoFiles = append(pkg.GoFiles, filename) - return true - } - found := addFilenameFromPos(err.Pos) - // In some cases, go list only reports the error position in the - // error text, not the error position. One such case is when the - // file's package name is a keyword (see golang.org/issue/39763). - if !found { - addFilenameFromPos(err.Err) - } - } - - if p.Error != nil { - msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363. - // Address golang.org/issue/35964 by appending import stack to error message. - if msg == "import cycle not allowed" && len(p.Error.ImportStack) != 0 { - msg += fmt.Sprintf(": import stack: %v", p.Error.ImportStack) - } - pkg.Errors = append(pkg.Errors, Error{ - Pos: p.Error.Pos, - Msg: msg, - Kind: ListError, - }) - } - - pkgs[pkg.ID] = pkg - } - - for id, errs := range additionalErrors { - if p, ok := pkgs[id]; ok { - p.Errors = append(p.Errors, errs...) - } - } - for _, pkg := range pkgs { - response.Packages = append(response.Packages, pkg) - } - sort.Slice(response.Packages, func(i, j int) bool { return response.Packages[i].ID < response.Packages[j].ID }) - - return response, nil -} - -func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool { - if len(p.GoFiles) > 0 || len(p.CompiledGoFiles) > 0 { - return false - } - - goV, err := state.getGoVersion() - if err != nil { - return false - } - - // On Go 1.14 and earlier, only add filenames from errors if the import stack is empty. - // The import stack behaves differently for these versions than newer Go versions. - if goV < 15 { - return len(p.Error.ImportStack) == 0 - } - - // On Go 1.15 and later, only parse filenames out of error if there's no import stack, - // or the current package is at the top of the import stack. This is not guaranteed - // to work perfectly, but should avoid some cases where files in errors don't belong to this - // package. - return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath -} - -// getGoVersion returns the effective minor version of the go command. -func (state *golistState) getGoVersion() (int, error) { - state.goVersionOnce.Do(func() { - state.goVersion, state.goVersionError = gocommand.GoVersion(state.ctx, state.cfgInvocation(), state.runner) - }) - return state.goVersion, state.goVersionError -} - -// getPkgPath finds the package path of a directory if it's relative to a root -// directory. -func (state *golistState) getPkgPath(dir string) (string, bool, error) { - if !filepath.IsAbs(dir) { - panic("non-absolute dir passed to getPkgPath") - } - roots, err := state.determineRootDirs() - if err != nil { - return "", false, err - } - - for rdir, rpath := range roots { - // Make sure that the directory is in the module, - // to avoid creating a path relative to another module. - if !strings.HasPrefix(dir, rdir) { - continue - } - // TODO(matloob): This doesn't properly handle symlinks. - r, err := filepath.Rel(rdir, dir) - if err != nil { - continue - } - if rpath != "" { - // We choose only one root even though the directory even it can belong in multiple modules - // or GOPATH entries. This is okay because we only need to work with absolute dirs when a - // file is missing from disk, for instance when gopls calls go/packages in an overlay. - // Once the file is saved, gopls, or the next invocation of the tool will get the correct - // result straight from golist. - // TODO(matloob): Implement module tiebreaking? - return path.Join(rpath, filepath.ToSlash(r)), true, nil - } - return filepath.ToSlash(r), true, nil - } - return "", false, nil -} - -// absJoin absolutizes and flattens the lists of files. -func absJoin(dir string, fileses ...[]string) (res []string) { - for _, files := range fileses { - for _, file := range files { - if !filepath.IsAbs(file) { - file = filepath.Join(dir, file) - } - res = append(res, file) - } - } - return res -} - -func jsonFlag(cfg *Config, goVersion int) string { - if goVersion < 19 { - return "-json" - } - var fields []string - added := make(map[string]bool) - addFields := func(fs ...string) { - for _, f := range fs { - if !added[f] { - added[f] = true - fields = append(fields, f) - } - } - } - addFields("Name", "ImportPath", "Error") // These fields are always needed - if cfg.Mode&NeedFiles != 0 || cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 { - addFields("Dir", "GoFiles", "IgnoredGoFiles", "IgnoredOtherFiles", "CFiles", - "CgoFiles", "CXXFiles", "MFiles", "HFiles", "FFiles", "SFiles", - "SwigFiles", "SwigCXXFiles", "SysoFiles") - if cfg.Tests { - addFields("TestGoFiles", "XTestGoFiles") - } - } - if cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 { - // CompiledGoFiles seems to be required for the test case TestCgoNoSyntax, - // even when -compiled isn't passed in. - // TODO(#52435): Should we make the test ask for -compiled, or automatically - // request CompiledGoFiles in certain circumstances? - addFields("Dir", "CompiledGoFiles") - } - if cfg.Mode&NeedCompiledGoFiles != 0 { - addFields("Dir", "CompiledGoFiles", "Export") - } - if cfg.Mode&NeedImports != 0 { - // When imports are requested, DepOnly is used to distinguish between packages - // explicitly requested and transitive imports of those packages. - addFields("DepOnly", "Imports", "ImportMap") - if cfg.Tests { - addFields("TestImports", "XTestImports") - } - } - if cfg.Mode&NeedDeps != 0 { - addFields("DepOnly") - } - if usesExportData(cfg) { - // Request Dir in the unlikely case Export is not absolute. - addFields("Dir", "Export") - } - if cfg.Mode&NeedForTest != 0 { - addFields("ForTest") - } - if cfg.Mode&needInternalDepsErrors != 0 { - addFields("DepsErrors") - } - if cfg.Mode&NeedModule != 0 { - addFields("Module") - } - if cfg.Mode&NeedEmbedFiles != 0 { - addFields("EmbedFiles") - } - if cfg.Mode&NeedEmbedPatterns != 0 { - addFields("EmbedPatterns") - } - if cfg.Mode&NeedTarget != 0 { - addFields("Target") - } - return "-json=" + strings.Join(fields, ",") -} - -func golistargs(cfg *Config, words []string, goVersion int) []string { - const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo - fullargs := []string{ - "-e", jsonFlag(cfg, goVersion), - fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0), - fmt.Sprintf("-test=%t", cfg.Tests), - fmt.Sprintf("-export=%t", usesExportData(cfg)), - fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0), - // go list doesn't let you pass -test and -find together, - // probably because you'd just get the TestMain. - fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0 && !usesExportData(cfg)), - // VCS information is not needed when not printing Stale or StaleReason fields - "-buildvcs=false", - } - - // golang/go#60456: with go1.21 and later, go list serves pgo variants, which - // can be costly to compute and may result in redundant processing for the - // caller. Disable these variants. If someone wants to add e.g. a NeedPGO - // mode flag, that should be a separate proposal. - if goVersion >= 21 { - fullargs = append(fullargs, "-pgo=off") - } - - fullargs = append(fullargs, cfg.BuildFlags...) - fullargs = append(fullargs, "--") - fullargs = append(fullargs, words...) - return fullargs -} - -// cfgInvocation returns an Invocation that reflects cfg's settings. -func (state *golistState) cfgInvocation() gocommand.Invocation { - cfg := state.cfg - return gocommand.Invocation{ - BuildFlags: cfg.BuildFlags, - CleanEnv: cfg.Env != nil, - Env: cfg.Env, - Logf: cfg.Logf, - WorkingDir: cfg.Dir, - Overlay: state.overlay, - } -} - -// invokeGo returns the stdout of a go command invocation. -func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) { - cfg := state.cfg - - inv := state.cfgInvocation() - inv.Verb = verb - inv.Args = args - - stdout, stderr, friendlyErr, err := state.runner.RunRaw(cfg.Context, inv) - if err != nil { - // Check for 'go' executable not being found. - if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound { - return nil, fmt.Errorf("'go list' driver requires 'go', but %s", exec.ErrNotFound) - } - - exitErr, ok := err.(*exec.ExitError) - if !ok { - // Catastrophic error: - // - context cancellation - return nil, fmt.Errorf("couldn't run 'go': %w", err) - } - - // Old go version? - if strings.Contains(stderr.String(), "flag provided but not defined") { - return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)} - } - - // Related to #24854 - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") { - return nil, friendlyErr - } - - // Return an error if 'go list' failed due to missing tools in - // $GOROOT/pkg/tool/$GOOS_$GOARCH (#69606). - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), `go: no such tool`) { - return nil, friendlyErr - } - - // Is there an error running the C compiler in cgo? This will be reported in the "Error" field - // and should be suppressed by go list -e. - // - // This condition is not perfect yet because the error message can include other error messages than runtime/cgo. - isPkgPathRune := func(r rune) bool { - // From https://golang.org/ref/spec#Import_declarations: - // Implementation restriction: A compiler may restrict ImportPaths to non-empty strings - // using only characters belonging to Unicode's L, M, N, P, and S general categories - // (the Graphic characters without spaces) and may also exclude the - // characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD. - return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) && - !strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r) - } - // golang/go#36770: Handle case where cmd/go prints module download messages before the error. - msg := stderr.String() - for strings.HasPrefix(msg, "go: downloading") { - msg = msg[strings.IndexRune(msg, '\n')+1:] - } - if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") { - msg := msg[len("# "):] - if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") { - return stdout, nil - } - // Treat pkg-config errors as a special case (golang.org/issue/36770). - if strings.HasPrefix(msg, "pkg-config") { - return stdout, nil - } - } - - // This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show - // the error in the Err section of stdout in case -e option is provided. - // This fix is provided for backwards compatibility. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Similar to the previous error, but currently lacks a fix in Go. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath. - // If the package doesn't exist, put the absolute path of the directory into the error message, - // as Go 1.13 list does. - const noSuchDirectory = "no such directory" - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) { - errstr := stderr.String() - abspath := strings.TrimSpace(errstr[strings.Index(errstr, noSuchDirectory)+len(noSuchDirectory):]) - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - abspath, strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist. - // Note that the error message we look for in this case is different that the one looked for above. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a - // directory outside any module. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") { - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - // TODO(matloob): command-line-arguments isn't correct here. - "command-line-arguments", strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Another variation of the previous error - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside module root") { - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - // TODO(matloob): command-line-arguments isn't correct here. - "command-line-arguments", strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for an instance of golang.org/issue/26755: go list -e will return a non-zero exit - // status if there's a dependency on a package that doesn't exist. But it should return - // a zero exit status and set an error on that package. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") { - // Don't clobber stdout if `go list` actually returned something. - if len(stdout.String()) > 0 { - return stdout, nil - } - // try to extract package name from string - stderrStr := stderr.String() - var importPath string - colon := strings.Index(stderrStr, ":") - if colon > 0 && strings.HasPrefix(stderrStr, "go build ") { - importPath = stderrStr[len("go build "):colon] - } - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - importPath, strings.Trim(stderrStr, "\n")) - return bytes.NewBufferString(output), nil - } - - // Export mode entails a build. - // If that build fails, errors appear on stderr - // (despite the -e flag) and the Export field is blank. - // Do not fail in that case. - // The same is true if an ad-hoc package given to go list doesn't exist. - // TODO(matloob): Remove these once we can depend on go list to exit with a zero status with -e even when - // packages don't exist or a build fails. - if !usesExportData(cfg) && !containsGoFile(args) { - return nil, friendlyErr - } - } - return stdout, nil -} - -func containsGoFile(s []string) bool { - for _, f := range s { - if strings.HasSuffix(f, ".go") { - return true - } - } - return false -} - -func cmdDebugStr(cmd *exec.Cmd) string { - env := make(map[string]string) - for _, kv := range cmd.Env { - split := strings.SplitN(kv, "=", 2) - k, v := split[0], split[1] - env[k] = v - } - - var args []string - for _, arg := range cmd.Args { - quoted := strconv.Quote(arg) - if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { - args = append(args, quoted) - } else { - args = append(args, arg) - } - } - return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) -} - -// getSizesForArgs queries 'go list' for the appropriate -// Compiler and GOARCH arguments to pass to [types.SizesFor]. -func getSizesForArgs(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) { - inv.Verb = "list" - inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"} - stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv) - var goarch, compiler string - if rawErr != nil { - rawErrMsg := rawErr.Error() - if strings.Contains(rawErrMsg, "cannot find main module") || - strings.Contains(rawErrMsg, "go.mod file not found") { - // User's running outside of a module. - // All bets are off. Get GOARCH and guess compiler is gc. - // TODO(matloob): Is this a problem in practice? - inv.Verb = "env" - inv.Args = []string{"GOARCH"} - envout, enverr := gocmdRunner.Run(ctx, inv) - if enverr != nil { - return "", "", enverr - } - goarch = strings.TrimSpace(envout.String()) - compiler = "gc" - } else if friendlyErr != nil { - return "", "", friendlyErr - } else { - // This should be unreachable, but be defensive - // in case RunRaw's error results are inconsistent. - return "", "", rawErr - } - } else { - fields := strings.Fields(stdout.String()) - if len(fields) < 2 { - return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>", - stdout.String(), stderr.String()) - } - goarch = fields[0] - compiler = fields[1] - } - return compiler, goarch, nil -} diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go deleted file mode 100644 index d9d5a45c..00000000 --- a/vendor/golang.org/x/tools/go/packages/golist_overlay.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2018 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 packages - -import ( - "encoding/json" - "path/filepath" - - "golang.org/x/tools/internal/gocommand" -) - -// determineRootDirs returns a mapping from absolute directories that could -// contain code to their corresponding import path prefixes. -func (state *golistState) determineRootDirs() (map[string]string, error) { - env, err := state.getEnv() - if err != nil { - return nil, err - } - if env["GOMOD"] != "" { - state.rootsOnce.Do(func() { - state.rootDirs, state.rootDirsError = state.determineRootDirsModules() - }) - } else { - state.rootsOnce.Do(func() { - state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH() - }) - } - return state.rootDirs, state.rootDirsError -} - -func (state *golistState) determineRootDirsModules() (map[string]string, error) { - // List all of the modules--the first will be the directory for the main - // module. Any replaced modules will also need to be treated as roots. - // Editing files in the module cache isn't a great idea, so we don't - // plan to ever support that. - out, err := state.invokeGo("list", "-m", "-json", "all") - if err != nil { - // 'go list all' will fail if we're outside of a module and - // GO111MODULE=on. Try falling back without 'all'. - var innerErr error - out, innerErr = state.invokeGo("list", "-m", "-json") - if innerErr != nil { - return nil, err - } - } - roots := map[string]string{} - modules := map[string]string{} - var i int - for dec := json.NewDecoder(out); dec.More(); { - mod := new(gocommand.ModuleJSON) - if err := dec.Decode(mod); err != nil { - return nil, err - } - if mod.Dir != "" && mod.Path != "" { - // This is a valid module; add it to the map. - absDir, err := state.cfg.abs(mod.Dir) - if err != nil { - return nil, err - } - modules[absDir] = mod.Path - // The first result is the main module. - if i == 0 || mod.Replace != nil && mod.Replace.Path != "" { - roots[absDir] = mod.Path - } - } - i++ - } - return roots, nil -} - -func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) { - m := map[string]string{} - for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) { - absDir, err := filepath.Abs(dir) - if err != nil { - return nil, err - } - m[filepath.Join(absDir, "src")] = "" - } - return m, nil -} diff --git a/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/vendor/golang.org/x/tools/go/packages/loadmode_string.go deleted file mode 100644 index 69eec9f4..00000000 --- a/vendor/golang.org/x/tools/go/packages/loadmode_string.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2019 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 packages - -import ( - "fmt" - "strings" -) - -var modes = [...]struct { - mode LoadMode - name string -}{ - {NeedName, "NeedName"}, - {NeedFiles, "NeedFiles"}, - {NeedCompiledGoFiles, "NeedCompiledGoFiles"}, - {NeedImports, "NeedImports"}, - {NeedDeps, "NeedDeps"}, - {NeedExportFile, "NeedExportFile"}, - {NeedTypes, "NeedTypes"}, - {NeedSyntax, "NeedSyntax"}, - {NeedTypesInfo, "NeedTypesInfo"}, - {NeedTypesSizes, "NeedTypesSizes"}, - {NeedForTest, "NeedForTest"}, - {NeedModule, "NeedModule"}, - {NeedEmbedFiles, "NeedEmbedFiles"}, - {NeedEmbedPatterns, "NeedEmbedPatterns"}, - {NeedTarget, "NeedTarget"}, -} - -func (mode LoadMode) String() string { - if mode == 0 { - return "LoadMode(0)" - } - var out []string - // named bits - for _, item := range modes { - if (mode & item.mode) != 0 { - mode ^= item.mode - out = append(out, item.name) - } - } - // unnamed residue - if mode != 0 { - if out == nil { - return fmt.Sprintf("LoadMode(%#x)", int(mode)) - } - out = append(out, fmt.Sprintf("%#x", int(mode))) - } - if len(out) == 1 { - return out[0] - } - return "(" + strings.Join(out, "|") + ")" -} diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go deleted file mode 100644 index 412ba06b..00000000 --- a/vendor/golang.org/x/tools/go/packages/packages.go +++ /dev/null @@ -1,1579 +0,0 @@ -// Copyright 2018 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 packages - -// See doc.go for package documentation and implementation notes. - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "go/ast" - "go/parser" - "go/scanner" - "go/token" - "go/types" - "log" - "os" - "path/filepath" - "runtime" - "strings" - "sync" - "sync/atomic" - "time" - - "golang.org/x/sync/errgroup" - - "golang.org/x/tools/go/gcexportdata" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/packagesinternal" - "golang.org/x/tools/internal/typesinternal" -) - -// A LoadMode controls the amount of detail to return when loading. -// The bits below can be combined to specify which fields should be -// filled in the result packages. -// -// The zero value is a special case, equivalent to combining -// the NeedName, NeedFiles, and NeedCompiledGoFiles bits. -// -// ID and Errors (if present) will always be filled. -// [Load] may return more information than requested. -// -// The Mode flag is a union of several bits named NeedName, -// NeedFiles, and so on, each of which determines whether -// a given field of Package (Name, Files, etc) should be -// populated. -// -// For convenience, we provide named constants for the most -// common combinations of Need flags: -// -// [LoadFiles] lists of files in each package -// [LoadImports] ... plus imports -// [LoadTypes] ... plus type information -// [LoadSyntax] ... plus type-annotated syntax -// [LoadAllSyntax] ... for all dependencies -// -// Unfortunately there are a number of open bugs related to -// interactions among the LoadMode bits: -// - https://go.dev/issue/56633 -// - https://go.dev/issue/56677 -// - https://go.dev/issue/58726 -// - https://go.dev/issue/63517 -type LoadMode int - -const ( - // NeedName adds Name and PkgPath. - NeedName LoadMode = 1 << iota - - // NeedFiles adds Dir, GoFiles, OtherFiles, and IgnoredFiles - NeedFiles - - // NeedCompiledGoFiles adds CompiledGoFiles. - NeedCompiledGoFiles - - // NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain - // "placeholder" Packages with only the ID set. - NeedImports - - // NeedDeps adds the fields requested by the LoadMode in the packages in Imports. - NeedDeps - - // NeedExportFile adds ExportFile. - NeedExportFile - - // NeedTypes adds Types, Fset, and IllTyped. - NeedTypes - - // NeedSyntax adds Syntax and Fset. - NeedSyntax - - // NeedTypesInfo adds TypesInfo and Fset. - NeedTypesInfo - - // NeedTypesSizes adds TypesSizes. - NeedTypesSizes - - // needInternalDepsErrors adds the internal deps errors field for use by gopls. - needInternalDepsErrors - - // NeedForTest adds ForTest. - // - // Tests must also be set on the context for this field to be populated. - NeedForTest - - // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+. - // Modifies CompiledGoFiles and Types, and has no effect on its own. - typecheckCgo - - // NeedModule adds Module. - NeedModule - - // NeedEmbedFiles adds EmbedFiles. - NeedEmbedFiles - - // NeedEmbedPatterns adds EmbedPatterns. - NeedEmbedPatterns - - // NeedTarget adds Target. - NeedTarget - - // Be sure to update loadmode_string.go when adding new items! -) - -const ( - // LoadFiles loads the name and file names for the initial packages. - LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles - - // LoadImports loads the name, file names, and import mapping for the initial packages. - LoadImports = LoadFiles | NeedImports - - // LoadTypes loads exported type information for the initial packages. - LoadTypes = LoadImports | NeedTypes | NeedTypesSizes - - // LoadSyntax loads typed syntax for the initial packages. - LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo - - // LoadAllSyntax loads typed syntax for the initial packages and all dependencies. - LoadAllSyntax = LoadSyntax | NeedDeps - - // Deprecated: NeedExportsFile is a historical misspelling of NeedExportFile. - // - //go:fix inline - NeedExportsFile = NeedExportFile -) - -// A Config specifies details about how packages should be loaded. -// The zero value is a valid configuration. -// -// Calls to [Load] do not modify this struct. -type Config struct { - // Mode controls the level of information returned for each package. - Mode LoadMode - - // Context specifies the context for the load operation. - // Cancelling the context may cause [Load] to abort and - // return an error. - Context context.Context - - // Logf is the logger for the config. - // If the user provides a logger, debug logging is enabled. - // If the GOPACKAGESDEBUG environment variable is set to true, - // but the logger is nil, default to log.Printf. - Logf func(format string, args ...any) - - // Dir is the directory in which to run the build system's query tool - // that provides information about the packages. - // If Dir is empty, the tool is run in the current directory. - Dir string - - // Env is the environment to use when invoking the build system's query tool. - // If Env is nil, the current environment is used. - // As in os/exec's Cmd, only the last value in the slice for - // each environment key is used. To specify the setting of only - // a few variables, append to the current environment, as in: - // - // opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386") - // - Env []string - - // BuildFlags is a list of command-line flags to be passed through to - // the build system's query tool. - BuildFlags []string - - // Fset provides source position information for syntax trees and types. - // If Fset is nil, Load will use a new fileset, but preserve Fset's value. - Fset *token.FileSet - - // ParseFile is called to read and parse each file - // when preparing a package's type-checked syntax tree. - // It must be safe to call ParseFile simultaneously from multiple goroutines. - // If ParseFile is nil, the loader will uses parser.ParseFile. - // - // ParseFile should parse the source from src and use filename only for - // recording position information. - // - // An application may supply a custom implementation of ParseFile - // to change the effective file contents or the behavior of the parser, - // or to modify the syntax tree. For example, selectively eliminating - // unwanted function bodies can significantly accelerate type checking. - ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) - - // If Tests is set, the loader includes not just the packages - // matching a particular pattern but also any related test packages, - // including test-only variants of the package and the test executable. - // - // For example, when using the go command, loading "fmt" with Tests=true - // returns four packages, with IDs "fmt" (the standard package), - // "fmt [fmt.test]" (the package as compiled for the test), - // "fmt_test" (the test functions from source files in package fmt_test), - // and "fmt.test" (the test binary). - // - // In build systems with explicit names for tests, - // setting Tests may have no effect. - Tests bool - - // Overlay is a mapping from absolute file paths to file contents. - // - // For each map entry, [Load] uses the alternative file - // contents provided by the overlay mapping instead of reading - // from the file system. This mechanism can be used to enable - // editor-integrated tools to correctly analyze the contents - // of modified but unsaved buffers, for example. - // - // The overlay mapping is passed to the build system's driver - // (see "The driver protocol") so that it too can report - // consistent package metadata about unsaved files. However, - // drivers may vary in their level of support for overlays. - Overlay map[string][]byte -} - -// Load loads and returns the Go packages named by the given patterns. -// -// The cfg parameter specifies loading options; nil behaves the same as an empty [Config]. -// -// The [Config.Mode] field is a set of bits that determine what kinds -// of information should be computed and returned. Modes that require -// more information tend to be slower. See [LoadMode] for details -// and important caveats. Its zero value is equivalent to -// [NeedName] | [NeedFiles] | [NeedCompiledGoFiles]. -// -// Each call to Load returns a new set of [Package] instances. -// The Packages and their Imports form a directed acyclic graph. -// -// If the [NeedTypes] mode flag was set, each call to Load uses a new -// [types.Importer], so [types.Object] and [types.Type] values from -// different calls to Load must not be mixed as they will have -// inconsistent notions of type identity. -// -// If any of the patterns was invalid as defined by the -// underlying build system, Load returns an error. -// It may return an empty list of packages without an error, -// for instance for an empty expansion of a valid wildcard. -// Errors associated with a particular package are recorded in the -// corresponding Package's Errors list, and do not cause Load to -// return an error. Clients may need to handle such errors before -// proceeding with further analysis. The [PrintErrors] function is -// provided for convenient display of all errors. -func Load(cfg *Config, patterns ...string) ([]*Package, error) { - ld := newLoader(cfg) - response, external, err := defaultDriver(&ld.Config, patterns...) - if err != nil { - return nil, err - } - - ld.sizes = types.SizesFor(response.Compiler, response.Arch) - if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 { - // Type size information is needed but unavailable. - if external { - // An external driver may fail to populate the Compiler/GOARCH fields, - // especially since they are relatively new (see #63700). - // Provide a sensible fallback in this case. - ld.sizes = types.SizesFor("gc", runtime.GOARCH) - if ld.sizes == nil { // gccgo-only arch - ld.sizes = types.SizesFor("gc", "amd64") - } - } else { - // Go list should never fail to deliver accurate size information. - // Reject the whole Load since the error is the same for every package. - return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q", - response.Compiler, response.Arch) - } - } - - ld.externalDriver = external - - return ld.refine(response) -} - -// defaultDriver is a driver that implements go/packages' fallback behavior. -// It will try to request to an external driver, if one exists. If there's -// no external driver, or the driver returns a response with NotHandled set, -// defaultDriver will fall back to the go list driver. -// The boolean result indicates that an external driver handled the request. -func defaultDriver(cfg *Config, patterns ...string) (*DriverResponse, bool, error) { - const ( - // windowsArgMax specifies the maximum command line length for - // the Windows' CreateProcess function. - windowsArgMax = 32767 - // maxEnvSize is a very rough estimation of the maximum environment - // size of a user. - maxEnvSize = 16384 - // safeArgMax specifies the maximum safe command line length to use - // by the underlying driver excl. the environment. We choose the Windows' - // ARG_MAX as the starting point because it's one of the lowest ARG_MAX - // constants out of the different supported platforms, - // e.g., https://www.in-ulm.de/~mascheck/various/argmax/#results. - safeArgMax = windowsArgMax - maxEnvSize - ) - chunks, err := splitIntoChunks(patterns, safeArgMax) - if err != nil { - return nil, false, err - } - - if driver := findExternalDriver(cfg); driver != nil { - response, err := callDriverOnChunks(driver, cfg, chunks) - if err != nil { - return nil, false, err - } else if !response.NotHandled { - return response, true, nil - } - // not handled: fall through - } - - // go list fallback - - // Write overlays once, as there are many calls - // to 'go list' (one per chunk plus others too). - overlayFile, cleanupOverlay, err := gocommand.WriteOverlays(cfg.Overlay) - if err != nil { - return nil, false, err - } - defer cleanupOverlay() - - var runner gocommand.Runner // (shared across many 'go list' calls) - driver := func(cfg *Config, patterns []string) (*DriverResponse, error) { - return goListDriver(cfg, &runner, overlayFile, patterns) - } - response, err := callDriverOnChunks(driver, cfg, chunks) - if err != nil { - return nil, false, err - } - return response, false, err -} - -// splitIntoChunks chunks the slice so that the total number of characters -// in a chunk is no longer than argMax. -func splitIntoChunks(patterns []string, argMax int) ([][]string, error) { - if argMax <= 0 { - return nil, errors.New("failed to split patterns into chunks, negative safe argMax value") - } - var chunks [][]string - charsInChunk := 0 - nextChunkStart := 0 - for i, v := range patterns { - vChars := len(v) - if vChars > argMax { - // a single pattern is longer than the maximum safe ARG_MAX, hardly should happen - return nil, errors.New("failed to split patterns into chunks, a pattern is too long") - } - charsInChunk += vChars + 1 // +1 is for a whitespace between patterns that has to be counted too - if charsInChunk > argMax { - chunks = append(chunks, patterns[nextChunkStart:i]) - nextChunkStart = i - charsInChunk = vChars - } - } - // add the last chunk - if nextChunkStart < len(patterns) { - chunks = append(chunks, patterns[nextChunkStart:]) - } - return chunks, nil -} - -func callDriverOnChunks(driver driver, cfg *Config, chunks [][]string) (*DriverResponse, error) { - if len(chunks) == 0 { - return driver(cfg, nil) - } - responses := make([]*DriverResponse, len(chunks)) - errNotHandled := errors.New("driver returned NotHandled") - var g errgroup.Group - for i, chunk := range chunks { - g.Go(func() (err error) { - responses[i], err = driver(cfg, chunk) - if responses[i] != nil && responses[i].NotHandled { - err = errNotHandled - } - return err - }) - } - if err := g.Wait(); err != nil { - if errors.Is(err, errNotHandled) { - return &DriverResponse{NotHandled: true}, nil - } - return nil, err - } - return mergeResponses(responses...), nil -} - -func mergeResponses(responses ...*DriverResponse) *DriverResponse { - if len(responses) == 0 { - return nil - } - // No dedup needed - if len(responses) == 1 { - return responses[0] - } - response := newDeduper() - response.dr.NotHandled = false - response.dr.Compiler = responses[0].Compiler - response.dr.Arch = responses[0].Arch - response.dr.GoVersion = responses[0].GoVersion - for _, v := range responses { - response.addAll(v) - } - return response.dr -} - -// A Package describes a loaded Go package. -// -// It also defines part of the JSON schema of [DriverResponse]. -// See the package documentation for an overview. -type Package struct { - // ID is a unique identifier for a package, - // in a syntax provided by the underlying build system. - // - // Because the syntax varies based on the build system, - // clients should treat IDs as opaque and not attempt to - // interpret them. - ID string - - // Name is the package name as it appears in the package source code. - Name string - - // PkgPath is the package path as used by the go/types package. - PkgPath string - - // Dir is the directory associated with the package, if it exists. - // - // For packages listed by the go command, this is the directory containing - // the package files. - Dir string - - // Errors contains any errors encountered querying the metadata - // of the package, or while parsing or type-checking its files. - Errors []Error - - // TypeErrors contains the subset of errors produced during type checking. - TypeErrors []types.Error - - // GoFiles lists the absolute file paths of the package's Go source files. - // It may include files that should not be compiled, for example because - // they contain non-matching build tags, are documentary pseudo-files such as - // unsafe/unsafe.go or builtin/builtin.go, or are subject to cgo preprocessing. - GoFiles []string - - // CompiledGoFiles lists the absolute file paths of the package's source - // files that are suitable for type checking. - // This may differ from GoFiles if files are processed before compilation. - CompiledGoFiles []string - - // OtherFiles lists the absolute file paths of the package's non-Go source files, - // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on. - OtherFiles []string - - // EmbedFiles lists the absolute file paths of the package's files - // embedded with go:embed. - EmbedFiles []string - - // EmbedPatterns lists the absolute file patterns of the package's - // files embedded with go:embed. - EmbedPatterns []string - - // IgnoredFiles lists source files that are not part of the package - // using the current build configuration but that might be part of - // the package using other build configurations. - IgnoredFiles []string - - // ExportFile is the absolute path to a file containing type - // information for the package as provided by the build system. - ExportFile string - - // Target is the absolute install path of the .a file, for libraries, - // and of the executable file, for binaries. - Target string - - // Imports maps import paths appearing in the package's Go source files - // to corresponding loaded Packages. - Imports map[string]*Package - - // Module is the module information for the package if it exists. - // - // Note: it may be missing for std and cmd; see Go issue #65816. - Module *Module - - // -- The following fields are not part of the driver JSON schema. -- - - // Types provides type information for the package. - // The NeedTypes LoadMode bit sets this field for packages matching the - // patterns; type information for dependencies may be missing or incomplete, - // unless NeedDeps and NeedImports are also set. - // - // Each call to [Load] returns a consistent set of type - // symbols, as defined by the comment at [types.Identical]. - // Avoid mixing type information from two or more calls to [Load]. - Types *types.Package `json:"-"` - - // Fset provides position information for Types, TypesInfo, and Syntax. - // It is set only when Types is set. - Fset *token.FileSet `json:"-"` - - // IllTyped indicates whether the package or any dependency contains errors. - // It is set only when Types is set. - IllTyped bool `json:"-"` - - // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles. - // - // The NeedSyntax LoadMode bit populates this field for packages matching the patterns. - // If NeedDeps and NeedImports are also set, this field will also be populated - // for dependencies. - // - // Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are - // removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles. - Syntax []*ast.File `json:"-"` - - // TypesInfo provides type information about the package's syntax trees. - // It is set only when Syntax is set. - TypesInfo *types.Info `json:"-"` - - // TypesSizes provides the effective size function for types in TypesInfo. - TypesSizes types.Sizes `json:"-"` - - // -- internal -- - - // ForTest is the package under test, if any. - ForTest string - - // depsErrors is the DepsErrors field from the go list response, if any. - depsErrors []*packagesinternal.PackageError -} - -// Module provides module information for a package. -// -// It also defines part of the JSON schema of [DriverResponse]. -// See the package documentation for an overview. -type Module struct { - Path string // module path - Version string // module version - Replace *Module // replaced by this module - Time *time.Time // time version was created - Main bool // is this the main module? - Indirect bool // is this module only an indirect dependency of main module? - Dir string // directory holding files for this module, if any - GoMod string // path to go.mod file used when loading this module, if any - GoVersion string // go version used in module - Error *ModuleError // error loading module -} - -// ModuleError holds errors loading a module. -type ModuleError struct { - Err string // the error itself -} - -func init() { - packagesinternal.GetDepsErrors = func(p any) []*packagesinternal.PackageError { - return p.(*Package).depsErrors - } - packagesinternal.TypecheckCgo = int(typecheckCgo) - packagesinternal.DepsErrors = int(needInternalDepsErrors) -} - -// An Error describes a problem with a package's metadata, syntax, or types. -type Error struct { - Pos string // "file:line:col" or "file:line" or "" or "-" - Msg string - Kind ErrorKind -} - -// ErrorKind describes the source of the error, allowing the user to -// differentiate between errors generated by the driver, the parser, or the -// type-checker. -type ErrorKind int - -const ( - UnknownError ErrorKind = iota - ListError - ParseError - TypeError -) - -func (err Error) Error() string { - pos := err.Pos - if pos == "" { - pos = "-" // like token.Position{}.String() - } - return pos + ": " + err.Msg -} - -// flatPackage is the JSON form of Package -// It drops all the type and syntax fields, and transforms the Imports -// -// TODO(adonovan): identify this struct with Package, effectively -// publishing the JSON protocol. -type flatPackage struct { - ID string - Name string `json:",omitempty"` - PkgPath string `json:",omitempty"` - Errors []Error `json:",omitempty"` - GoFiles []string `json:",omitempty"` - CompiledGoFiles []string `json:",omitempty"` - OtherFiles []string `json:",omitempty"` - EmbedFiles []string `json:",omitempty"` - EmbedPatterns []string `json:",omitempty"` - IgnoredFiles []string `json:",omitempty"` - ExportFile string `json:",omitempty"` - Imports map[string]string `json:",omitempty"` -} - -// MarshalJSON returns the Package in its JSON form. -// For the most part, the structure fields are written out unmodified, and -// the type and syntax fields are skipped. -// The imports are written out as just a map of path to package id. -// The errors are written using a custom type that tries to preserve the -// structure of error types we know about. -// -// This method exists to enable support for additional build systems. It is -// not intended for use by clients of the API and we may change the format. -func (p *Package) MarshalJSON() ([]byte, error) { - flat := &flatPackage{ - ID: p.ID, - Name: p.Name, - PkgPath: p.PkgPath, - Errors: p.Errors, - GoFiles: p.GoFiles, - CompiledGoFiles: p.CompiledGoFiles, - OtherFiles: p.OtherFiles, - EmbedFiles: p.EmbedFiles, - EmbedPatterns: p.EmbedPatterns, - IgnoredFiles: p.IgnoredFiles, - ExportFile: p.ExportFile, - } - if len(p.Imports) > 0 { - flat.Imports = make(map[string]string, len(p.Imports)) - for path, ipkg := range p.Imports { - flat.Imports[path] = ipkg.ID - } - } - return json.Marshal(flat) -} - -// UnmarshalJSON reads in a Package from its JSON format. -// See MarshalJSON for details about the format accepted. -func (p *Package) UnmarshalJSON(b []byte) error { - flat := &flatPackage{} - if err := json.Unmarshal(b, &flat); err != nil { - return err - } - *p = Package{ - ID: flat.ID, - Name: flat.Name, - PkgPath: flat.PkgPath, - Errors: flat.Errors, - GoFiles: flat.GoFiles, - CompiledGoFiles: flat.CompiledGoFiles, - OtherFiles: flat.OtherFiles, - EmbedFiles: flat.EmbedFiles, - EmbedPatterns: flat.EmbedPatterns, - IgnoredFiles: flat.IgnoredFiles, - ExportFile: flat.ExportFile, - } - if len(flat.Imports) > 0 { - p.Imports = make(map[string]*Package, len(flat.Imports)) - for path, id := range flat.Imports { - p.Imports[path] = &Package{ID: id} - } - } - return nil -} - -func (p *Package) String() string { return p.ID } - -// loaderPackage augments Package with state used during the loading phase -type loaderPackage struct { - *Package - importErrors map[string]error // maps each bad import to its error - preds []*loaderPackage // packages that import this one - unfinishedSuccs atomic.Int32 // number of direct imports not yet loaded - color uint8 // for cycle detection - needsrc bool // load from source (Mode >= LoadTypes) - needtypes bool // type information is either requested or depended on - initial bool // package was matched by a pattern - goVersion int // minor version number of go command on PATH -} - -// loader holds the working state of a single call to load. -type loader struct { - pkgs map[string]*loaderPackage // keyed by Package.ID - Config - sizes types.Sizes // non-nil if needed by mode - parseCache map[string]*parseValue - parseCacheMu sync.Mutex - exportMu sync.Mutex // enforces mutual exclusion of exportdata operations - externalDriver bool // true if an external GOPACKAGESDRIVER handled the request - - // Config.Mode contains the implied mode (see impliedLoadMode). - // Implied mode contains all the fields we need the data for. - // In requestedMode there are the actually requested fields. - // We'll zero them out before returning packages to the user. - // This makes it easier for us to get the conditions where - // we need certain modes right. - requestedMode LoadMode -} - -type parseValue struct { - f *ast.File - err error - ready chan struct{} -} - -func newLoader(cfg *Config) *loader { - ld := &loader{ - parseCache: map[string]*parseValue{}, - } - if cfg != nil { - ld.Config = *cfg - // If the user has provided a logger, use it. - ld.Config.Logf = cfg.Logf - } - if ld.Config.Logf == nil { - // If the GOPACKAGESDEBUG environment variable is set to true, - // but the user has not provided a logger, default to log.Printf. - if debug { - ld.Config.Logf = log.Printf - } else { - ld.Config.Logf = func(format string, args ...any) {} - } - } - if ld.Config.Mode == 0 { - ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility. - } - if ld.Config.Env == nil { - ld.Config.Env = os.Environ() - } - if ld.Context == nil { - ld.Context = context.Background() - } - if ld.Dir == "" { - if dir, err := os.Getwd(); err == nil { - ld.Dir = dir - } - } - - // Save the actually requested fields. We'll zero them out before returning packages to the user. - ld.requestedMode = ld.Mode - ld.Mode = impliedLoadMode(ld.Mode) - - if ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0 { - if ld.Fset == nil { - ld.Fset = token.NewFileSet() - } - - // ParseFile is required even in LoadTypes mode - // because we load source if export data is missing. - if ld.ParseFile == nil { - ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { - // We implicitly promise to keep doing ast.Object resolution. :( - const mode = parser.AllErrors | parser.ParseComments - return parser.ParseFile(fset, filename, src, mode) - } - } - } - - return ld -} - -// refine connects the supplied packages into a graph and then adds type -// and syntax information as requested by the LoadMode. -func (ld *loader) refine(response *DriverResponse) ([]*Package, error) { - roots := response.Roots - rootMap := make(map[string]int, len(roots)) - for i, root := range roots { - rootMap[root] = i - } - ld.pkgs = make(map[string]*loaderPackage) - // first pass, fixup and build the map and roots - var initial = make([]*loaderPackage, len(roots)) - for _, pkg := range response.Packages { - rootIndex := -1 - if i, found := rootMap[pkg.ID]; found { - rootIndex = i - } - - // Overlays can invalidate export data. - // TODO(matloob): make this check fine-grained based on dependencies on overlaid files - exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe" - // This package needs type information if the caller requested types and the package is - // either a root, or it's a non-root and the user requested dependencies ... - needtypes := (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) - // This package needs source if the call requested source (or types info, which implies source) - // and the package is either a root, or itas a non- root and the user requested dependencies... - needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) || - // ... or if we need types and the exportData is invalid. We fall back to (incompletely) - // typechecking packages from source if they fail to compile. - (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe" - lpkg := &loaderPackage{ - Package: pkg, - needtypes: needtypes, - needsrc: needsrc, - goVersion: response.GoVersion, - } - ld.pkgs[lpkg.ID] = lpkg - if rootIndex >= 0 { - initial[rootIndex] = lpkg - lpkg.initial = true - } - } - for i, root := range roots { - if initial[i] == nil { - return nil, fmt.Errorf("root package %v is missing", root) - } - } - - // Materialize the import graph if it is needed (NeedImports), - // or if we'll be using loadPackages (Need{Syntax|Types|TypesInfo}). - var leaves []*loaderPackage // packages with no unfinished successors - if ld.Mode&(NeedImports|NeedSyntax|NeedTypes|NeedTypesInfo) != 0 { - const ( - white = 0 // new - grey = 1 // in progress - black = 2 // complete - ) - - // visit traverses the import graph, depth-first, - // and materializes the graph as Packages.Imports. - // - // Valid imports are saved in the Packages.Import map. - // Invalid imports (cycles and missing nodes) are saved in the importErrors map. - // Thus, even in the presence of both kinds of errors, - // the Import graph remains a DAG. - // - // visit returns whether the package needs src or has a transitive - // dependency on a package that does. These are the only packages - // for which we load source code. - var stack []*loaderPackage - var visit func(from, lpkg *loaderPackage) bool - visit = func(from, lpkg *loaderPackage) bool { - if lpkg.color == grey { - panic("internal error: grey node") - } - if lpkg.color == white { - lpkg.color = grey - stack = append(stack, lpkg) // push - stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports - lpkg.Imports = make(map[string]*Package, len(stubs)) - for importPath, ipkg := range stubs { - var importErr error - imp := ld.pkgs[ipkg.ID] - if imp == nil { - // (includes package "C" when DisableCgo) - importErr = fmt.Errorf("missing package: %q", ipkg.ID) - } else if imp.color == grey { - importErr = fmt.Errorf("import cycle: %s", stack) - } - if importErr != nil { - if lpkg.importErrors == nil { - lpkg.importErrors = make(map[string]error) - } - lpkg.importErrors[importPath] = importErr - continue - } - - if visit(lpkg, imp) { - lpkg.needsrc = true - } - lpkg.Imports[importPath] = imp.Package - } - - // -- postorder -- - - // Complete type information is required for the - // immediate dependencies of each source package. - if lpkg.needsrc && ld.Mode&NeedTypes != 0 { - for _, ipkg := range lpkg.Imports { - ld.pkgs[ipkg.ID].needtypes = true - } - } - - // NeedTypeSizes causes TypeSizes to be set even - // on packages for which types aren't needed. - if ld.Mode&NeedTypesSizes != 0 { - lpkg.TypesSizes = ld.sizes - } - - // Add packages with no imports directly to the queue of leaves. - if len(lpkg.Imports) == 0 { - leaves = append(leaves, lpkg) - } - - stack = stack[:len(stack)-1] // pop - lpkg.color = black - } - - // Add edge from predecessor. - if from != nil { - from.unfinishedSuccs.Add(+1) // incref - lpkg.preds = append(lpkg.preds, from) - } - - return lpkg.needsrc - } - - // For each initial package, create its import DAG. - for _, lpkg := range initial { - visit(nil, lpkg) - } - - } else { - // !NeedImports: drop the stub (ID-only) import packages - // that we are not even going to try to resolve. - for _, lpkg := range initial { - lpkg.Imports = nil - } - } - - // Load type data and syntax if needed, starting at - // the initial packages (roots of the import DAG). - if ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0 { - - // We avoid using g.SetLimit to limit concurrency as - // it makes g.Go stop accepting work, which prevents - // workers from enqeuing, and thus finishing, and thus - // allowing the group to make progress: deadlock. - // - // Instead we use the ioLimit and cpuLimit semaphores. - g, _ := errgroup.WithContext(ld.Context) - - // enqueues adds a package to the type-checking queue. - // It must have no unfinished successors. - var enqueue func(*loaderPackage) - enqueue = func(lpkg *loaderPackage) { - g.Go(func() error { - // Parse and type-check. - ld.loadPackage(lpkg) - - // Notify each waiting predecessor, - // and enqueue it when it becomes a leaf. - for _, pred := range lpkg.preds { - if pred.unfinishedSuccs.Add(-1) == 0 { // decref - enqueue(pred) - } - } - - return nil - }) - } - - // Load leaves first, adding new packages - // to the queue as they become leaves. - for _, leaf := range leaves { - enqueue(leaf) - } - - if err := g.Wait(); err != nil { - return nil, err // cancelled - } - } - - // If the context is done, return its error and - // throw out [likely] incomplete packages. - if err := ld.Context.Err(); err != nil { - return nil, err - } - - result := make([]*Package, len(initial)) - for i, lpkg := range initial { - result[i] = lpkg.Package - } - for i := range ld.pkgs { - // Clear all unrequested fields, - // to catch programs that use more than they request. - if ld.requestedMode&NeedName == 0 { - ld.pkgs[i].Name = "" - ld.pkgs[i].PkgPath = "" - } - if ld.requestedMode&NeedFiles == 0 { - ld.pkgs[i].GoFiles = nil - ld.pkgs[i].OtherFiles = nil - ld.pkgs[i].IgnoredFiles = nil - } - if ld.requestedMode&NeedEmbedFiles == 0 { - ld.pkgs[i].EmbedFiles = nil - } - if ld.requestedMode&NeedEmbedPatterns == 0 { - ld.pkgs[i].EmbedPatterns = nil - } - if ld.requestedMode&NeedCompiledGoFiles == 0 { - ld.pkgs[i].CompiledGoFiles = nil - } - if ld.requestedMode&NeedImports == 0 { - ld.pkgs[i].Imports = nil - } - if ld.requestedMode&NeedExportFile == 0 { - ld.pkgs[i].ExportFile = "" - } - if ld.requestedMode&NeedTypes == 0 { - ld.pkgs[i].Types = nil - ld.pkgs[i].IllTyped = false - } - if ld.requestedMode&NeedSyntax == 0 { - ld.pkgs[i].Syntax = nil - } - if ld.requestedMode&(NeedSyntax|NeedTypes|NeedTypesInfo) == 0 { - ld.pkgs[i].Fset = nil - } - if ld.requestedMode&NeedTypesInfo == 0 { - ld.pkgs[i].TypesInfo = nil - } - if ld.requestedMode&NeedTypesSizes == 0 { - ld.pkgs[i].TypesSizes = nil - } - if ld.requestedMode&NeedModule == 0 { - ld.pkgs[i].Module = nil - } - } - - return result, nil -} - -// loadPackage loads/parses/typechecks the specified package. -// It must be called only once per Package, -// after immediate dependencies are loaded. -// Precondition: ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0. -func (ld *loader) loadPackage(lpkg *loaderPackage) { - if lpkg.PkgPath == "unsafe" { - // To avoid surprises, fill in the blanks consistent - // with other packages. (For example, some analyzers - // assert that each needed types.Info map is non-nil - // even when there is no syntax that would cause them - // to consult the map.) - lpkg.Types = types.Unsafe - lpkg.Fset = ld.Fset - lpkg.Syntax = []*ast.File{} - lpkg.TypesInfo = ld.newTypesInfo() - lpkg.TypesSizes = ld.sizes - return - } - - // Call NewPackage directly with explicit name. - // This avoids skew between golist and go/types when the files' - // package declarations are inconsistent. - lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name) - lpkg.Fset = ld.Fset - - // Start shutting down if the context is done and do not load - // source or export data files. - // Packages that import this one will have ld.Context.Err() != nil. - // ld.Context.Err() will be returned later by refine. - if ld.Context.Err() != nil { - return - } - - // Subtle: we populate all Types fields with an empty Package - // before loading export data so that export data processing - // never has to create a types.Package for an indirect dependency, - // which would then require that such created packages be explicitly - // inserted back into the Import graph as a final step after export data loading. - // (Hence this return is after the Types assignment.) - // The Diamond test exercises this case. - if !lpkg.needtypes && !lpkg.needsrc { - return - } - - // TODO(adonovan): this condition looks wrong: - // I think it should be lpkg.needtypes && !lpg.needsrc, - // so that NeedSyntax without NeedTypes can be satisfied by export data. - if !lpkg.needsrc { - if err := ld.loadFromExportData(lpkg); err != nil { - lpkg.Errors = append(lpkg.Errors, Error{ - Pos: "-", - Msg: err.Error(), - Kind: UnknownError, // e.g. can't find/open/parse export data - }) - } - return // not a source package, don't get syntax trees - } - - appendError := func(err error) { - // Convert various error types into the one true Error. - var errs []Error - switch err := err.(type) { - case Error: - // from driver - errs = append(errs, err) - - case *os.PathError: - // from parser - errs = append(errs, Error{ - Pos: err.Path + ":1", - Msg: err.Err.Error(), - Kind: ParseError, - }) - - case scanner.ErrorList: - // from parser - for _, err := range err { - errs = append(errs, Error{ - Pos: err.Pos.String(), - Msg: err.Msg, - Kind: ParseError, - }) - } - - case types.Error: - // from type checker - lpkg.TypeErrors = append(lpkg.TypeErrors, err) - errs = append(errs, Error{ - Pos: err.Fset.Position(err.Pos).String(), - Msg: err.Msg, - Kind: TypeError, - }) - - default: - // unexpected impoverished error from parser? - errs = append(errs, Error{ - Pos: "-", - Msg: err.Error(), - Kind: UnknownError, - }) - - // If you see this error message, please file a bug. - log.Printf("internal error: error %q (%T) without position", err, err) - } - - lpkg.Errors = append(lpkg.Errors, errs...) - } - - // If the go command on the PATH is newer than the runtime, - // then the go/{scanner,ast,parser,types} packages from the - // standard library may be unable to process the files - // selected by go list. - // - // There is currently no way to downgrade the effective - // version of the go command (see issue 52078), so we proceed - // with the newer go command but, in case of parse or type - // errors, we emit an additional diagnostic. - // - // See: - // - golang.org/issue/52078 (flag to set release tags) - // - golang.org/issue/50825 (gopls legacy version support) - // - golang.org/issue/55883 (go/packages confusing error) - // - // Should we assert a hard minimum of (currently) go1.16 here? - var runtimeVersion int - if _, err := fmt.Sscanf(runtime.Version(), "go1.%d", &runtimeVersion); err == nil && runtimeVersion < lpkg.goVersion { - defer func() { - if len(lpkg.Errors) > 0 { - appendError(Error{ - Pos: "-", - Msg: fmt.Sprintf("This application uses version go1.%d of the source-processing packages but runs version go1.%d of 'go list'. It may fail to process source files that rely on newer language features. If so, rebuild the application using a newer version of Go.", runtimeVersion, lpkg.goVersion), - Kind: UnknownError, - }) - } - }() - } - - if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" { - // The config requested loading sources and types, but sources are missing. - // Add an error to the package and fall back to loading from export data. - appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError}) - _ = ld.loadFromExportData(lpkg) // ignore any secondary errors - - return // can't get syntax trees for this package - } - - files, errs := ld.parseFiles(lpkg.CompiledGoFiles) - for _, err := range errs { - appendError(err) - } - - lpkg.Syntax = files - if ld.Config.Mode&(NeedTypes|NeedTypesInfo) == 0 { - return - } - - // Start shutting down if the context is done and do not type check. - // Packages that import this one will have ld.Context.Err() != nil. - // ld.Context.Err() will be returned later by refine. - if ld.Context.Err() != nil { - return - } - - lpkg.TypesInfo = ld.newTypesInfo() - lpkg.TypesSizes = ld.sizes - - importer := importerFunc(func(path string) (*types.Package, error) { - if path == "unsafe" { - return types.Unsafe, nil - } - - // The imports map is keyed by import path. - ipkg := lpkg.Imports[path] - if ipkg == nil { - if err := lpkg.importErrors[path]; err != nil { - return nil, err - } - // There was skew between the metadata and the - // import declarations, likely due to an edit - // race, or because the ParseFile feature was - // used to supply alternative file contents. - return nil, fmt.Errorf("no metadata for %s", path) - } - - if ipkg.Types != nil && ipkg.Types.Complete() { - return ipkg.Types, nil - } - log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg) - panic("unreachable") - }) - - // type-check - tc := &types.Config{ - Importer: importer, - - // Type-check bodies of functions only in initial packages. - // Example: for import graph A->B->C and initial packages {A,C}, - // we can ignore function bodies in B. - IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial, - - Error: appendError, - Sizes: ld.sizes, // may be nil - } - if lpkg.Module != nil && lpkg.Module.GoVersion != "" { - tc.GoVersion = "go" + lpkg.Module.GoVersion - } else if ld.externalDriver && lpkg.goVersion != 0 { - // Module information is missing when GOPACKAGESDRIVER is used, - // so use the go version from the driver response. - tc.GoVersion = fmt.Sprintf("go1.%d", lpkg.goVersion) - } - if (ld.Mode & typecheckCgo) != 0 { - if !typesinternal.SetUsesCgo(tc) { - appendError(Error{ - Msg: "typecheckCgo requires Go 1.15+", - Kind: ListError, - }) - return - } - } - - // Type-checking is CPU intensive. - cpuLimit <- unit{} // acquire a token - defer func() { <-cpuLimit }() // release a token - - typErr := types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) - lpkg.importErrors = nil // no longer needed - - // In go/types go1.21 and go1.22, Checker.Files failed fast with a - // a "too new" error, without calling tc.Error and without - // proceeding to type-check the package (#66525). - // We rely on the runtimeVersion error to give the suggested remedy. - if typErr != nil && len(lpkg.Errors) == 0 && len(lpkg.Syntax) > 0 { - if msg := typErr.Error(); strings.HasPrefix(msg, "package requires newer Go version") { - appendError(types.Error{ - Fset: ld.Fset, - Pos: lpkg.Syntax[0].Package, - Msg: msg, - }) - } - } - - // If !Cgo, the type-checker uses FakeImportC mode, so - // it doesn't invoke the importer for import "C", - // nor report an error for the import, - // or for any undefined C.f reference. - // We must detect this explicitly and correctly - // mark the package as IllTyped (by reporting an error). - // TODO(adonovan): if these errors are annoying, - // we could just set IllTyped quietly. - if tc.FakeImportC { - outer: - for _, f := range lpkg.Syntax { - for _, imp := range f.Imports { - if imp.Path.Value == `"C"` { - err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`} - appendError(err) - break outer - } - } - } - } - - // If types.Checker.Files had an error that was unreported, - // make sure to report the unknown error so the package is illTyped. - if typErr != nil && len(lpkg.Errors) == 0 { - appendError(typErr) - } - - // Record accumulated errors. - illTyped := len(lpkg.Errors) > 0 - if !illTyped { - for _, imp := range lpkg.Imports { - if imp.IllTyped { - illTyped = true - break - } - } - } - lpkg.IllTyped = illTyped -} - -func (ld *loader) newTypesInfo() *types.Info { - // Populate TypesInfo only if needed, as it - // causes the type checker to work much harder. - if ld.Config.Mode&NeedTypesInfo == 0 { - return nil - } - return &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Instances: make(map[*ast.Ident]types.Instance), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - FileVersions: make(map[*ast.File]string), - } -} - -// An importFunc is an implementation of the single-method -// types.Importer interface based on a function value. -type importerFunc func(path string) (*types.Package, error) - -func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } - -// We use a counting semaphore to limit -// the number of parallel I/O calls or CPU threads per process. -var ( - ioLimit = make(chan unit, 20) - cpuLimit = make(chan unit, runtime.GOMAXPROCS(0)) -) - -func (ld *loader) parseFile(filename string) (*ast.File, error) { - ld.parseCacheMu.Lock() - v, ok := ld.parseCache[filename] - if ok { - // cache hit - ld.parseCacheMu.Unlock() - <-v.ready - } else { - // cache miss - v = &parseValue{ready: make(chan struct{})} - ld.parseCache[filename] = v - ld.parseCacheMu.Unlock() - - var src []byte - for f, contents := range ld.Config.Overlay { - // TODO(adonovan): Inefficient for large overlays. - // Do an exact name-based map lookup - // (for nonexistent files) followed by a - // FileID-based map lookup (for existing ones). - if sameFile(f, filename) { - src = contents - break - } - } - var err error - if src == nil { - ioLimit <- unit{} // acquire a token - src, err = os.ReadFile(filename) - <-ioLimit // release a token - } - if err != nil { - v.err = err - } else { - // Parsing is CPU intensive. - cpuLimit <- unit{} // acquire a token - v.f, v.err = ld.ParseFile(ld.Fset, filename, src) - <-cpuLimit // release a token - } - - close(v.ready) - } - return v.f, v.err -} - -// parseFiles reads and parses the Go source files and returns the ASTs -// of the ones that could be at least partially parsed, along with a -// list of I/O and parse errors encountered. -// -// Because files are scanned in parallel, the token.Pos -// positions of the resulting ast.Files are not ordered. -func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { - var ( - n = len(filenames) - parsed = make([]*ast.File, n) - errors = make([]error, n) - ) - var g errgroup.Group - for i, filename := range filenames { - // This creates goroutines unnecessarily in the - // cache-hit case, but that case is uncommon. - g.Go(func() error { - parsed[i], errors[i] = ld.parseFile(filename) - return nil - }) - } - g.Wait() - - // Eliminate nils, preserving order. - var o int - for _, f := range parsed { - if f != nil { - parsed[o] = f - o++ - } - } - parsed = parsed[:o] - - o = 0 - for _, err := range errors { - if err != nil { - errors[o] = err - o++ - } - } - errors = errors[:o] - - return parsed, errors -} - -// sameFile returns true if x and y have the same basename and denote -// the same file. -func sameFile(x, y string) bool { - if x == y { - // It could be the case that y doesn't exist. - // For instance, it may be an overlay file that - // hasn't been written to disk. To handle that case - // let x == y through. (We added the exact absolute path - // string to the CompiledGoFiles list, so the unwritten - // overlay case implies x==y.) - return true - } - if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation) - if xi, err := os.Stat(x); err == nil { - if yi, err := os.Stat(y); err == nil { - return os.SameFile(xi, yi) - } - } - } - return false -} - -// loadFromExportData ensures that type information is present for the specified -// package, loading it from an export data file on the first request. -// On success it sets lpkg.Types to a new Package. -func (ld *loader) loadFromExportData(lpkg *loaderPackage) error { - if lpkg.PkgPath == "" { - log.Fatalf("internal error: Package %s has no PkgPath", lpkg) - } - - // Because gcexportdata.Read has the potential to create or - // modify the types.Package for each node in the transitive - // closure of dependencies of lpkg, all exportdata operations - // must be sequential. (Finer-grained locking would require - // changes to the gcexportdata API.) - // - // The exportMu lock guards the lpkg.Types field and the - // types.Package it points to, for each loaderPackage in the graph. - // - // Not all accesses to Package.Pkg need to be protected by exportMu: - // graph ordering ensures that direct dependencies of source - // packages are fully loaded before the importer reads their Pkg field. - ld.exportMu.Lock() - defer ld.exportMu.Unlock() - - if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() { - return nil // cache hit - } - - lpkg.IllTyped = true // fail safe - - if lpkg.ExportFile == "" { - // Errors while building export data will have been printed to stderr. - return fmt.Errorf("no export data file") - } - f, err := os.Open(lpkg.ExportFile) - if err != nil { - return err - } - defer f.Close() - - // Read gc export data. - // - // We don't currently support gccgo export data because all - // underlying workspaces use the gc toolchain. (Even build - // systems that support gccgo don't use it for workspace - // queries.) - r, err := gcexportdata.NewReader(f) - if err != nil { - return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) - } - - // Build the view. - // - // The gcexportdata machinery has no concept of package ID. - // It identifies packages by their PkgPath, which although not - // globally unique is unique within the scope of one invocation - // of the linker, type-checker, or gcexportdata. - // - // So, we must build a PkgPath-keyed view of the global - // (conceptually ID-keyed) cache of packages and pass it to - // gcexportdata. The view must contain every existing - // package that might possibly be mentioned by the - // current package---its transitive closure. - // - // In loadPackage, we unconditionally create a types.Package for - // each dependency so that export data loading does not - // create new ones. - // - // TODO(adonovan): it would be simpler and more efficient - // if the export data machinery invoked a callback to - // get-or-create a package instead of a map. - // - view := make(map[string]*types.Package) // view seen by gcexportdata - seen := make(map[*loaderPackage]bool) // all visited packages - var visit func(pkgs map[string]*Package) - visit = func(pkgs map[string]*Package) { - for _, p := range pkgs { - lpkg := ld.pkgs[p.ID] - if !seen[lpkg] { - seen[lpkg] = true - view[lpkg.PkgPath] = lpkg.Types - visit(lpkg.Imports) - } - } - } - visit(lpkg.Imports) - - viewLen := len(view) + 1 // adding the self package - // Parse the export data. - // (May modify incomplete packages in view but not create new ones.) - tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath) - if err != nil { - return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) - } - if _, ok := view["go.shape"]; ok { - // Account for the pseudopackage "go.shape" that gets - // created by generic code. - viewLen++ - } - if viewLen != len(view) { - log.Panicf("golang.org/x/tools/go/packages: unexpected new packages during load of %s", lpkg.PkgPath) - } - - lpkg.Types = tpkg - lpkg.IllTyped = false - return nil -} - -// impliedLoadMode returns loadMode with its dependencies. -func impliedLoadMode(loadMode LoadMode) LoadMode { - if loadMode&(NeedDeps|NeedTypes|NeedTypesInfo) != 0 { - // All these things require knowing the import graph. - loadMode |= NeedImports - } - if loadMode&NeedTypes != 0 { - // Types require the GoVersion from Module. - loadMode |= NeedModule - } - - return loadMode -} - -func usesExportData(cfg *Config) bool { - return cfg.Mode&NeedExportFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0 -} - -type unit struct{} diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go deleted file mode 100644 index c546b1b6..00000000 --- a/vendor/golang.org/x/tools/go/packages/visit.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2018 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 packages - -import ( - "cmp" - "fmt" - "iter" - "os" - "slices" -) - -// Visit visits all the packages in the import graph whose roots are -// pkgs, calling the optional pre function the first time each package -// is encountered (preorder), and the optional post function after a -// package's dependencies have been visited (postorder). -// The boolean result of pre(pkg) determines whether -// the imports of package pkg are visited. -// -// Example: -// -// pkgs, err := Load(...) -// if err != nil { ... } -// Visit(pkgs, nil, func(pkg *Package) { -// log.Println(pkg) -// }) -// -// In most cases, it is more convenient to use [Postorder]: -// -// for pkg := range Postorder(pkgs) { -// log.Println(pkg) -// } -func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { - seen := make(map[*Package]bool) - var visit func(*Package) - visit = func(pkg *Package) { - if !seen[pkg] { - seen[pkg] = true - - if pre == nil || pre(pkg) { - for _, imp := range sorted(pkg.Imports) { // for determinism - visit(imp) - } - } - - if post != nil { - post(pkg) - } - } - } - for _, pkg := range pkgs { - visit(pkg) - } -} - -// PrintErrors prints to os.Stderr the accumulated errors of all -// packages in the import graph rooted at pkgs, dependencies first. -// PrintErrors returns the number of errors printed. -func PrintErrors(pkgs []*Package) int { - var n int - errModules := make(map[*Module]bool) - for pkg := range Postorder(pkgs) { - for _, err := range pkg.Errors { - fmt.Fprintln(os.Stderr, err) - n++ - } - - // Print pkg.Module.Error once if present. - mod := pkg.Module - if mod != nil && mod.Error != nil && !errModules[mod] { - errModules[mod] = true - fmt.Fprintln(os.Stderr, mod.Error.Err) - n++ - } - } - return n -} - -// Postorder returns an iterator over the packages in -// the import graph whose roots are pkg. -// Packages are enumerated in dependencies-first order. -func Postorder(pkgs []*Package) iter.Seq[*Package] { - return func(yield func(*Package) bool) { - seen := make(map[*Package]bool) - var visit func(*Package) bool - visit = func(pkg *Package) bool { - if !seen[pkg] { - seen[pkg] = true - for _, imp := range sorted(pkg.Imports) { // for determinism - if !visit(imp) { - return false - } - } - if !yield(pkg) { - return false - } - } - return true - } - for _, pkg := range pkgs { - if !visit(pkg) { - break - } - } - } -} - -// -- copied from golang.org.x/tools/gopls/internal/util/moremaps -- - -// sorted returns an iterator over the entries of m in key order. -func sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] { - // TODO(adonovan): use maps.Sorted if proposal #68598 is accepted. - return func(yield func(K, V) bool) { - keys := keySlice(m) - slices.Sort(keys) - for _, k := range keys { - if !yield(k, m[k]) { - break - } - } - } -} - -// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)). -func keySlice[M ~map[K]V, K comparable, V any](m M) []K { - r := make([]K, 0, len(m)) - for k := range m { - r = append(r, k) - } - return r -} diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go deleted file mode 100644 index 77aad553..00000000 --- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go +++ /dev/null @@ -1,816 +0,0 @@ -// Copyright 2018 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 objectpath defines a naming scheme for types.Objects -// (that is, named entities in Go programs) relative to their enclosing -// package. -// -// Type-checker objects are canonical, so they are usually identified by -// their address in memory (a pointer), but a pointer has meaning only -// within one address space. By contrast, objectpath names allow the -// identity of an object to be sent from one program to another, -// establishing a correspondence between types.Object variables that are -// distinct but logically equivalent. -// -// A single object may have multiple paths. In this example, -// -// type A struct{ X int } -// type B A -// -// the field X has two paths due to its membership of both A and B. -// The For(obj) function always returns one of these paths, arbitrarily -// but consistently. -package objectpath - -import ( - "fmt" - "go/types" - "strconv" - "strings" - - "golang.org/x/tools/internal/typesinternal" -) - -// TODO(adonovan): think about generic aliases. - -// A Path is an opaque name that identifies a types.Object -// relative to its package. Conceptually, the name consists of a -// sequence of destructuring operations applied to the package scope -// to obtain the original object. -// The name does not include the package itself. -type Path string - -// Encoding -// -// An object path is a textual and (with training) human-readable encoding -// of a sequence of destructuring operators, starting from a types.Package. -// The sequences represent a path through the package/object/type graph. -// We classify these operators by their type: -// -// PO package->object Package.Scope.Lookup -// OT object->type Object.Type -// TT type->type Type.{Elem,Key,{,{,Recv}Type}Params,Results,Underlying,Rhs} [EKPRUTrCa] -// TO type->object Type.{At,Field,Method,Obj} [AFMO] -// -// All valid paths start with a package and end at an object -// and thus may be defined by the regular language: -// -// objectpath = PO (OT TT* TO)* -// -// The concrete encoding follows directly: -// - The only PO operator is Package.Scope.Lookup, which requires an identifier. -// - The only OT operator is Object.Type, -// which we encode as '.' because dot cannot appear in an identifier. -// - The TT operators are encoded as [EKPRUTrCa]; -// two of these ({,Recv}TypeParams) require an integer operand, -// which is encoded as a string of decimal digits. -// - The TO operators are encoded as [AFMO]; -// three of these (At,Field,Method) require an integer operand, -// which is encoded as a string of decimal digits. -// These indices are stable across different representations -// of the same package, even source and export data. -// The indices used are implementation specific and may not correspond to -// the argument to the go/types function. -// -// In the example below, -// -// package p -// -// type T interface { -// f() (a string, b struct{ X int }) -// } -// -// field X has the path "T.UM0.RA1.F0", -// representing the following sequence of operations: -// -// p.Lookup("T") T -// .Type().Underlying().Method(0). f -// .Type().Results().At(1) b -// .Type().Field(0) X -// -// The encoding is not maximally compact---every R or P is -// followed by an A, for example---but this simplifies the -// encoder and decoder. -const ( - // object->type operators - opType = '.' // .Type() (Object) - - // type->type operators - opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map) - opKey = 'K' // .Key() (Map) - opParams = 'P' // .Params() (Signature) - opResults = 'R' // .Results() (Signature) - opUnderlying = 'U' // .Underlying() (Named) - opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature) - opRecvTypeParam = 'r' // .RecvTypeParams.At(i) (Signature) - opConstraint = 'C' // .Constraint() (TypeParam) - opRhs = 'a' // .Rhs() (Alias) - - // type->object operators - opAt = 'A' // .At(i) (Tuple) - opField = 'F' // .Field(i) (Struct) - opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored) - opObj = 'O' // .Obj() (Named, TypeParam) -) - -// For is equivalent to new(Encoder).For(obj). -// -// It may be more efficient to reuse a single Encoder across several calls. -func For(obj types.Object) (Path, error) { - return new(Encoder).For(obj) -} - -// An Encoder amortizes the cost of encoding the paths of multiple objects. -// The zero value of an Encoder is ready to use. -type Encoder struct { - scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects -} - -// For returns the path to an object relative to its package, -// or an error if the object is not accessible from the package's Scope. -// -// The For function guarantees to return a path only for the following objects: -// - package-level types -// - exported package-level non-types -// - methods -// - parameter and result variables -// - struct fields -// These objects are sufficient to define the API of their package. -// The objects described by a package's export data are drawn from this set. -// -// The set of objects accessible from a package's Scope depends on -// whether the package was produced by type-checking syntax, or -// reading export data; the latter may have a smaller Scope since -// export data trims objects that are not reachable from an exported -// declaration. For example, the For function will return a path for -// an exported method of an unexported type that is not reachable -// from any public declaration; this path will cause the Object -// function to fail if called on a package loaded from export data. -// TODO(adonovan): is this a bug or feature? Should this package -// compute accessibility in the same way? -// -// For does not return a path for predeclared names, imported package -// names, local names, and unexported package-level names (except -// types). -// -// Example: given this definition, -// -// package p -// -// type T interface { -// f() (a string, b struct{ X int }) -// } -// -// For(X) would return a path that denotes the following sequence of operations: -// -// p.Scope().Lookup("T") (TypeName T) -// .Type().Underlying().Method(0). (method Func f) -// .Type().Results().At(1) (field Var b) -// .Type().Field(0) (field Var X) -// -// where p is the package (*types.Package) to which X belongs. -func (enc *Encoder) For(obj types.Object) (Path, error) { - pkg := obj.Pkg() - - // This table lists the cases of interest. - // - // Object Action - // ------ ------ - // nil reject - // builtin reject - // pkgname reject - // label reject - // var - // package-level accept - // func param/result accept - // local reject - // struct field accept - // const - // package-level accept - // local reject - // func - // package-level accept - // init functions reject - // concrete method accept - // interface method accept - // type - // package-level accept - // local reject - // - // The only accessible package-level objects are members of pkg itself. - // - // The cases are handled in four steps: - // - // 1. reject nil and builtin - // 2. accept package-level objects - // 3. reject obviously invalid objects - // 4. search the API for the path to the param/result/field/method. - - // 1. reference to nil or builtin? - if pkg == nil { - return "", fmt.Errorf("predeclared %s has no path", obj) - } - scope := pkg.Scope() - - // 2. package-level object? - if scope.Lookup(obj.Name()) == obj { - // Only exported objects (and non-exported types) have a path. - // Non-exported types may be referenced by other objects. - if _, ok := obj.(*types.TypeName); !ok && !obj.Exported() { - return "", fmt.Errorf("no path for non-exported %v", obj) - } - return Path(obj.Name()), nil - } - - // 3. Not a package-level object. - // Reject obviously non-viable cases. - switch obj := obj.(type) { - case *types.TypeName: - if _, ok := types.Unalias(obj.Type()).(*types.TypeParam); !ok { - // With the exception of type parameters, only package-level type names - // have a path. - return "", fmt.Errorf("no path for %v", obj) - } - case *types.Const, // Only package-level constants have a path. - *types.Label, // Labels are function-local. - *types.PkgName: // PkgNames are file-local. - return "", fmt.Errorf("no path for %v", obj) - - case *types.Var: - // Could be: - // - a field (obj.IsField()) - // - a func parameter or result - // - a local var. - // Sadly there is no way to distinguish - // a param/result from a local - // so we must proceed to the find. - - case *types.Func: - // A func, if not package-level, must be a method. - if recv := obj.Signature().Recv(); recv == nil { - return "", fmt.Errorf("func is not a method: %v", obj) - } - - if path, ok := enc.concreteMethod(obj); ok { - // Fast path for concrete methods that avoids looping over scope. - return path, nil - } - - default: - panic(obj) - } - - // 4. Search the API for the path to the var (field/param/result) or method. - - // First inspect package-level named types. - // In the presence of path aliases, these give - // the best paths because non-types may - // refer to types, but not the reverse. - empty := make([]byte, 0, 48) // initial space - objs := enc.scopeObjects(scope) - for _, o := range objs { - tname, ok := o.(*types.TypeName) - if !ok { - continue // handle non-types in second pass - } - - path := append(empty, o.Name()...) - path = append(path, opType) - - T := o.Type() - if alias, ok := T.(*types.Alias); ok { - if r := findTypeParam(obj, alias.TypeParams(), path, opTypeParam); r != nil { - return Path(r), nil - } - if r := find(obj, alias.Rhs(), append(path, opRhs)); r != nil { - return Path(r), nil - } - - } else if tname.IsAlias() { - // legacy alias - if r := find(obj, T, path); r != nil { - return Path(r), nil - } - - } else if named, ok := T.(*types.Named); ok { - // defined (named) type - if r := findTypeParam(obj, named.TypeParams(), path, opTypeParam); r != nil { - return Path(r), nil - } - if r := find(obj, named.Underlying(), append(path, opUnderlying)); r != nil { - return Path(r), nil - } - } - } - - // Then inspect everything else: - // non-types, and declared methods of defined types. - for _, o := range objs { - path := append(empty, o.Name()...) - if _, ok := o.(*types.TypeName); !ok { - if o.Exported() { - // exported non-type (const, var, func) - if r := find(obj, o.Type(), append(path, opType)); r != nil { - return Path(r), nil - } - } - continue - } - - // Inspect declared methods of defined types. - if T, ok := types.Unalias(o.Type()).(*types.Named); ok { - path = append(path, opType) - // The method index here is always with respect - // to the underlying go/types data structures, - // which ultimately derives from source order - // and must be preserved by export data. - for i := 0; i < T.NumMethods(); i++ { - m := T.Method(i) - path2 := appendOpArg(path, opMethod, i) - if m == obj { - return Path(path2), nil // found declared method - } - if r := find(obj, m.Type(), append(path2, opType)); r != nil { - return Path(r), nil - } - } - } - } - - return "", fmt.Errorf("can't find path for %v in %s", obj, pkg.Path()) -} - -func appendOpArg(path []byte, op byte, arg int) []byte { - path = append(path, op) - path = strconv.AppendInt(path, int64(arg), 10) - return path -} - -// concreteMethod returns the path for meth, which must have a non-nil receiver. -// The second return value indicates success and may be false if the method is -// an interface method or if it is an instantiated method. -// -// This function is just an optimization that avoids the general scope walking -// approach. You are expected to fall back to the general approach if this -// function fails. -func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) { - // Concrete methods can only be declared on package-scoped named types. For - // that reason we can skip the expensive walk over the package scope: the - // path will always be package -> named type -> method. We can trivially get - // the type name from the receiver, and only have to look over the type's - // methods to find the method index. - // - // Methods on generic types require special consideration, however. Consider - // the following package: - // - // L1: type S[T any] struct{} - // L2: func (recv S[A]) Foo() { recv.Bar() } - // L3: func (recv S[B]) Bar() { } - // L4: type Alias = S[int] - // L5: func _[T any]() { var s S[int]; s.Foo() } - // - // The receivers of methods on generic types are instantiations. L2 and L3 - // instantiate S with the type-parameters A and B, which are scoped to the - // respective methods. L4 and L5 each instantiate S with int. Each of these - // instantiations has its own method set, full of methods (and thus objects) - // with receivers whose types are the respective instantiations. In other - // words, we have - // - // S[A].Foo, S[A].Bar - // S[B].Foo, S[B].Bar - // S[int].Foo, S[int].Bar - // - // We may thus be trying to produce object paths for any of these objects. - // - // S[A].Foo and S[B].Bar are the origin methods, and their paths are S.Foo - // and S.Bar, which are the paths that this function naturally produces. - // - // S[A].Bar, S[B].Foo, and both methods on S[int] are instantiations that - // don't correspond to the origin methods. For S[int], this is significant. - // The most precise object path for S[int].Foo, for example, is Alias.Foo, - // not S.Foo. Our function, however, would produce S.Foo, which would - // resolve to a different object. - // - // For S[A].Bar and S[B].Foo it could be argued that S.Bar and S.Foo are - // still the correct paths, since only the origin methods have meaningful - // paths. But this is likely only true for trivial cases and has edge cases. - // Since this function is only an optimization, we err on the side of giving - // up, deferring to the slower but definitely correct algorithm. Most users - // of objectpath will only be giving us origin methods, anyway, as referring - // to instantiated methods is usually not useful. - - if meth.Origin() != meth { - return "", false - } - - _, named := typesinternal.ReceiverNamed(meth.Signature().Recv()) - if named == nil { - return "", false - } - - if types.IsInterface(named) { - // Named interfaces don't have to be package-scoped - // - // TODO(dominikh): opt: if scope.Lookup(name) == named, then we can apply this optimization to interface - // methods, too, I think. - return "", false - } - - // Preallocate space for the name, opType, opMethod, and some digits. - name := named.Obj().Name() - path := make([]byte, 0, len(name)+8) - path = append(path, name...) - path = append(path, opType) - - // Method indices are w.r.t. the go/types data structures, - // ultimately deriving from source order, - // which is preserved by export data. - for i := 0; i < named.NumMethods(); i++ { - if named.Method(i) == meth { - path = appendOpArg(path, opMethod, i) - return Path(path), true - } - } - - // Due to golang/go#59944, go/types fails to associate the receiver with - // certain methods on cgo types. - // - // TODO(rfindley): replace this panic once golang/go#59944 is fixed in all Go - // versions gopls supports. - return "", false - // panic(fmt.Sprintf("couldn't find method %s on type %s; methods: %#v", meth, named, enc.namedMethods(named))) -} - -// find finds obj within type T, returning the path to it, or nil if not found. -// -// The seen map is used to short circuit cycles through type parameters. If -// nil, it will be allocated as necessary. -// -// The seenMethods map is used internally to short circuit cycles through -// interface methods, such as occur in the following example: -// -// type I interface { f() interface{I} } -// -// See golang/go#68046 for details. -func find(obj types.Object, T types.Type, path []byte) []byte { - return (&finder{obj: obj}).find(T, path) -} - -// finder closes over search state for a call to find. -type finder struct { - obj types.Object // the sought object - seenTParamNames map[*types.TypeName]bool // for cycle breaking through type parameters - seenMethods map[*types.Func]bool // for cycle breaking through recursive interfaces -} - -func (f *finder) find(T types.Type, path []byte) []byte { - switch T := T.(type) { - case *types.Alias: - return f.find(types.Unalias(T), path) - case *types.Basic, *types.Named: - // Named types belonging to pkg were handled already, - // so T must belong to another package. No path. - return nil - case *types.Pointer: - return f.find(T.Elem(), append(path, opElem)) - case *types.Slice: - return f.find(T.Elem(), append(path, opElem)) - case *types.Array: - return f.find(T.Elem(), append(path, opElem)) - case *types.Chan: - return f.find(T.Elem(), append(path, opElem)) - case *types.Map: - if r := f.find(T.Key(), append(path, opKey)); r != nil { - return r - } - return f.find(T.Elem(), append(path, opElem)) - case *types.Signature: - if r := f.findTypeParam(T.RecvTypeParams(), path, opRecvTypeParam); r != nil { - return r - } - if r := f.findTypeParam(T.TypeParams(), path, opTypeParam); r != nil { - return r - } - if r := f.find(T.Params(), append(path, opParams)); r != nil { - return r - } - return f.find(T.Results(), append(path, opResults)) - case *types.Struct: - for i := 0; i < T.NumFields(); i++ { - fld := T.Field(i) - path2 := appendOpArg(path, opField, i) - if fld == f.obj { - return path2 // found field var - } - if r := f.find(fld.Type(), append(path2, opType)); r != nil { - return r - } - } - return nil - case *types.Tuple: - for i := 0; i < T.Len(); i++ { - v := T.At(i) - path2 := appendOpArg(path, opAt, i) - if v == f.obj { - return path2 // found param/result var - } - if r := f.find(v.Type(), append(path2, opType)); r != nil { - return r - } - } - return nil - case *types.Interface: - for i := 0; i < T.NumMethods(); i++ { - m := T.Method(i) - if f.seenMethods[m] { - continue // break cycles (see TestIssue70418) - } - path2 := appendOpArg(path, opMethod, i) - if m == f.obj { - return path2 // found interface method - } - if f.seenMethods == nil { - f.seenMethods = make(map[*types.Func]bool) - } - f.seenMethods[m] = true - if r := f.find(m.Type(), append(path2, opType)); r != nil { - return r - } - } - return nil - case *types.TypeParam: - name := T.Obj() - if f.seenTParamNames[name] { - return nil - } - if name == f.obj { - return append(path, opObj) - } - if f.seenTParamNames == nil { - f.seenTParamNames = make(map[*types.TypeName]bool) - } - f.seenTParamNames[name] = true - if r := f.find(T.Constraint(), append(path, opConstraint)); r != nil { - return r - } - return nil - } - panic(T) -} - -func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, op byte) []byte { - return (&finder{obj: obj}).findTypeParam(list, path, op) -} - -func (f *finder) findTypeParam(list *types.TypeParamList, path []byte, op byte) []byte { - for i := 0; i < list.Len(); i++ { - tparam := list.At(i) - path2 := appendOpArg(path, op, i) - if r := f.find(tparam, path2); r != nil { - return r - } - } - return nil -} - -// Object returns the object denoted by path p within the package pkg. -func Object(pkg *types.Package, p Path) (types.Object, error) { - pathstr := string(p) - if pathstr == "" { - return nil, fmt.Errorf("empty path") - } - - var pkgobj, suffix string - if dot := strings.IndexByte(pathstr, opType); dot < 0 { - pkgobj = pathstr - } else { - pkgobj = pathstr[:dot] - suffix = pathstr[dot:] // suffix starts with "." - } - - obj := pkg.Scope().Lookup(pkgobj) - if obj == nil { - return nil, fmt.Errorf("package %s does not contain %q", pkg.Path(), pkgobj) - } - - // abstraction of *types.{Pointer,Slice,Array,Chan,Map} - type hasElem interface { - Elem() types.Type - } - // abstraction of *types.{Named,Signature} - type hasTypeParams interface { - TypeParams() *types.TypeParamList - } - // abstraction of *types.{Alias,Named,TypeParam} - type hasObj interface { - Obj() *types.TypeName - } - - // The loop state is the pair (t, obj), - // exactly one of which is non-nil, initially obj. - // All suffixes start with '.' (the only object->type operation), - // followed by optional type->type operations, - // then a type->object operation. - // The cycle then repeats. - var t types.Type - for suffix != "" { - code := suffix[0] - suffix = suffix[1:] - - // Codes [AFMTr] have an integer operand. - var index int - switch code { - case opAt, opField, opMethod, opTypeParam, opRecvTypeParam: - rest := strings.TrimLeft(suffix, "0123456789") - numerals := suffix[:len(suffix)-len(rest)] - suffix = rest - i, err := strconv.Atoi(numerals) - if err != nil { - return nil, fmt.Errorf("invalid path: bad numeric operand %q for code %q", numerals, code) - } - index = int(i) - case opObj: - // no operand - default: - // The suffix must end with a type->object operation. - if suffix == "" { - return nil, fmt.Errorf("invalid path: ends with %q, want [AFMO]", code) - } - } - - if code == opType { - if t != nil { - return nil, fmt.Errorf("invalid path: unexpected %q in type context", opType) - } - t = obj.Type() - obj = nil - continue - } - - if t == nil { - return nil, fmt.Errorf("invalid path: code %q in object context", code) - } - - // Inv: t != nil, obj == nil - - t = types.Unalias(t) - switch code { - case opElem: - hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want pointer, slice, array, chan or map)", code, t, t) - } - t = hasElem.Elem() - - case opKey: - mapType, ok := t.(*types.Map) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want map)", code, t, t) - } - t = mapType.Key() - - case opParams: - sig, ok := t.(*types.Signature) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) - } - t = sig.Params() - - case opResults: - sig, ok := t.(*types.Signature) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) - } - t = sig.Results() - - case opUnderlying: - named, ok := t.(*types.Named) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named)", code, t, t) - } - t = named.Underlying() - - case opRhs: - if alias, ok := t.(*types.Alias); ok { - t = alias.Rhs() - } else if false { - // Now that go1.24 is assured, we should be able to - // replace this with "if true {", but it causes objectpath - // tests to fail. TODO(adonovan): investigate. - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want alias)", code, t, t) - } - - case opTypeParam: - hasTypeParams, ok := t.(hasTypeParams) // Named, Signature - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or signature)", code, t, t) - } - tparams := hasTypeParams.TypeParams() - if n := tparams.Len(); index >= n { - return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) - } - t = tparams.At(index) - - case opRecvTypeParam: - sig, ok := t.(*types.Signature) // Signature - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) - } - rtparams := sig.RecvTypeParams() - if n := rtparams.Len(); index >= n { - return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) - } - t = rtparams.At(index) - - case opConstraint: - tparam, ok := t.(*types.TypeParam) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t) - } - t = tparam.Constraint() - - case opAt: - tuple, ok := t.(*types.Tuple) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want tuple)", code, t, t) - } - if n := tuple.Len(); index >= n { - return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) - } - obj = tuple.At(index) - t = nil - - case opField: - structType, ok := t.(*types.Struct) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want struct)", code, t, t) - } - if n := structType.NumFields(); index >= n { - return nil, fmt.Errorf("field index %d out of range [0-%d)", index, n) - } - obj = structType.Field(index) - t = nil - - case opMethod: - switch t := t.(type) { - case *types.Interface: - if index >= t.NumMethods() { - return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) - } - obj = t.Method(index) // Id-ordered - - case *types.Named: - if index >= t.NumMethods() { - return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods()) - } - obj = t.Method(index) - - default: - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t) - } - t = nil - - case opObj: - hasObj, ok := t.(hasObj) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or type param)", code, t, t) - } - obj = hasObj.Obj() - t = nil - - default: - return nil, fmt.Errorf("invalid path: unknown code %q", code) - } - } - - if obj == nil { - panic(p) // path does not end in an object-valued operator - } - - if obj.Pkg() != pkg { - return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj) - } - - return obj, nil // success -} - -// scopeObjects is a memoization of scope objects. -// Callers must not modify the result. -func (enc *Encoder) scopeObjects(scope *types.Scope) []types.Object { - m := enc.scopeMemo - if m == nil { - m = make(map[*types.Scope][]types.Object) - enc.scopeMemo = m - } - objs, ok := m[scope] - if !ok { - names := scope.Names() // allocates and sorts - objs = make([]types.Object, len(names)) - for i, name := range names { - objs[i] = scope.Lookup(name) - } - m[scope] = objs - } - return objs -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/callee.go b/vendor/golang.org/x/tools/go/types/typeutil/callee.go deleted file mode 100644 index 3d24a8c6..00000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/callee.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2018 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 typeutil - -import ( - "go/ast" - "go/types" - _ "unsafe" // for linkname -) - -// Callee returns the named target of a function call, if any: -// a function, method, builtin, or variable. -// It returns nil for a T(x) conversion. -// -// Functions and methods may potentially have type parameters. -// -// Note: for calls of instantiated functions and methods, Callee returns -// the corresponding generic function or method on the generic type. -func Callee(info *types.Info, call *ast.CallExpr) types.Object { - obj := info.Uses[usedIdent(info, call.Fun)] - if obj == nil { - return nil - } - if _, ok := obj.(*types.TypeName); ok { - return nil - } - return obj -} - -// StaticCallee returns the target (function or method) of a static function -// call, if any. It returns nil for calls to builtins. -// -// Note: for calls of instantiated functions and methods, StaticCallee returns -// the corresponding generic function or method on the generic type. -func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { - obj := info.Uses[usedIdent(info, call.Fun)] - fn, _ := obj.(*types.Func) - if fn == nil || interfaceMethod(fn) { - return nil - } - return fn -} - -// usedIdent is the implementation of [internal/typesinternal.UsedIdent]. -// It returns the identifier associated with e. -// See typesinternal.UsedIdent for a fuller description. -// This function should live in typesinternal, but cannot because it would -// create an import cycle. -// -//go:linkname usedIdent golang.org/x/tools/go/types/typeutil.usedIdent -func usedIdent(info *types.Info, e ast.Expr) *ast.Ident { - if info.Types == nil || info.Uses == nil { - panic("one of info.Types or info.Uses is nil; both must be populated") - } - // Look through type instantiation if necessary. - switch d := ast.Unparen(e).(type) { - case *ast.IndexExpr: - if info.Types[d.Index].IsType() { - e = d.X - } - case *ast.IndexListExpr: - e = d.X - } - - switch e := ast.Unparen(e).(type) { - // info.Uses always has the object we want, even for selector expressions. - // We don't need info.Selections. - // See go/types/recording.go:recordSelection. - case *ast.Ident: - return e - case *ast.SelectorExpr: - return e.Sel - } - return nil -} - -// interfaceMethod reports whether its argument is a method of an interface. -// This function should live in typesinternal, but cannot because it would create an import cycle. -// -//go:linkname interfaceMethod golang.org/x/tools/go/types/typeutil.interfaceMethod -func interfaceMethod(f *types.Func) bool { - recv := f.Signature().Recv() - return recv != nil && types.IsInterface(recv.Type()) -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/imports.go b/vendor/golang.org/x/tools/go/types/typeutil/imports.go deleted file mode 100644 index b81ce0c3..00000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/imports.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 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 typeutil - -import "go/types" - -// Dependencies returns all dependencies of the specified packages. -// -// Dependent packages appear in topological order: if package P imports -// package Q, Q appears earlier than P in the result. -// The algorithm follows import statements in the order they -// appear in the source code, so the result is a total order. -func Dependencies(pkgs ...*types.Package) []*types.Package { - var result []*types.Package - seen := make(map[*types.Package]bool) - var visit func(pkgs []*types.Package) - visit = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !seen[p] { - seen[p] = true - visit(p.Imports()) - result = append(result, p) - } - } - } - visit(pkgs) - return result -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/map.go b/vendor/golang.org/x/tools/go/types/typeutil/map.go deleted file mode 100644 index 36624572..00000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/map.go +++ /dev/null @@ -1,459 +0,0 @@ -// Copyright 2014 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 typeutil defines various utilities for types, such as [Map], -// a hash table that maps [types.Type] to any value. -package typeutil - -import ( - "bytes" - "fmt" - "go/types" - "hash/maphash" - - "golang.org/x/tools/internal/typeparams" -) - -// Map is a hash-table-based mapping from types (types.Type) to -// arbitrary values. The concrete types that implement -// the Type interface are pointers. Since they are not canonicalized, -// == cannot be used to check for equivalence, and thus we cannot -// simply use a Go map. -// -// Just as with map[K]V, a nil *Map is a valid empty map. -// -// Read-only map operations ([Map.At], [Map.Len], and so on) may -// safely be called concurrently. -// -// TODO(adonovan): deprecate in favor of https://go.dev/issues/69420 -// and 69559, if the latter proposals for a generic hash-map type and -// a types.Hash function are accepted. -type Map struct { - table map[uint32][]entry // maps hash to bucket; entry.key==nil means unused - length int // number of map entries -} - -// entry is an entry (key/value association) in a hash bucket. -type entry struct { - key types.Type - value any -} - -// SetHasher has no effect. -// -// It is a relic of an optimization that is no longer profitable. Do -// not use [Hasher], [MakeHasher], or [SetHasher] in new code. -func (m *Map) SetHasher(Hasher) {} - -// Delete removes the entry with the given key, if any. -// It returns true if the entry was found. -func (m *Map) Delete(key types.Type) bool { - if m != nil && m.table != nil { - hash := hash(key) - bucket := m.table[hash] - for i, e := range bucket { - if e.key != nil && types.Identical(key, e.key) { - // We can't compact the bucket as it - // would disturb iterators. - bucket[i] = entry{} - m.length-- - return true - } - } - } - return false -} - -// At returns the map entry for the given key. -// The result is nil if the entry is not present. -func (m *Map) At(key types.Type) any { - if m != nil && m.table != nil { - for _, e := range m.table[hash(key)] { - if e.key != nil && types.Identical(key, e.key) { - return e.value - } - } - } - return nil -} - -// Set sets the map entry for key to val, -// and returns the previous entry, if any. -func (m *Map) Set(key types.Type, value any) (prev any) { - if m.table != nil { - hash := hash(key) - bucket := m.table[hash] - var hole *entry - for i, e := range bucket { - if e.key == nil { - hole = &bucket[i] - } else if types.Identical(key, e.key) { - prev = e.value - bucket[i].value = value - return - } - } - - if hole != nil { - *hole = entry{key, value} // overwrite deleted entry - } else { - m.table[hash] = append(bucket, entry{key, value}) - } - } else { - hash := hash(key) - m.table = map[uint32][]entry{hash: {entry{key, value}}} - } - - m.length++ - return -} - -// Len returns the number of map entries. -func (m *Map) Len() int { - if m != nil { - return m.length - } - return 0 -} - -// Iterate calls function f on each entry in the map in unspecified order. -// -// If f should mutate the map, Iterate provides the same guarantees as -// Go maps: if f deletes a map entry that Iterate has not yet reached, -// f will not be invoked for it, but if f inserts a map entry that -// Iterate has not yet reached, whether or not f will be invoked for -// it is unspecified. -func (m *Map) Iterate(f func(key types.Type, value any)) { - if m != nil { - for _, bucket := range m.table { - for _, e := range bucket { - if e.key != nil { - f(e.key, e.value) - } - } - } - } -} - -// Keys returns a new slice containing the set of map keys. -// The order is unspecified. -func (m *Map) Keys() []types.Type { - keys := make([]types.Type, 0, m.Len()) - m.Iterate(func(key types.Type, _ any) { - keys = append(keys, key) - }) - return keys -} - -func (m *Map) toString(values bool) string { - if m == nil { - return "{}" - } - var buf bytes.Buffer - fmt.Fprint(&buf, "{") - sep := "" - m.Iterate(func(key types.Type, value any) { - fmt.Fprint(&buf, sep) - sep = ", " - fmt.Fprint(&buf, key) - if values { - fmt.Fprintf(&buf, ": %q", value) - } - }) - fmt.Fprint(&buf, "}") - return buf.String() -} - -// String returns a string representation of the map's entries. -// Values are printed using fmt.Sprintf("%v", v). -// Order is unspecified. -func (m *Map) String() string { - return m.toString(true) -} - -// KeysString returns a string representation of the map's key set. -// Order is unspecified. -func (m *Map) KeysString() string { - return m.toString(false) -} - -// -- Hasher -- - -// hash returns the hash of type t. -// TODO(adonovan): replace by types.Hash when Go proposal #69420 is accepted. -func hash(t types.Type) uint32 { - return theHasher.Hash(t) -} - -// A Hasher provides a [Hasher.Hash] method to map a type to its hash value. -// Hashers are stateless, and all are equivalent. -type Hasher struct{} - -var theHasher Hasher - -// MakeHasher returns Hasher{}. -// Hashers are stateless; all are equivalent. -func MakeHasher() Hasher { return theHasher } - -// Hash computes a hash value for the given type t such that -// Identical(t, t') => Hash(t) == Hash(t'). -func (h Hasher) Hash(t types.Type) uint32 { - return hasher{inGenericSig: false}.hash(t) -} - -// hasher holds the state of a single Hash traversal: whether we are -// inside the signature of a generic function; this is used to -// optimize [hasher.hashTypeParam]. -type hasher struct{ inGenericSig bool } - -// hashString computes the Fowler–Noll–Vo hash of s. -func hashString(s string) uint32 { - var h uint32 - for i := 0; i < len(s); i++ { - h ^= uint32(s[i]) - h *= 16777619 - } - return h -} - -// hash computes the hash of t. -func (h hasher) hash(t types.Type) uint32 { - // See Identical for rationale. - switch t := t.(type) { - case *types.Basic: - return uint32(t.Kind()) - - case *types.Alias: - return h.hash(types.Unalias(t)) - - case *types.Array: - return 9043 + 2*uint32(t.Len()) + 3*h.hash(t.Elem()) - - case *types.Slice: - return 9049 + 2*h.hash(t.Elem()) - - case *types.Struct: - var hash uint32 = 9059 - for i, n := 0, t.NumFields(); i < n; i++ { - f := t.Field(i) - if f.Anonymous() { - hash += 8861 - } - hash += hashString(t.Tag(i)) - hash += hashString(f.Name()) // (ignore f.Pkg) - hash += h.hash(f.Type()) - } - return hash - - case *types.Pointer: - return 9067 + 2*h.hash(t.Elem()) - - case *types.Signature: - var hash uint32 = 9091 - if t.Variadic() { - hash *= 8863 - } - - tparams := t.TypeParams() - if n := tparams.Len(); n > 0 { - h.inGenericSig = true // affects constraints, params, and results - - for i := range n { - tparam := tparams.At(i) - hash += 7 * h.hash(tparam.Constraint()) - } - } - - return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results()) - - case *types.Union: - return h.hashUnion(t) - - case *types.Interface: - // Interfaces are identical if they have the same set of methods, with - // identical names and types, and they have the same set of type - // restrictions. See go/types.identical for more details. - var hash uint32 = 9103 - - // Hash methods. - for i, n := 0, t.NumMethods(); i < n; i++ { - // Method order is not significant. - // Ignore m.Pkg(). - m := t.Method(i) - // Use shallow hash on method signature to - // avoid anonymous interface cycles. - hash += 3*hashString(m.Name()) + 5*h.shallowHash(m.Type()) - } - - // Hash type restrictions. - terms, err := typeparams.InterfaceTermSet(t) - // if err != nil t has invalid type restrictions. - if err == nil { - hash += h.hashTermSet(terms) - } - - return hash - - case *types.Map: - return 9109 + 2*h.hash(t.Key()) + 3*h.hash(t.Elem()) - - case *types.Chan: - return 9127 + 2*uint32(t.Dir()) + 3*h.hash(t.Elem()) - - case *types.Named: - hash := h.hashTypeName(t.Obj()) - targs := t.TypeArgs() - for targ := range targs.Types() { - hash += 2 * h.hash(targ) - } - return hash - - case *types.TypeParam: - return h.hashTypeParam(t) - - case *types.Tuple: - return h.hashTuple(t) - } - - panic(fmt.Sprintf("%T: %v", t, t)) -} - -func (h hasher) hashTuple(tuple *types.Tuple) uint32 { - // See go/types.identicalTypes for rationale. - n := tuple.Len() - hash := 9137 + 2*uint32(n) - for i := range n { - hash += 3 * h.hash(tuple.At(i).Type()) - } - return hash -} - -func (h hasher) hashUnion(t *types.Union) uint32 { - // Hash type restrictions. - terms, err := typeparams.UnionTermSet(t) - // if err != nil t has invalid type restrictions. Fall back on a non-zero - // hash. - if err != nil { - return 9151 - } - return h.hashTermSet(terms) -} - -func (h hasher) hashTermSet(terms []*types.Term) uint32 { - hash := 9157 + 2*uint32(len(terms)) - for _, term := range terms { - // term order is not significant. - termHash := h.hash(term.Type()) - if term.Tilde() { - termHash *= 9161 - } - hash += 3 * termHash - } - return hash -} - -// hashTypeParam returns the hash of a type parameter. -func (h hasher) hashTypeParam(t *types.TypeParam) uint32 { - // Within the signature of a generic function, TypeParams are - // identical if they have the same index and constraint, so we - // hash them based on index. - // - // When we are outside a generic function, free TypeParams are - // identical iff they are the same object, so we can use a - // more discriminating hash consistent with object identity. - // This optimization saves [Map] about 4% when hashing all the - // types.Info.Types in the forward closure of net/http. - if !h.inGenericSig { - // Optimization: outside a generic function signature, - // use a more discrimating hash consistent with object identity. - return h.hashTypeName(t.Obj()) - } - return 9173 + 3*uint32(t.Index()) -} - -var theSeed = maphash.MakeSeed() - -// hashTypeName hashes the pointer of tname. -func (hasher) hashTypeName(tname *types.TypeName) uint32 { - // Since types.Identical uses == to compare TypeNames, - // the Hash function uses maphash.Comparable. - hash := maphash.Comparable(theSeed, tname) - return uint32(hash ^ (hash >> 32)) -} - -// shallowHash computes a hash of t without looking at any of its -// element Types, to avoid potential anonymous cycles in the types of -// interface methods. -// -// When an unnamed non-empty interface type appears anywhere among the -// arguments or results of an interface method, there is a potential -// for endless recursion. Consider: -// -// type X interface { m() []*interface { X } } -// -// The problem is that the Methods of the interface in m's result type -// include m itself; there is no mention of the named type X that -// might help us break the cycle. -// (See comment in go/types.identical, case *Interface, for more.) -func (h hasher) shallowHash(t types.Type) uint32 { - // t is the type of an interface method (Signature), - // its params or results (Tuples), or their immediate - // elements (mostly Slice, Pointer, Basic, Named), - // so there's no need to optimize anything else. - switch t := t.(type) { - case *types.Alias: - return h.shallowHash(types.Unalias(t)) - - case *types.Signature: - var hash uint32 = 604171 - if t.Variadic() { - hash *= 971767 - } - // The Signature/Tuple recursion is always finite - // and invariably shallow. - return hash + 1062599*h.shallowHash(t.Params()) + 1282529*h.shallowHash(t.Results()) - - case *types.Tuple: - n := t.Len() - hash := 9137 + 2*uint32(n) - for i := range n { - hash += 53471161 * h.shallowHash(t.At(i).Type()) - } - return hash - - case *types.Basic: - return 45212177 * uint32(t.Kind()) - - case *types.Array: - return 1524181 + 2*uint32(t.Len()) - - case *types.Slice: - return 2690201 - - case *types.Struct: - return 3326489 - - case *types.Pointer: - return 4393139 - - case *types.Union: - return 562448657 - - case *types.Interface: - return 2124679 // no recursion here - - case *types.Map: - return 9109 - - case *types.Chan: - return 9127 - - case *types.Named: - return h.hashTypeName(t.Obj()) - - case *types.TypeParam: - return h.hashTypeParam(t) - } - panic(fmt.Sprintf("shallowHash: %T: %v", t, t)) -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go b/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go deleted file mode 100644 index f7666028..00000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements a cache of method sets. - -package typeutil - -import ( - "go/types" - "sync" -) - -// A MethodSetCache records the method set of each type T for which -// MethodSet(T) is called so that repeat queries are fast. -// The zero value is a ready-to-use cache instance. -type MethodSetCache struct { - mu sync.Mutex - named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N - others map[types.Type]*types.MethodSet // all other types -} - -// MethodSet returns the method set of type T. It is thread-safe. -// -// If cache is nil, this function is equivalent to types.NewMethodSet(T). -// Utility functions can thus expose an optional *MethodSetCache -// parameter to clients that care about performance. -func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet { - if cache == nil { - return types.NewMethodSet(T) - } - cache.mu.Lock() - defer cache.mu.Unlock() - - switch T := types.Unalias(T).(type) { - case *types.Named: - return cache.lookupNamed(T).value - - case *types.Pointer: - if N, ok := types.Unalias(T.Elem()).(*types.Named); ok { - return cache.lookupNamed(N).pointer - } - } - - // all other types - // (The map uses pointer equivalence, not type identity.) - mset := cache.others[T] - if mset == nil { - mset = types.NewMethodSet(T) - if cache.others == nil { - cache.others = make(map[types.Type]*types.MethodSet) - } - cache.others[T] = mset - } - return mset -} - -func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } { - if cache.named == nil { - cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet }) - } - // Avoid recomputing mset(*T) for each distinct Pointer - // instance whose underlying type is a named type. - msets, ok := cache.named[named] - if !ok { - msets.value = types.NewMethodSet(named) - msets.pointer = types.NewMethodSet(types.NewPointer(named)) - cache.named[named] = msets - } - return msets -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/ui.go b/vendor/golang.org/x/tools/go/types/typeutil/ui.go deleted file mode 100644 index 9dda6a25..00000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/ui.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014 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 typeutil - -// This file defines utilities for user interfaces that display types. - -import ( - "go/types" -) - -// IntuitiveMethodSet returns the intuitive method set of a type T, -// which is the set of methods you can call on an addressable value of -// that type. -// -// The result always contains MethodSet(T), and is exactly MethodSet(T) -// for interface types and for pointer-to-concrete types. -// For all other concrete types T, the result additionally -// contains each method belonging to *T if there is no identically -// named method on T itself. -// -// This corresponds to user intuition about method sets; -// this function is intended only for user interfaces. -// -// The order of the result is as for types.MethodSet(T). -func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { - isPointerToConcrete := func(T types.Type) bool { - ptr, ok := types.Unalias(T).(*types.Pointer) - return ok && !types.IsInterface(ptr.Elem()) - } - - var result []*types.Selection - mset := msets.MethodSet(T) - if types.IsInterface(T) || isPointerToConcrete(T) { - for i, n := 0, mset.Len(); i < n; i++ { - result = append(result, mset.At(i)) - } - } else { - // T is some other concrete type. - // Report methods of T and *T, preferring those of T. - pmset := msets.MethodSet(types.NewPointer(T)) - for i, n := 0, pmset.Len(); i < n; i++ { - meth := pmset.At(i) - if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { - meth = m - } - result = append(result, meth) - } - - } - return result -} diff --git a/vendor/golang.org/x/tools/imports/forward.go b/vendor/golang.org/x/tools/imports/forward.go deleted file mode 100644 index 5d120d07..00000000 --- a/vendor/golang.org/x/tools/imports/forward.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2019 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 imports implements a Go pretty-printer (like package "go/format") -// that also adds or removes import statements as necessary. -package imports // import "golang.org/x/tools/imports" - -import ( - "log" - "os" - - "golang.org/x/tools/internal/gocommand" - intimp "golang.org/x/tools/internal/imports" -) - -// Options specifies options for processing files. -type Options struct { - Fragment bool // Accept fragment of a source file (no package statement) - AllErrors bool // Report all errors (not just the first 10 on different lines) - - Comments bool // Print comments (true if nil *Options provided) - TabIndent bool // Use tabs for indent (true if nil *Options provided) - TabWidth int // Tab width (8 if nil *Options provided) - - FormatOnly bool // Disable the insertion and deletion of imports -} - -// Debug controls verbose logging. -var Debug = false - -// LocalPrefix is a comma-separated string of import path prefixes, which, if -// set, instructs Process to sort the import paths with the given prefixes -// into another group after 3rd-party packages. -var LocalPrefix string - -// Process formats and adjusts imports for the provided file. -// If opt is nil the defaults are used, and if src is nil the source -// is read from the filesystem. -// -// Note that filename's directory influences which imports can be chosen, -// so it is important that filename be accurate. -// To process data “as if” it were in filename, pass the data as a non-nil src. -func Process(filename string, src []byte, opt *Options) ([]byte, error) { - var err error - if src == nil { - src, err = os.ReadFile(filename) - if err != nil { - return nil, err - } - } - if opt == nil { - opt = &Options{Comments: true, TabIndent: true, TabWidth: 8} - } - intopt := &intimp.Options{ - Env: &intimp.ProcessEnv{ - GocmdRunner: &gocommand.Runner{}, - }, - LocalPrefix: LocalPrefix, - AllErrors: opt.AllErrors, - Comments: opt.Comments, - FormatOnly: opt.FormatOnly, - Fragment: opt.Fragment, - TabIndent: opt.TabIndent, - TabWidth: opt.TabWidth, - } - if Debug { - intopt.Env.Logf = log.Printf - } - return intimp.Process(filename, src, intopt) -} - -// VendorlessPath returns the devendorized version of the import path ipath. -// For example, VendorlessPath("foo/barbendor/a/b") return "a/b". -func VendorlessPath(ipath string) string { - return intimp.VendorlessPath(ipath) -} diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases.go b/vendor/golang.org/x/tools/internal/aliases/aliases.go deleted file mode 100644 index a4ae04bc..00000000 --- a/vendor/golang.org/x/tools/internal/aliases/aliases.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2024 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 aliases - -import ( - "go/token" - "go/types" -) - -// New creates a new TypeName in Package pkg that -// is an alias for the type rhs. -func New(pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName { - tname := types.NewTypeName(pos, pkg, name, nil) - types.NewAlias(tname, rhs).SetTypeParams(tparams) - return tname -} diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go deleted file mode 100644 index 42c21881..00000000 --- a/vendor/golang.org/x/tools/internal/event/core/event.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2019 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 core provides support for event based telemetry. -package core - -import ( - "fmt" - "iter" - "time" - - "golang.org/x/tools/internal/event/label" -) - -// Event holds the information about an event of note that occurred. -type Event struct { - at time.Time - - // As events are often on the stack, storing the first few labels directly - // in the event can avoid an allocation at all for the very common cases of - // simple events. - // The length needs to be large enough to cope with the majority of events - // but no so large as to cause undue stack pressure. - // A log message with two values will use 3 labels (one for each value and - // one for the message itself). - - static [3]label.Label // inline storage for the first few labels - dynamic []label.Label // dynamically sized storage for remaining labels -} - -func (ev Event) At() time.Time { return ev.at } - -func (ev Event) Format(f fmt.State, r rune) { - if !ev.at.IsZero() { - fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 ")) - } - for l := range ev.Labels() { - fmt.Fprintf(f, "\n\t%v", l) - } -} - -func (ev Event) Valid(index int) bool { - return index >= 0 && index < len(ev.static)+len(ev.dynamic) -} - -func (ev Event) Label(index int) label.Label { - if index < len(ev.static) { - return ev.static[index] - } - return ev.dynamic[index-len(ev.static)] -} - -// Labels returns an iterator over the event's valid labels. -func (ev Event) Labels() iter.Seq[label.Label] { - return func(yield func(label.Label) bool) { - for _, l := range ev.static { - if l.Valid() && !yield(l) { - return - } - } - for _, l := range ev.dynamic { - if l.Valid() && !yield(l) { - return - } - } - } -} - -func (ev Event) Find(key label.Key) label.Label { - for _, l := range ev.static { - if l.Key() == key { - return l - } - } - for _, l := range ev.dynamic { - if l.Key() == key { - return l - } - } - return label.Label{} -} - -func MakeEvent(static [3]label.Label, labels []label.Label) Event { - return Event{ - static: static, - dynamic: labels, - } -} - -// CloneEvent event returns a copy of the event with the time adjusted to at. -func CloneEvent(ev Event, at time.Time) Event { - ev.at = at - return ev -} diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go deleted file mode 100644 index 16ae6bb0..00000000 --- a/vendor/golang.org/x/tools/internal/event/core/export.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2019 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 core - -import ( - "context" - "sync/atomic" - "time" - - "golang.org/x/tools/internal/event/label" -) - -// Exporter is a function that handles events. -// It may return a modified context and event. -type Exporter func(context.Context, Event, label.Map) context.Context - -var exporter atomic.Pointer[Exporter] - -// SetExporter sets the global exporter function that handles all events. -// The exporter is called synchronously from the event call site, so it should -// return quickly so as not to hold up user code. -func SetExporter(e Exporter) { - if e == nil { - // &e is always valid, and so p is always valid, but for the early abort - // of ProcessEvent to be efficient it needs to make the nil check on the - // pointer without having to dereference it, so we make the nil function - // also a nil pointer - exporter.Store(nil) - } else { - exporter.Store(&e) - } -} - -// deliver is called to deliver an event to the supplied exporter. -// it will fill in the time. -func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context { - // add the current time to the event - ev.at = time.Now() - // hand the event off to the current exporter - return exporter(ctx, ev, ev) -} - -// Export is called to deliver an event to the global exporter if set. -func Export(ctx context.Context, ev Event) context.Context { - // get the global exporter and abort early if there is not one - exporterPtr := exporter.Load() - if exporterPtr == nil { - return ctx - } - return deliver(ctx, *exporterPtr, ev) -} - -// ExportPair is called to deliver a start event to the supplied exporter. -// It also returns a function that will deliver the end event to the same -// exporter. -// It will fill in the time. -func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) { - // get the global exporter and abort early if there is not one - exporterPtr := exporter.Load() - if exporterPtr == nil { - return ctx, func() {} - } - ctx = deliver(ctx, *exporterPtr, begin) - return ctx, func() { deliver(ctx, *exporterPtr, end) } -} diff --git a/vendor/golang.org/x/tools/internal/event/core/fast.go b/vendor/golang.org/x/tools/internal/event/core/fast.go deleted file mode 100644 index 06c1d461..00000000 --- a/vendor/golang.org/x/tools/internal/event/core/fast.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2019 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 core - -import ( - "context" - - "golang.org/x/tools/internal/event/keys" - "golang.org/x/tools/internal/event/label" -) - -// Log1 takes a message and one label delivers a log event to the exporter. -// It is a customized version of Print that is faster and does no allocation. -func Log1(ctx context.Context, message string, t1 label.Label) { - Export(ctx, MakeEvent([3]label.Label{ - keys.Msg.Of(message), - t1, - }, nil)) -} - -// Log2 takes a message and two labels and delivers a log event to the exporter. -// It is a customized version of Print that is faster and does no allocation. -func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) { - Export(ctx, MakeEvent([3]label.Label{ - keys.Msg.Of(message), - t1, - t2, - }, nil)) -} - -// Metric1 sends a label event to the exporter with the supplied labels. -func Metric1(ctx context.Context, t1 label.Label) context.Context { - return Export(ctx, MakeEvent([3]label.Label{ - keys.Metric.New(), - t1, - }, nil)) -} - -// Metric2 sends a label event to the exporter with the supplied labels. -func Metric2(ctx context.Context, t1, t2 label.Label) context.Context { - return Export(ctx, MakeEvent([3]label.Label{ - keys.Metric.New(), - t1, - t2, - }, nil)) -} - -// Start1 sends a span start event with the supplied label list to the exporter. -// It also returns a function that will end the span, which should normally be -// deferred. -func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) { - return ExportPair(ctx, - MakeEvent([3]label.Label{ - keys.Start.Of(name), - t1, - }, nil), - MakeEvent([3]label.Label{ - keys.End.New(), - }, nil)) -} - -// Start2 sends a span start event with the supplied label list to the exporter. -// It also returns a function that will end the span, which should normally be -// deferred. -func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) { - return ExportPair(ctx, - MakeEvent([3]label.Label{ - keys.Start.Of(name), - t1, - t2, - }, nil), - MakeEvent([3]label.Label{ - keys.End.New(), - }, nil)) -} diff --git a/vendor/golang.org/x/tools/internal/event/doc.go b/vendor/golang.org/x/tools/internal/event/doc.go deleted file mode 100644 index 5dc6e6ba..00000000 --- a/vendor/golang.org/x/tools/internal/event/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2019 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 event provides a set of packages that cover the main -// concepts of telemetry in an implementation agnostic way. -package event diff --git a/vendor/golang.org/x/tools/internal/event/event.go b/vendor/golang.org/x/tools/internal/event/event.go deleted file mode 100644 index 4d55e577..00000000 --- a/vendor/golang.org/x/tools/internal/event/event.go +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2019 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 event - -import ( - "context" - - "golang.org/x/tools/internal/event/core" - "golang.org/x/tools/internal/event/keys" - "golang.org/x/tools/internal/event/label" -) - -// Exporter is a function that handles events. -// It may return a modified context and event. -type Exporter func(context.Context, core.Event, label.Map) context.Context - -// SetExporter sets the global exporter function that handles all events. -// The exporter is called synchronously from the event call site, so it should -// return quickly so as not to hold up user code. -func SetExporter(e Exporter) { - core.SetExporter(core.Exporter(e)) -} - -// Log takes a message and a label list and combines them into a single event -// before delivering them to the exporter. -func Log(ctx context.Context, message string, labels ...label.Label) { - core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Msg.Of(message), - }, labels)) -} - -// IsLog returns true if the event was built by the Log function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsLog(ev core.Event) bool { - return ev.Label(0).Key() == keys.Msg -} - -// Error takes a message and a label list and combines them into a single event -// before delivering them to the exporter. It captures the error in the -// delivered event. -func Error(ctx context.Context, message string, err error, labels ...label.Label) { - core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Msg.Of(message), - keys.Err.Of(err), - }, labels)) -} - -// IsError returns true if the event was built by the Error function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsError(ev core.Event) bool { - return ev.Label(0).Key() == keys.Msg && - ev.Label(1).Key() == keys.Err -} - -// Metric sends a label event to the exporter with the supplied labels. -func Metric(ctx context.Context, labels ...label.Label) { - core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Metric.New(), - }, labels)) -} - -// IsMetric returns true if the event was built by the Metric function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsMetric(ev core.Event) bool { - return ev.Label(0).Key() == keys.Metric -} - -// Label sends a label event to the exporter with the supplied labels. -func Label(ctx context.Context, labels ...label.Label) context.Context { - return core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Label.New(), - }, labels)) -} - -// IsLabel returns true if the event was built by the Label function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsLabel(ev core.Event) bool { - return ev.Label(0).Key() == keys.Label -} - -// Start sends a span start event with the supplied label list to the exporter. -// It also returns a function that will end the span, which should normally be -// deferred. -func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) { - return core.ExportPair(ctx, - core.MakeEvent([3]label.Label{ - keys.Start.Of(name), - }, labels), - core.MakeEvent([3]label.Label{ - keys.End.New(), - }, nil)) -} - -// IsStart returns true if the event was built by the Start function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsStart(ev core.Event) bool { - return ev.Label(0).Key() == keys.Start -} - -// IsEnd returns true if the event was built by the End function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsEnd(ev core.Event) bool { - return ev.Label(0).Key() == keys.End -} - -// Detach returns a context without an associated span. -// This allows the creation of spans that are not children of the current span. -func Detach(ctx context.Context) context.Context { - return core.Export(ctx, core.MakeEvent([3]label.Label{ - keys.Detach.New(), - }, nil)) -} - -// IsDetach returns true if the event was built by the Detach function. -// It is intended to be used in exporters to identify the semantics of the -// event when deciding what to do with it. -func IsDetach(ev core.Event) bool { - return ev.Label(0).Key() == keys.Detach -} diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go deleted file mode 100644 index ac78bc3b..00000000 --- a/vendor/golang.org/x/tools/internal/event/keys/keys.go +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package keys - -import ( - "fmt" - "math" - "strconv" - - "golang.org/x/tools/internal/event/label" -) - -// Value is a [label.Key] for untyped values. -type Value struct { - name string - description string -} - -// New creates a new Key for untyped values. -func New(name, description string) *Value { - return &Value{name: name, description: description} -} - -func (k *Value) Name() string { return k.name } -func (k *Value) Description() string { return k.description } - -func (k *Value) Append(buf []byte, l label.Label) []byte { - return fmt.Append(buf, k.From(l)) -} - -// Get returns the label for the key of a label.Map. -func (k *Value) Get(lm label.Map) any { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return nil -} - -// From returns the value of a Label. -func (k *Value) From(t label.Label) any { return t.UnpackValue() } - -// Of creates a new Label with this key and the supplied value. -func (k *Value) Of(value any) label.Label { return label.OfValue(k, value) } - -// Tag represents a key for tagging labels that have no value. -// These are used when the existence of the label is the entire information it -// carries, such as marking events to be of a specific kind, or from a specific -// package. -type Tag struct { - name string - description string -} - -// NewTag creates a new [label.Key] for tagging labels. -func NewTag(name, description string) *Tag { - return &Tag{name: name, description: description} -} - -func (k *Tag) Name() string { return k.name } -func (k *Tag) Description() string { return k.description } - -func (k *Tag) Append(buf []byte, l label.Label) []byte { return buf } - -// New creates a new Label with this key. -func (k *Tag) New() label.Label { return label.OfValue(k, nil) } - -// Int is a [label.Key] for signed integers. -type Int struct { - name string - description string -} - -// NewInt returns a new [label.Key] for int64 values. -func NewInt(name, description string) *Int { - return &Int{name: name, description: description} -} - -func (k *Int) Name() string { return k.name } -func (k *Int) Description() string { return k.description } - -func (k *Int) Append(buf []byte, l label.Label) []byte { - return strconv.AppendInt(buf, k.From(l), 10) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int) Of(v int) label.Label { return k.Of64(int64(v)) } - -// Of64 creates a new Label with this key and the supplied value. -func (k *Int) Of64(v int64) label.Label { return label.Of64(k, uint64(v)) } - -// Get returns the label for the key of a label.Map. -func (k *Int) Get(lm label.Map) int64 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From returns the value of a Label. -func (k *Int) From(t label.Label) int64 { return int64(t.Unpack64()) } - -// Uint is a [label.Key] for unsigned integers. -type Uint struct { - name string - description string -} - -// NewUint creates a new [label.Key] for unsigned values. -func NewUint(name, description string) *Uint { - return &Uint{name: name, description: description} -} - -func (k *Uint) Name() string { return k.name } -func (k *Uint) Description() string { return k.description } - -func (k *Uint) Append(buf []byte, l label.Label) []byte { - return strconv.AppendUint(buf, k.From(l), 10) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Uint) Of(v uint64) label.Label { return label.Of64(k, v) } - -// Get returns the label for the key of a label.Map. -func (k *Uint) Get(lm label.Map) uint64 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From returns the value of a Label. -func (k *Uint) From(t label.Label) uint64 { return t.Unpack64() } - -// Float is a label.Key for floating-point values. -type Float struct { - name string - description string -} - -// NewFloat creates a new [label.Key] for floating-point values. -func NewFloat(name, description string) *Float { - return &Float{name: name, description: description} -} - -func (k *Float) Name() string { return k.name } -func (k *Float) Description() string { return k.description } - -func (k *Float) Append(buf []byte, l label.Label) []byte { - return strconv.AppendFloat(buf, k.From(l), 'E', -1, 64) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Float) Of(v float64) label.Label { - return label.Of64(k, math.Float64bits(v)) -} - -// Get returns the label for the key of a label.Map. -func (k *Float) Get(lm label.Map) float64 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From returns the value of a Label. -func (k *Float) From(t label.Label) float64 { - return math.Float64frombits(t.Unpack64()) -} - -// String represents a key -type String struct { - name string - description string -} - -// NewString creates a new Key for int64 values. -func NewString(name, description string) *String { - return &String{name: name, description: description} -} - -func (k *String) Name() string { return k.name } -func (k *String) Description() string { return k.description } - -func (k *String) Append(buf []byte, l label.Label) []byte { - return strconv.AppendQuote(buf, k.From(l)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *String) Of(v string) label.Label { return label.OfString(k, v) } - -// Get returns the label for the key of a label.Map. -func (k *String) Get(lm label.Map) string { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return "" -} - -// From returns the value of a Label. -func (k *String) From(t label.Label) string { return t.UnpackString() } - -// Error represents a key -type Error struct { - name string - description string -} - -// NewError returns a new [label.Key] for error values. -func NewError(name, description string) *Error { - return &Error{name: name, description: description} -} - -func (k *Error) Name() string { return k.name } -func (k *Error) Description() string { return k.description } - -func (k *Error) Append(buf []byte, l label.Label) []byte { - return append(buf, k.From(l).Error()...) -} - -// Of returns a new Label with this key and the supplied value. -func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) } - -// Get returns the label for the key of a label.Map. -func (k *Error) Get(lm label.Map) error { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return nil -} - -// From returns the value of a Label. -func (k *Error) From(t label.Label) error { - err, _ := t.UnpackValue().(error) - return err -} diff --git a/vendor/golang.org/x/tools/internal/event/keys/standard.go b/vendor/golang.org/x/tools/internal/event/keys/standard.go deleted file mode 100644 index 7e958665..00000000 --- a/vendor/golang.org/x/tools/internal/event/keys/standard.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package keys - -var ( - // Msg is a key used to add message strings to label lists. - Msg = NewString("message", "a readable message") - // Label is a key used to indicate an event adds labels to the context. - Label = NewTag("label", "a label context marker") - // Start is used for things like traces that have a name. - Start = NewString("start", "span start") - // Metric is a key used to indicate an event records metrics. - End = NewTag("end", "a span end marker") - // Metric is a key used to indicate an event records metrics. - Detach = NewTag("detach", "a span detach marker") - // Err is a key used to add error values to label lists. - Err = NewError("error", "an error that occurred") - // Metric is a key used to indicate an event records metrics. - Metric = NewTag("metric", "a metric event marker") -) diff --git a/vendor/golang.org/x/tools/internal/event/keys/util.go b/vendor/golang.org/x/tools/internal/event/keys/util.go deleted file mode 100644 index c0e8e731..00000000 --- a/vendor/golang.org/x/tools/internal/event/keys/util.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package keys - -import ( - "sort" - "strings" -) - -// Join returns a canonical join of the keys in S: -// a sorted comma-separated string list. -func Join[S ~[]T, T ~string](s S) string { - strs := make([]string, 0, len(s)) - for _, v := range s { - strs = append(strs, string(v)) - } - sort.Strings(strs) - return strings.Join(strs, ",") -} diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go deleted file mode 100644 index e84226f8..00000000 --- a/vendor/golang.org/x/tools/internal/event/label/label.go +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2019 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 label - -import ( - "fmt" - "io" - "slices" - "unsafe" -) - -// Key is used as the identity of a Label. -// Keys are intended to be compared by pointer only, the name should be unique -// for communicating with external systems, but it is not required or enforced. -type Key interface { - // Name returns the key name. - Name() string - // Description returns a string that can be used to describe the value. - Description() string - // Append appends the formatted value of the label to the supplied buffer. - Append(buf []byte, l Label) []byte -} - -// Label holds a key and value pair. -// It is normally used when passing around lists of labels. -type Label struct { - key Key - packed uint64 - untyped any -} - -// Map is the interface to a collection of Labels indexed by key. -type Map interface { - // Find returns the label that matches the supplied key. - Find(key Key) Label -} - -// List is the interface to something that provides an iterable -// list of labels. -// Iteration should start from 0 and continue until Valid returns false. -type List interface { - // Valid returns true if the index is within range for the list. - // It does not imply the label at that index will itself be valid. - Valid(index int) bool - // Label returns the label at the given index. - Label(index int) Label -} - -// list implements LabelList for a list of Labels. -type list struct { - labels []Label -} - -// filter wraps a LabelList filtering out specific labels. -type filter struct { - keys []Key - underlying List -} - -// listMap implements LabelMap for a simple list of labels. -type listMap struct { - labels []Label -} - -// mapChain implements LabelMap for a list of underlying LabelMap. -type mapChain struct { - maps []Map -} - -// OfValue creates a new label from the key and value. -// This method is for implementing new key types, label creation should -// normally be done with the Of method of the key. -func OfValue(k Key, value any) Label { return Label{key: k, untyped: value} } - -// UnpackValue assumes the label was built using LabelOfValue and returns the value -// that was passed to that constructor. -// This method is for implementing new key types, for type safety normal -// access should be done with the From method of the key. -func (t Label) UnpackValue() any { return t.untyped } - -// Of64 creates a new label from a key and a uint64. This is often -// used for non uint64 values that can be packed into a uint64. -// This method is for implementing new key types, label creation should -// normally be done with the Of method of the key. -func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} } - -// Unpack64 assumes the label was built using LabelOf64 and returns the value that -// was passed to that constructor. -// This method is for implementing new key types, for type safety normal -// access should be done with the From method of the key. -func (t Label) Unpack64() uint64 { return t.packed } - -type stringptr unsafe.Pointer - -// OfString creates a new label from a key and a string. -// This method is for implementing new key types, label creation should -// normally be done with the Of method of the key. -func OfString(k Key, v string) Label { - return Label{ - key: k, - packed: uint64(len(v)), - untyped: stringptr(unsafe.StringData(v)), - } -} - -// UnpackString assumes the label was built using LabelOfString and returns the -// value that was passed to that constructor. -// This method is for implementing new key types, for type safety normal -// access should be done with the From method of the key. -func (t Label) UnpackString() string { - return unsafe.String((*byte)(t.untyped.(stringptr)), int(t.packed)) -} - -// Valid returns true if the Label is a valid one (it has a key). -func (t Label) Valid() bool { return t.key != nil } - -// Key returns the key of this Label. -func (t Label) Key() Key { return t.key } - -// Format is used for debug printing of labels. -func (t Label) Format(f fmt.State, r rune) { - if !t.Valid() { - io.WriteString(f, `nil`) - return - } - io.WriteString(f, t.Key().Name()) - io.WriteString(f, "=") - f.Write(t.Key().Append(nil, t)) // ignore error -} - -func (l *list) Valid(index int) bool { - return index >= 0 && index < len(l.labels) -} - -func (l *list) Label(index int) Label { - return l.labels[index] -} - -func (f *filter) Valid(index int) bool { - return f.underlying.Valid(index) -} - -func (f *filter) Label(index int) Label { - l := f.underlying.Label(index) - if slices.Contains(f.keys, l.Key()) { - return Label{} - } - return l -} - -func (lm listMap) Find(key Key) Label { - for _, l := range lm.labels { - if l.Key() == key { - return l - } - } - return Label{} -} - -func (c mapChain) Find(key Key) Label { - for _, src := range c.maps { - l := src.Find(key) - if l.Valid() { - return l - } - } - return Label{} -} - -var emptyList = &list{} - -func NewList(labels ...Label) List { - if len(labels) == 0 { - return emptyList - } - return &list{labels: labels} -} - -func Filter(l List, keys ...Key) List { - if len(keys) == 0 { - return l - } - return &filter{keys: keys, underlying: l} -} - -func NewMap(labels ...Label) Map { - return listMap{labels: labels} -} - -func MergeMaps(srcs ...Map) Map { - var nonNil []Map - for _, src := range srcs { - if src != nil { - nonNil = append(nonNil, src) - } - } - if len(nonNil) == 1 { - return nonNil[0] - } - return mapChain{maps: nonNil} -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go deleted file mode 100644 index 555ef626..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/bimport.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file contains the remaining vestiges of -// $GOROOT/src/go/internal/gcimporter/bimport.go. - -package gcimporter - -import ( - "fmt" - "go/token" - "go/types" - "sync" -) - -func errorf(format string, args ...any) { - panic(fmt.Sprintf(format, args...)) -} - -const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go - -// Synthesize a token.Pos -type fakeFileSet struct { - fset *token.FileSet - files map[string]*fileInfo -} - -type fileInfo struct { - file *token.File - lastline int -} - -const maxlines = 64 * 1024 - -func (s *fakeFileSet) pos(file string, line, column int) token.Pos { - _ = column // TODO(mdempsky): Make use of column. - - // Since we don't know the set of needed file positions, we reserve maxlines - // positions per file. We delay calling token.File.SetLines until all - // positions have been calculated (by way of fakeFileSet.setLines), so that - // we can avoid setting unnecessary lines. See also golang/go#46586. - f := s.files[file] - if f == nil { - f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)} - s.files[file] = f - } - if line > maxlines { - line = 1 - } - if line > f.lastline { - f.lastline = line - } - - // Return a fake position assuming that f.file consists only of newlines. - return token.Pos(f.file.Base() + line - 1) -} - -func (s *fakeFileSet) setLines() { - fakeLinesOnce.Do(func() { - fakeLines = make([]int, maxlines) - for i := range fakeLines { - fakeLines[i] = i - } - }) - for _, f := range s.files { - f.file.SetLines(fakeLines[:f.lastline]) - } -} - -var ( - fakeLines []int - fakeLinesOnce sync.Once -) - -func chanDir(d int) types.ChanDir { - // tag values must match the constants in cmd/compile/internal/gc/go.go - switch d { - case 1 /* Crecv */ : - return types.RecvOnly - case 2 /* Csend */ : - return types.SendOnly - case 3 /* Cboth */ : - return types.SendRecv - default: - errorf("unexpected channel dir %d", d) - return 0 - } -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go deleted file mode 100644 index 5662a311..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file should be kept in sync with $GOROOT/src/internal/exportdata/exportdata.go. -// This file also additionally implements FindExportData for gcexportdata.NewReader. - -package gcimporter - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "go/build" - "io" - "os" - "os/exec" - "path/filepath" - "strings" - "sync" -) - -// FindExportData positions the reader r at the beginning of the -// export data section of an underlying cmd/compile created archive -// file by reading from it. The reader must be positioned at the -// start of the file before calling this function. -// This returns the length of the export data in bytes. -// -// This function is needed by [gcexportdata.Read], which must -// accept inputs produced by the last two releases of cmd/compile, -// plus tip. -func FindExportData(r *bufio.Reader) (size int64, err error) { - arsize, err := FindPackageDefinition(r) - if err != nil { - return - } - size = int64(arsize) - - objapi, headers, err := ReadObjectHeaders(r) - if err != nil { - return - } - size -= int64(len(objapi)) - for _, h := range headers { - size -= int64(len(h)) - } - - // Check for the binary export data section header "$$B\n". - // TODO(taking): Unify with ReadExportDataHeader so that it stops at the 'u' instead of reading - line, err := r.ReadSlice('\n') - if err != nil { - return - } - hdr := string(line) - if hdr != "$$B\n" { - err = fmt.Errorf("unknown export data header: %q", hdr) - return - } - size -= int64(len(hdr)) - - // For files with a binary export data header "$$B\n", - // these are always terminated by an end-of-section marker "\n$$\n". - // So the last bytes must always be this constant. - // - // The end-of-section marker is not a part of the export data itself. - // Do not include these in size. - // - // It would be nice to have sanity check that the final bytes after - // the export data are indeed the end-of-section marker. The split - // of gcexportdata.NewReader and gcexportdata.Read make checking this - // ugly so gcimporter gives up enforcing this. The compiler and go/types - // importer do enforce this, which seems good enough. - const endofsection = "\n$$\n" - size -= int64(len(endofsection)) - - if size < 0 { - err = fmt.Errorf("invalid size (%d) in the archive file: %d bytes remain without section headers (recompile package)", arsize, size) - return - } - - return -} - -// ReadUnified reads the contents of the unified export data from a reader r -// that contains the contents of a GC-created archive file. -// -// On success, the reader will be positioned after the end-of-section marker "\n$$\n". -// -// Supported GC-created archive files have 4 layers of nesting: -// - An archive file containing a package definition file. -// - The package definition file contains headers followed by a data section. -// Headers are lines (≤ 4kb) that do not start with "$$". -// - The data section starts with "$$B\n" followed by export data followed -// by an end of section marker "\n$$\n". (The section start "$$\n" is no -// longer supported.) -// - The export data starts with a format byte ('u') followed by the in -// the given format. (See ReadExportDataHeader for older formats.) -// -// Putting this together, the bytes in a GC-created archive files are expected -// to look like the following. -// See cmd/internal/archive for more details on ar file headers. -// -// | \n | ar file signature -// | __.PKGDEF...size...\n | ar header for __.PKGDEF including size. -// | go object <...>\n | objabi header -// | \n | other headers such as build id -// | $$B\n | binary format marker -// | u\n | unified export -// | $$\n | end-of-section marker -// | [optional padding] | padding byte (0x0A) if size is odd -// | [ar file header] | other ar files -// | [ar file data] | -func ReadUnified(r *bufio.Reader) (data []byte, err error) { - // We historically guaranteed headers at the default buffer size (4096) work. - // This ensures we can use ReadSlice throughout. - const minBufferSize = 4096 - r = bufio.NewReaderSize(r, minBufferSize) - - size, err := FindPackageDefinition(r) - if err != nil { - return - } - n := size - - objapi, headers, err := ReadObjectHeaders(r) - if err != nil { - return - } - n -= len(objapi) - for _, h := range headers { - n -= len(h) - } - - hdrlen, err := ReadExportDataHeader(r) - if err != nil { - return - } - n -= hdrlen - - // size also includes the end of section marker. Remove that many bytes from the end. - const marker = "\n$$\n" - n -= len(marker) - - if n < 0 { - err = fmt.Errorf("invalid size (%d) in the archive file: %d bytes remain without section headers (recompile package)", size, n) - return - } - - // Read n bytes from buf. - data = make([]byte, n) - _, err = io.ReadFull(r, data) - if err != nil { - return - } - - // Check for marker at the end. - var suffix [len(marker)]byte - _, err = io.ReadFull(r, suffix[:]) - if err != nil { - return - } - if s := string(suffix[:]); s != marker { - err = fmt.Errorf("read %q instead of end-of-section marker (%q)", s, marker) - return - } - - return -} - -// FindPackageDefinition positions the reader r at the beginning of a package -// definition file ("__.PKGDEF") within a GC-created archive by reading -// from it, and returns the size of the package definition file in the archive. -// -// The reader must be positioned at the start of the archive file before calling -// this function, and "__.PKGDEF" is assumed to be the first file in the archive. -// -// See cmd/internal/archive for details on the archive format. -func FindPackageDefinition(r *bufio.Reader) (size int, err error) { - // Uses ReadSlice to limit risk of malformed inputs. - - // Read first line to make sure this is an object file. - line, err := r.ReadSlice('\n') - if err != nil { - err = fmt.Errorf("can't find export data (%v)", err) - return - } - - // Is the first line an archive file signature? - if string(line) != "!\n" { - err = fmt.Errorf("not the start of an archive file (%q)", line) - return - } - - // package export block should be first - size = readArchiveHeader(r, "__.PKGDEF") - if size <= 0 { - err = fmt.Errorf("not a package file") - return - } - - return -} - -// ReadObjectHeaders reads object headers from the reader. Object headers are -// lines that do not start with an end-of-section marker "$$". The first header -// is the objabi header. On success, the reader will be positioned at the beginning -// of the end-of-section marker. -// -// It returns an error if any header does not fit in r.Size() bytes. -func ReadObjectHeaders(r *bufio.Reader) (objapi string, headers []string, err error) { - // line is a temporary buffer for headers. - // Use bounded reads (ReadSlice, Peek) to limit risk of malformed inputs. - var line []byte - - // objapi header should be the first line - if line, err = r.ReadSlice('\n'); err != nil { - err = fmt.Errorf("can't find export data (%v)", err) - return - } - objapi = string(line) - - // objapi header begins with "go object ". - if !strings.HasPrefix(objapi, "go object ") { - err = fmt.Errorf("not a go object file: %s", objapi) - return - } - - // process remaining object header lines - for { - // check for an end of section marker "$$" - line, err = r.Peek(2) - if err != nil { - return - } - if string(line) == "$$" { - return // stop - } - - // read next header - line, err = r.ReadSlice('\n') - if err != nil { - return - } - headers = append(headers, string(line)) - } -} - -// ReadExportDataHeader reads the export data header and format from r. -// It returns the number of bytes read, or an error if the format is no longer -// supported or it failed to read. -// -// The only currently supported format is binary export data in the -// unified export format. -func ReadExportDataHeader(r *bufio.Reader) (n int, err error) { - // Read export data header. - line, err := r.ReadSlice('\n') - if err != nil { - return - } - - hdr := string(line) - switch hdr { - case "$$\n": - err = fmt.Errorf("old textual export format no longer supported (recompile package)") - return - - case "$$B\n": - var format byte - format, err = r.ReadByte() - if err != nil { - return - } - // The unified export format starts with a 'u'. - switch format { - case 'u': - default: - // Older no longer supported export formats include: - // indexed export format which started with an 'i'; and - // the older binary export format which started with a 'c', - // 'd', or 'v' (from "version"). - err = fmt.Errorf("binary export format %q is no longer supported (recompile package)", format) - return - } - - default: - err = fmt.Errorf("unknown export data header: %q", hdr) - return - } - - n = len(hdr) + 1 // + 1 is for 'u' - return -} - -// FindPkg returns the filename and unique package id for an import -// path based on package information provided by build.Import (using -// the build.Default build.Context). A relative srcDir is interpreted -// relative to the current working directory. -// -// FindPkg is only used in tests within x/tools. -func FindPkg(path, srcDir string) (filename, id string, err error) { - // TODO(taking): Move internal/exportdata.FindPkg into its own file, - // and then this copy into a _test package. - if path == "" { - return "", "", errors.New("path is empty") - } - - var noext string - switch { - default: - // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" - // Don't require the source files to be present. - if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282 - srcDir = abs - } - var bp *build.Package - bp, err = build.Import(path, srcDir, build.FindOnly|build.AllowBinary) - if bp.PkgObj == "" { - if bp.Goroot && bp.Dir != "" { - filename, err = lookupGorootExport(bp.Dir) - if err == nil { - _, err = os.Stat(filename) - } - if err == nil { - return filename, bp.ImportPath, nil - } - } - goto notfound - } else { - noext = strings.TrimSuffix(bp.PkgObj, ".a") - } - id = bp.ImportPath - - case build.IsLocalImport(path): - // "./x" -> "/this/directory/x.ext", "/this/directory/x" - noext = filepath.Join(srcDir, path) - id = noext - - case filepath.IsAbs(path): - // for completeness only - go/build.Import - // does not support absolute imports - // "/x" -> "/x.ext", "/x" - noext = path - id = path - } - - if false { // for debugging - if path != id { - fmt.Printf("%s -> %s\n", path, id) - } - } - - // try extensions - for _, ext := range pkgExts { - filename = noext + ext - f, statErr := os.Stat(filename) - if statErr == nil && !f.IsDir() { - return filename, id, nil - } - if err == nil { - err = statErr - } - } - -notfound: - if err == nil { - return "", path, fmt.Errorf("can't find import: %q", path) - } - return "", path, fmt.Errorf("can't find import: %q: %w", path, err) -} - -var pkgExts = [...]string{".a", ".o"} // a file from the build cache will have no extension - -var exportMap sync.Map // package dir → func() (string, error) - -// lookupGorootExport returns the location of the export data -// (normally found in the build cache, but located in GOROOT/pkg -// in prior Go releases) for the package located in pkgDir. -// -// (We use the package's directory instead of its import path -// mainly to simplify handling of the packages in src/vendor -// and cmd/vendor.) -// -// lookupGorootExport is only used in tests within x/tools. -func lookupGorootExport(pkgDir string) (string, error) { - f, ok := exportMap.Load(pkgDir) - if !ok { - var ( - listOnce sync.Once - exportPath string - err error - ) - f, _ = exportMap.LoadOrStore(pkgDir, func() (string, error) { - listOnce.Do(func() { - cmd := exec.Command(filepath.Join(build.Default.GOROOT, "bin", "go"), "list", "-export", "-f", "{{.Export}}", pkgDir) - cmd.Dir = build.Default.GOROOT - cmd.Env = append(os.Environ(), "PWD="+cmd.Dir, "GOROOT="+build.Default.GOROOT) - var output []byte - output, err = cmd.Output() - if err != nil { - if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 { - err = errors.New(string(ee.Stderr)) - } - return - } - - exports := strings.Split(string(bytes.TrimSpace(output)), "\n") - if len(exports) != 1 { - err = fmt.Errorf("go list reported %d exports; expected 1", len(exports)) - return - } - - exportPath = exports[0] - }) - - return exportPath, err - }) - } - - return f.(func() (string, error))() -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go deleted file mode 100644 index 3dbd21d1..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file is a reduced copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go. - -// Package gcimporter provides various functions for reading -// gc-generated object files that can be used to implement the -// Importer interface defined by the Go 1.5 standard library package. -// -// The encoding is deterministic: if the encoder is applied twice to -// the same types.Package data structure, both encodings are equal. -// This property may be important to avoid spurious changes in -// applications such as build systems. -// -// However, the encoder is not necessarily idempotent. Importing an -// exported package may yield a types.Package that, while it -// represents the same set of Go types as the original, may differ in -// the details of its internal representation. Because of these -// differences, re-encoding the imported package may yield a -// different, but equally valid, encoding of the package. -package gcimporter // import "golang.org/x/tools/internal/gcimporter" - -import ( - "bufio" - "fmt" - "go/token" - "go/types" - "io" - "os" -) - -const ( - // Enable debug during development: it adds some additional checks, and - // prevents errors from being recovered. - debug = false - - // If trace is set, debugging output is printed to std out. - trace = false -) - -// Import imports a gc-generated package given its import path and srcDir, adds -// the corresponding package object to the packages map, and returns the object. -// The packages map must contain all packages already imported. -// -// Import is only used in tests. -func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) { - var rc io.ReadCloser - var id string - if lookup != nil { - // With custom lookup specified, assume that caller has - // converted path to a canonical import path for use in the map. - if path == "unsafe" { - return types.Unsafe, nil - } - id = path - - // No need to re-import if the package was imported completely before. - if pkg = packages[id]; pkg != nil && pkg.Complete() { - return - } - f, err := lookup(path) - if err != nil { - return nil, err - } - rc = f - } else { - var filename string - filename, id, err = FindPkg(path, srcDir) - if filename == "" { - if path == "unsafe" { - return types.Unsafe, nil - } - return nil, err - } - - // no need to re-import if the package was imported completely before - if pkg = packages[id]; pkg != nil && pkg.Complete() { - return - } - - // open file - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer func() { - if err != nil { - // add file name to error - err = fmt.Errorf("%s: %v", filename, err) - } - }() - rc = f - } - defer rc.Close() - - buf := bufio.NewReader(rc) - data, err := ReadUnified(buf) - if err != nil { - err = fmt.Errorf("import %q: %v", path, err) - return - } - - // unified: emitted by cmd/compile since go1.20. - _, pkg, err = UImportData(fset, packages, data, id) - - return -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go deleted file mode 100644 index 4c9450f4..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go +++ /dev/null @@ -1,1602 +0,0 @@ -// Copyright 2019 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. - -// Indexed package export. -// -// The indexed export data format is an evolution of the previous -// binary export data format. Its chief contribution is introducing an -// index table, which allows efficient random access of individual -// declarations and inline function bodies. In turn, this allows -// avoiding unnecessary work for compilation units that import large -// packages. -// -// -// The top-level data format is structured as: -// -// Header struct { -// Tag byte // 'i' -// Version uvarint -// StringSize uvarint -// DataSize uvarint -// } -// -// Strings [StringSize]byte -// Data [DataSize]byte -// -// MainIndex []struct{ -// PkgPath stringOff -// PkgName stringOff -// PkgHeight uvarint -// -// Decls []struct{ -// Name stringOff -// Offset declOff -// } -// } -// -// Fingerprint [8]byte -// -// uvarint means a uint64 written out using uvarint encoding. -// -// []T means a uvarint followed by that many T objects. In other -// words: -// -// Len uvarint -// Elems [Len]T -// -// stringOff means a uvarint that indicates an offset within the -// Strings section. At that offset is another uvarint, followed by -// that many bytes, which form the string value. -// -// declOff means a uvarint that indicates an offset within the Data -// section where the associated declaration can be found. -// -// -// There are five kinds of declarations, distinguished by their first -// byte: -// -// type Var struct { -// Tag byte // 'V' -// Pos Pos -// Type typeOff -// } -// -// type Func struct { -// Tag byte // 'F' or 'G' -// Pos Pos -// TypeParams []typeOff // only present if Tag == 'G' -// Signature Signature -// } -// -// type Const struct { -// Tag byte // 'C' -// Pos Pos -// Value Value -// } -// -// type Type struct { -// Tag byte // 'T' or 'U' -// Pos Pos -// TypeParams []typeOff // only present if Tag == 'U' -// Underlying typeOff -// -// Methods []struct{ // omitted if Underlying is an interface type -// Pos Pos -// Name stringOff -// Recv Param -// Signature Signature -// } -// } -// -// type Alias struct { -// Tag byte // 'A' or 'B' -// Pos Pos -// TypeParams []typeOff // only present if Tag == 'B' -// Type typeOff -// } -// -// // "Automatic" declaration of each typeparam -// type TypeParam struct { -// Tag byte // 'P' -// Pos Pos -// Implicit bool -// Constraint typeOff -// } -// -// typeOff means a uvarint that either indicates a predeclared type, -// or an offset into the Data section. If the uvarint is less than -// predeclReserved, then it indicates the index into the predeclared -// types list (see predeclared in bexport.go for order). Otherwise, -// subtracting predeclReserved yields the offset of a type descriptor. -// -// Value means a type, kind, and type-specific value. See -// (*exportWriter).value for details. -// -// -// There are twelve kinds of type descriptors, distinguished by an itag: -// -// type DefinedType struct { -// Tag itag // definedType -// Name stringOff -// PkgPath stringOff -// } -// -// type PointerType struct { -// Tag itag // pointerType -// Elem typeOff -// } -// -// type SliceType struct { -// Tag itag // sliceType -// Elem typeOff -// } -// -// type ArrayType struct { -// Tag itag // arrayType -// Len uint64 -// Elem typeOff -// } -// -// type ChanType struct { -// Tag itag // chanType -// Dir uint64 // 1 RecvOnly; 2 SendOnly; 3 SendRecv -// Elem typeOff -// } -// -// type MapType struct { -// Tag itag // mapType -// Key typeOff -// Elem typeOff -// } -// -// type FuncType struct { -// Tag itag // signatureType -// PkgPath stringOff -// Signature Signature -// } -// -// type StructType struct { -// Tag itag // structType -// PkgPath stringOff -// Fields []struct { -// Pos Pos -// Name stringOff -// Type typeOff -// Embedded bool -// Note stringOff -// } -// } -// -// type InterfaceType struct { -// Tag itag // interfaceType -// PkgPath stringOff -// Embeddeds []struct { -// Pos Pos -// Type typeOff -// } -// Methods []struct { -// Pos Pos -// Name stringOff -// Signature Signature -// } -// } -// -// // Reference to a type param declaration -// type TypeParamType struct { -// Tag itag // typeParamType -// Name stringOff -// PkgPath stringOff -// } -// -// // Instantiation of a generic type (like List[T2] or List[int]) -// type InstanceType struct { -// Tag itag // instanceType -// Pos pos -// TypeArgs []typeOff -// BaseType typeOff -// } -// -// type UnionType struct { -// Tag itag // interfaceType -// Terms []struct { -// tilde bool -// Type typeOff -// } -// } -// -// -// -// type Signature struct { -// Params []Param -// Results []Param -// Variadic bool // omitted if Results is empty -// } -// -// type Param struct { -// Pos Pos -// Name stringOff -// Type typOff -// } -// -// -// Pos encodes a file:line:column triple, incorporating a simple delta -// encoding scheme within a data object. See exportWriter.pos for -// details. - -package gcimporter - -import ( - "bytes" - "encoding/binary" - "fmt" - "go/constant" - "go/token" - "go/types" - "io" - "math/big" - "reflect" - "slices" - "sort" - "strconv" - "strings" - - "golang.org/x/tools/go/types/objectpath" -) - -// IExportShallow encodes "shallow" export data for the specified package. -// -// For types, we use "shallow" export data. Historically, the Go -// compiler always produced a summary of the types for a given package -// that included types from other packages that it indirectly -// referenced: "deep" export data. This had the advantage that the -// compiler (and analogous tools such as gopls) need only load one -// file per direct import. However, it meant that the files tended to -// get larger based on the level of the package in the import -// graph. For example, higher-level packages in the kubernetes module -// have over 1MB of "deep" export data, even when they have almost no -// content of their own, merely because they mention a major type that -// references many others. In pathological cases the export data was -// 300x larger than the source for a package due to this quadratic -// growth. -// -// "Shallow" export data means that the serialized types describe only -// a single package. If those types mention types from other packages, -// the type checker may need to request additional packages beyond -// just the direct imports. Type information for the entire transitive -// closure of imports is provided (lazily) by the DAG. -// -// No promises are made about the encoding other than that it can be decoded by -// the same version of IIExportShallow. If you plan to save export data in the -// file system, be sure to include a cryptographic digest of the executable in -// the key to avoid version skew. -// -// If the provided reportf func is non-nil, it is used for reporting -// bugs (e.g. recovered panics) encountered during export, enabling us -// to obtain via telemetry the stack that would otherwise be lost by -// merely returning an error. -func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc) ([]byte, error) { - // In principle this operation can only fail if out.Write fails, - // but that's impossible for bytes.Buffer---and as a matter of - // fact iexportCommon doesn't even check for I/O errors. - // TODO(adonovan): handle I/O errors properly. - // TODO(adonovan): use byte slices throughout, avoiding copying. - const bundle, shallow = false, true - var out bytes.Buffer - err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}, reportf) - return out.Bytes(), err -} - -// IImportShallow decodes "shallow" types.Package data encoded by -// [IExportShallow] in the same executable. This function cannot import data -// from cmd/compile or gcexportdata.Write. -// -// The importer calls getPackages to obtain package symbols for all -// packages mentioned in the export data, including the one being -// decoded. -// -// If the provided reportf func is non-nil, it will be used for reporting bugs -// encountered during import. -// TODO(rfindley): remove reportf when we are confident enough in the new -// objectpath encoding. -func IImportShallow(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, path string, reportf ReportFunc) (*types.Package, error) { - const bundle = false - const shallow = true - pkgs, err := iimportCommon(fset, getPackages, data, bundle, path, shallow, reportf) - if err != nil { - return nil, err - } - return pkgs[0], nil -} - -// ReportFunc is the type of a function used to report formatted bugs. -type ReportFunc = func(string, ...any) - -// Current bundled export format version. Increase with each format change. -// 0: initial implementation -const bundleVersion = 0 - -// IExportData writes indexed export data for pkg to out. -// -// If no file set is provided, position info will be missing. -// The package path of the top-level package will not be recorded, -// so that calls to IImportData can override with a provided package path. -func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error { - const bundle, shallow = false, false - return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}, nil) -} - -// IExportBundle writes an indexed export bundle for pkgs to out. -func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { - const bundle, shallow = true, false - return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs, nil) -} - -func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package, reportf ReportFunc) (err error) { - if !debug { - defer func() { - if e := recover(); e != nil { - // Report the stack via telemetry (see #71067). - if reportf != nil { - reportf("panic in exporter") - } - if ierr, ok := e.(internalError); ok { - // internalError usually means we exported a - // bad go/types data structure: a violation - // of an implicit precondition of Export. - err = ierr - return - } - // Not an internal error; panic again. - panic(e) - } - }() - } - - p := iexporter{ - fset: fset, - version: version, - shallow: shallow, - allPkgs: map[*types.Package]bool{}, - stringIndex: map[string]uint64{}, - declIndex: map[types.Object]uint64{}, - tparamNames: map[types.Object]string{}, - typIndex: map[types.Type]uint64{}, - } - if !bundle { - p.localpkg = pkgs[0] - } - - for i, pt := range predeclared() { - p.typIndex[pt] = uint64(i) - } - if len(p.typIndex) > predeclReserved { - panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved)) - } - - // Initialize work queue with exported declarations. - for _, pkg := range pkgs { - scope := pkg.Scope() - for _, name := range scope.Names() { - if token.IsExported(name) { - p.pushDecl(scope.Lookup(name)) - } - } - - if bundle { - // Ensure pkg and its imports are included in the index. - p.allPkgs[pkg] = true - for _, imp := range pkg.Imports() { - p.allPkgs[imp] = true - } - } - } - - // Loop until no more work. - for !p.declTodo.empty() { - p.doDecl(p.declTodo.popHead()) - } - - // Produce index of offset of each file record in files. - var files intWriter - var fileOffset []uint64 // fileOffset[i] is offset in files of file encoded as i - if p.shallow { - fileOffset = make([]uint64, len(p.fileInfos)) - for i, info := range p.fileInfos { - fileOffset[i] = uint64(files.Len()) - p.encodeFile(&files, info.file, info.needed) - } - } - - // Append indices to data0 section. - dataLen := uint64(p.data0.Len()) - w := p.newWriter() - w.writeIndex(p.declIndex) - - if bundle { - w.uint64(uint64(len(pkgs))) - for _, pkg := range pkgs { - w.pkg(pkg) - imps := pkg.Imports() - w.uint64(uint64(len(imps))) - for _, imp := range imps { - w.pkg(imp) - } - } - } - w.flush() - - // Assemble header. - var hdr intWriter - if bundle { - hdr.uint64(bundleVersion) - } - hdr.uint64(uint64(p.version)) - hdr.uint64(uint64(p.strings.Len())) - if p.shallow { - hdr.uint64(uint64(files.Len())) - hdr.uint64(uint64(len(fileOffset))) - for _, offset := range fileOffset { - hdr.uint64(offset) - } - } - hdr.uint64(dataLen) - - // Flush output. - io.Copy(out, &hdr) - io.Copy(out, &p.strings) - if p.shallow { - io.Copy(out, &files) - } - io.Copy(out, &p.data0) - - return nil -} - -// encodeFile writes to w a representation of the file sufficient to -// faithfully restore position information about all needed offsets. -// Mutates the needed array. -func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64) { - _ = needed[0] // precondition: needed is non-empty - - w.uint64(p.stringOff(file.Name())) - - size := uint64(file.Size()) - w.uint64(size) - - // Sort the set of needed offsets. Duplicates are harmless. - slices.Sort(needed) - - lines := file.Lines() // byte offset of each line start - w.uint64(uint64(len(lines))) - - // Rather than record the entire array of line start offsets, - // we save only a sparse list of (index, offset) pairs for - // the start of each line that contains a needed position. - var sparse [][2]int // (index, offset) pairs -outer: - for i, lineStart := range lines { - lineEnd := size - if i < len(lines)-1 { - lineEnd = uint64(lines[i+1]) - } - // Does this line contains a needed offset? - if needed[0] < lineEnd { - sparse = append(sparse, [2]int{i, lineStart}) - for needed[0] < lineEnd { - needed = needed[1:] - if len(needed) == 0 { - break outer - } - } - } - } - - // Delta-encode the columns. - w.uint64(uint64(len(sparse))) - var prev [2]int - for _, pair := range sparse { - w.uint64(uint64(pair[0] - prev[0])) - w.uint64(uint64(pair[1] - prev[1])) - prev = pair - } -} - -// writeIndex writes out an object index. mainIndex indicates whether -// we're writing out the main index, which is also read by -// non-compiler tools and includes a complete package description -// (i.e., name and height). -func (w *exportWriter) writeIndex(index map[types.Object]uint64) { - type pkgObj struct { - obj types.Object - name string // qualified name; differs from obj.Name for type params - } - // Build a map from packages to objects from that package. - pkgObjs := map[*types.Package][]pkgObj{} - - // For the main index, make sure to include every package that - // we reference, even if we're not exporting (or reexporting) - // any symbols from it. - if w.p.localpkg != nil { - pkgObjs[w.p.localpkg] = nil - } - for pkg := range w.p.allPkgs { - pkgObjs[pkg] = nil - } - - for obj := range index { - name := w.p.exportName(obj) - pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name}) - } - - var pkgs []*types.Package - for pkg, objs := range pkgObjs { - pkgs = append(pkgs, pkg) - - sort.Slice(objs, func(i, j int) bool { - return objs[i].name < objs[j].name - }) - } - - sort.Slice(pkgs, func(i, j int) bool { - return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j]) - }) - - w.uint64(uint64(len(pkgs))) - for _, pkg := range pkgs { - w.string(w.exportPath(pkg)) - w.string(pkg.Name()) - w.uint64(uint64(0)) // package height is not needed for go/types - - objs := pkgObjs[pkg] - w.uint64(uint64(len(objs))) - for _, obj := range objs { - w.string(obj.name) - w.uint64(index[obj.obj]) - } - } -} - -// exportName returns the 'exported' name of an object. It differs from -// obj.Name() only for type parameters (see tparamExportName for details). -func (p *iexporter) exportName(obj types.Object) (res string) { - if name := p.tparamNames[obj]; name != "" { - return name - } - return obj.Name() -} - -type iexporter struct { - fset *token.FileSet - version int - - shallow bool // don't put types from other packages in the index - objEncoder *objectpath.Encoder // encodes objects from other packages in shallow mode; lazily allocated - localpkg *types.Package // (nil in bundle mode) - - // allPkgs tracks all packages that have been referenced by - // the export data, so we can ensure to include them in the - // main index. - allPkgs map[*types.Package]bool - - declTodo objQueue - - strings intWriter - stringIndex map[string]uint64 - - // In shallow mode, object positions are encoded as (file, offset). - // Each file is recorded as a line-number table. - // Only the lines of needed positions are saved faithfully. - fileInfo map[*token.File]uint64 // value is index in fileInfos - fileInfos []*filePositions - - data0 intWriter - declIndex map[types.Object]uint64 - tparamNames map[types.Object]string // typeparam->exported name - typIndex map[types.Type]uint64 - - indent int // for tracing support -} - -type filePositions struct { - file *token.File - needed []uint64 // unordered list of needed file offsets -} - -func (p *iexporter) trace(format string, args ...any) { - if !trace { - // Call sites should also be guarded, but having this check here allows - // easily enabling/disabling debug trace statements. - return - } - fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) -} - -// objectpathEncoder returns the lazily allocated objectpath.Encoder to use -// when encoding objects in other packages during shallow export. -// -// Using a shared Encoder amortizes some of cost of objectpath search. -func (p *iexporter) objectpathEncoder() *objectpath.Encoder { - if p.objEncoder == nil { - p.objEncoder = new(objectpath.Encoder) - } - return p.objEncoder -} - -// stringOff returns the offset of s within the string section. -// If not already present, it's added to the end. -func (p *iexporter) stringOff(s string) uint64 { - off, ok := p.stringIndex[s] - if !ok { - off = uint64(p.strings.Len()) - p.stringIndex[s] = off - - p.strings.uint64(uint64(len(s))) - p.strings.WriteString(s) - } - return off -} - -// fileIndexAndOffset returns the index of the token.File and the byte offset of pos within it. -func (p *iexporter) fileIndexAndOffset(file *token.File, pos token.Pos) (uint64, uint64) { - index, ok := p.fileInfo[file] - if !ok { - index = uint64(len(p.fileInfo)) - p.fileInfos = append(p.fileInfos, &filePositions{file: file}) - if p.fileInfo == nil { - p.fileInfo = make(map[*token.File]uint64) - } - p.fileInfo[file] = index - } - // Record each needed offset. - info := p.fileInfos[index] - offset := uint64(file.Offset(pos)) - info.needed = append(info.needed, offset) - - return index, offset -} - -// pushDecl adds n to the declaration work queue, if not already present. -func (p *iexporter) pushDecl(obj types.Object) { - // Package unsafe is known to the compiler and predeclared. - // Caller should not ask us to do export it. - if obj.Pkg() == types.Unsafe { - panic("cannot export package unsafe") - } - - // Shallow export data: don't index decls from other packages. - if p.shallow && obj.Pkg() != p.localpkg { - return - } - - if _, ok := p.declIndex[obj]; ok { - return - } - - p.declIndex[obj] = ^uint64(0) // mark obj present in work queue - p.declTodo.pushTail(obj) -} - -// exportWriter handles writing out individual data section chunks. -type exportWriter struct { - p *iexporter - - data intWriter - prevFile string - prevLine int64 - prevColumn int64 -} - -func (w *exportWriter) exportPath(pkg *types.Package) string { - if pkg == w.p.localpkg { - return "" - } - return pkg.Path() -} - -func (p *iexporter) doDecl(obj types.Object) { - if trace { - p.trace("exporting decl %v (%T)", obj, obj) - p.indent++ - defer func() { - p.indent-- - p.trace("=> %s", obj) - }() - } - w := p.newWriter() - - switch obj := obj.(type) { - case *types.Var: - w.tag(varTag) - w.pos(obj.Pos()) - w.typ(obj.Type(), obj.Pkg()) - - case *types.Func: - sig, _ := obj.Type().(*types.Signature) - if sig.Recv() != nil { - // We shouldn't see methods in the package scope, - // but the type checker may repair "func () F() {}" - // to "func (Invalid) F()" and then treat it like "func F()", - // so allow that. See golang/go#57729. - if sig.Recv().Type() != types.Typ[types.Invalid] { - panic(internalErrorf("unexpected method: %v", sig)) - } - } - - // Function. - if sig.TypeParams().Len() == 0 { - w.tag(funcTag) - } else { - w.tag(genericFuncTag) - } - w.pos(obj.Pos()) - // The tparam list of the function type is the declaration of the type - // params. So, write out the type params right now. Then those type params - // will be referenced via their type offset (via typOff) in all other - // places in the signature and function where they are used. - // - // While importing the type parameters, tparamList computes and records - // their export name, so that it can be later used when writing the index. - if tparams := sig.TypeParams(); tparams.Len() > 0 { - w.tparamList(obj.Name(), tparams, obj.Pkg()) - } - w.signature(sig) - - case *types.Const: - w.tag(constTag) - w.pos(obj.Pos()) - w.value(obj.Type(), obj.Val()) - - case *types.TypeName: - t := obj.Type() - - if tparam, ok := types.Unalias(t).(*types.TypeParam); ok { - w.tag(typeParamTag) - w.pos(obj.Pos()) - constraint := tparam.Constraint() - if p.version >= iexportVersionGo1_18 { - implicit := false - if iface, _ := types.Unalias(constraint).(*types.Interface); iface != nil { - implicit = iface.IsImplicit() - } - w.bool(implicit) - } - w.typ(constraint, obj.Pkg()) - break - } - - if obj.IsAlias() { - alias, materialized := t.(*types.Alias) // perhaps false for certain built-ins? - - var tparams *types.TypeParamList - if materialized { - tparams = alias.TypeParams() - } - if tparams.Len() == 0 { - w.tag(aliasTag) - } else { - w.tag(genericAliasTag) - } - w.pos(obj.Pos()) - if tparams.Len() > 0 { - w.tparamList(obj.Name(), tparams, obj.Pkg()) - } - if materialized { - // Preserve materialized aliases, - // even of non-exported types. - t = alias.Rhs() - } - w.typ(t, obj.Pkg()) - break - } - - // Defined type. - named, ok := t.(*types.Named) - if !ok { - panic(internalErrorf("%s is not a defined type", t)) - } - - if named.TypeParams().Len() == 0 { - w.tag(typeTag) - } else { - w.tag(genericTypeTag) - } - w.pos(obj.Pos()) - - if named.TypeParams().Len() > 0 { - // While importing the type parameters, tparamList computes and records - // their export name, so that it can be later used when writing the index. - w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg()) - } - - underlying := named.Underlying() - w.typ(underlying, obj.Pkg()) - - if types.IsInterface(t) { - break - } - - n := named.NumMethods() - w.uint64(uint64(n)) - for i := range n { - m := named.Method(i) - w.pos(m.Pos()) - w.string(m.Name()) - sig, _ := m.Type().(*types.Signature) - - // Receiver type parameters are type arguments of the receiver type, so - // their name must be qualified before exporting recv. - if rparams := sig.RecvTypeParams(); rparams.Len() > 0 { - prefix := obj.Name() + "." + m.Name() - for rparam := range rparams.TypeParams() { - name := tparamExportName(prefix, rparam) - w.p.tparamNames[rparam.Obj()] = name - } - } - w.param(sig.Recv()) - w.signature(sig) - } - - default: - panic(internalErrorf("unexpected object: %v", obj)) - } - - p.declIndex[obj] = w.flush() -} - -func (w *exportWriter) tag(tag byte) { - w.data.WriteByte(tag) -} - -func (w *exportWriter) pos(pos token.Pos) { - if w.p.shallow { - w.posV2(pos) - } else if w.p.version >= iexportVersionPosCol { - w.posV1(pos) - } else { - w.posV0(pos) - } -} - -// posV2 encoding (used only in shallow mode) records positions as -// (file, offset), where file is the index in the token.File table -// (which records the file name and newline offsets) and offset is a -// byte offset. It effectively ignores //line directives. -func (w *exportWriter) posV2(pos token.Pos) { - if pos == token.NoPos { - w.uint64(0) - return - } - file := w.p.fset.File(pos) // fset must be non-nil - index, offset := w.p.fileIndexAndOffset(file, pos) - w.uint64(1 + index) - w.uint64(offset) -} - -func (w *exportWriter) posV1(pos token.Pos) { - if w.p.fset == nil { - w.int64(0) - return - } - - p := w.p.fset.Position(pos) - file := p.Filename - line := int64(p.Line) - column := int64(p.Column) - - deltaColumn := (column - w.prevColumn) << 1 - deltaLine := (line - w.prevLine) << 1 - - if file != w.prevFile { - deltaLine |= 1 - } - if deltaLine != 0 { - deltaColumn |= 1 - } - - w.int64(deltaColumn) - if deltaColumn&1 != 0 { - w.int64(deltaLine) - if deltaLine&1 != 0 { - w.string(file) - } - } - - w.prevFile = file - w.prevLine = line - w.prevColumn = column -} - -func (w *exportWriter) posV0(pos token.Pos) { - if w.p.fset == nil { - w.int64(0) - return - } - - p := w.p.fset.Position(pos) - file := p.Filename - line := int64(p.Line) - - // When file is the same as the last position (common case), - // we can save a few bytes by delta encoding just the line - // number. - // - // Note: Because data objects may be read out of order (or not - // at all), we can only apply delta encoding within a single - // object. This is handled implicitly by tracking prevFile and - // prevLine as fields of exportWriter. - - if file == w.prevFile { - delta := line - w.prevLine - w.int64(delta) - if delta == deltaNewFile { - w.int64(-1) - } - } else { - w.int64(deltaNewFile) - w.int64(line) // line >= 0 - w.string(file) - w.prevFile = file - } - w.prevLine = line -} - -func (w *exportWriter) pkg(pkg *types.Package) { - if pkg == nil { - // [exportWriter.typ] accepts a nil pkg only for types - // of constants, which cannot contain named objects - // such as fields or methods and thus should never - // reach this method (#76222). - panic("nil package") - } - // Ensure any referenced packages are declared in the main index. - w.p.allPkgs[pkg] = true - - w.string(w.exportPath(pkg)) -} - -func (w *exportWriter) qualifiedType(obj *types.TypeName) { - name := w.p.exportName(obj) - - // Ensure any referenced declarations are written out too. - w.p.pushDecl(obj) - w.string(name) - w.pkg(obj.Pkg()) -} - -// typ emits the specified type. -// -// Objects within the type (struct fields and interface methods) are -// qualified by pkg. It may be nil if the type cannot contain objects, -// such as the type of a constant. -func (w *exportWriter) typ(t types.Type, pkg *types.Package) { - w.data.uint64(w.p.typOff(t, pkg)) -} - -func (p *iexporter) newWriter() *exportWriter { - return &exportWriter{p: p} -} - -func (w *exportWriter) flush() uint64 { - off := uint64(w.p.data0.Len()) - io.Copy(&w.p.data0, &w.data) - return off -} - -func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 { - off, ok := p.typIndex[t] - if !ok { - w := p.newWriter() - w.doTyp(t, pkg) - off = predeclReserved + w.flush() - p.typIndex[t] = off - } - return off -} - -func (w *exportWriter) startType(k itag) { - w.data.uint64(uint64(k)) -} - -// doTyp is the implementation of [exportWriter.typ]. -func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { - if trace { - w.p.trace("exporting type %s (%T)", t, t) - w.p.indent++ - defer func() { - w.p.indent-- - w.p.trace("=> %s", t) - }() - } - switch t := t.(type) { - case *types.Alias: - if targs := t.TypeArgs(); targs.Len() > 0 { - w.startType(instanceType) - w.pos(t.Obj().Pos()) - w.typeList(targs, pkg) - w.typ(t.Origin(), pkg) - return - } - w.startType(aliasType) - w.qualifiedType(t.Obj()) - - case *types.Named: - if targs := t.TypeArgs(); targs.Len() > 0 { - w.startType(instanceType) - // TODO(rfindley): investigate if this position is correct, and if it - // matters. - w.pos(t.Obj().Pos()) - w.typeList(targs, pkg) - w.typ(t.Origin(), pkg) - return - } - w.startType(definedType) - w.qualifiedType(t.Obj()) - - case *types.TypeParam: - w.startType(typeParamType) - w.qualifiedType(t.Obj()) - - case *types.Pointer: - w.startType(pointerType) - w.typ(t.Elem(), pkg) - - case *types.Slice: - w.startType(sliceType) - w.typ(t.Elem(), pkg) - - case *types.Array: - w.startType(arrayType) - w.uint64(uint64(t.Len())) - w.typ(t.Elem(), pkg) - - case *types.Chan: - w.startType(chanType) - // 1 RecvOnly; 2 SendOnly; 3 SendRecv - var dir uint64 - switch t.Dir() { - case types.RecvOnly: - dir = 1 - case types.SendOnly: - dir = 2 - case types.SendRecv: - dir = 3 - } - w.uint64(dir) - w.typ(t.Elem(), pkg) - - case *types.Map: - w.startType(mapType) - w.typ(t.Key(), pkg) - w.typ(t.Elem(), pkg) - - case *types.Signature: - w.startType(signatureType) - w.pkg(pkg) // qualifies param/result vars - w.signature(t) - - case *types.Struct: - w.startType(structType) - n := t.NumFields() - // Even for struct{} we must emit some qualifying package, because that's - // what the compiler does, and thus that's what the importer expects. - fieldPkg := pkg - if n > 0 { - fieldPkg = t.Field(0).Pkg() - } - if fieldPkg == nil { - // TODO(rfindley): improve this very hacky logic. - // - // The importer expects a package to be set for all struct types, even - // those with no fields. A better encoding might be to set NumFields - // before pkg. setPkg panics with a nil package, which may be possible - // to reach with invalid packages (and perhaps valid packages, too?), so - // (arbitrarily) set the localpkg if available. - // - // Alternatively, we may be able to simply guarantee that pkg != nil, by - // reconsidering the encoding of constant values. - if w.p.shallow { - fieldPkg = w.p.localpkg - } else { - panic(internalErrorf("no package to set for empty struct")) - } - } - w.pkg(fieldPkg) - w.uint64(uint64(n)) - - for i := range n { - f := t.Field(i) - if w.p.shallow { - w.objectPath(f) - } - w.pos(f.Pos()) - w.string(f.Name()) // unexported fields implicitly qualified by prior setPkg - w.typ(f.Type(), fieldPkg) - w.bool(f.Anonymous()) - w.string(t.Tag(i)) // note (or tag) - } - - case *types.Interface: - w.startType(interfaceType) - w.pkg(pkg) // qualifies unexported method funcs - - n := t.NumEmbeddeds() - w.uint64(uint64(n)) - for i := 0; i < n; i++ { - ft := t.EmbeddedType(i) - if named, _ := types.Unalias(ft).(*types.Named); named != nil { - w.pos(named.Obj().Pos()) - } else { - // e.g. ~int - w.pos(token.NoPos) - } - w.typ(ft, pkg) - } - - // See comment for struct fields. In shallow mode we change the encoding - // for interface methods that are promoted from other packages. - - n = t.NumExplicitMethods() - w.uint64(uint64(n)) - for i := 0; i < n; i++ { - m := t.ExplicitMethod(i) - if w.p.shallow { - w.objectPath(m) - } - w.pos(m.Pos()) - w.string(m.Name()) - sig, _ := m.Type().(*types.Signature) - w.signature(sig) - } - - case *types.Union: - w.startType(unionType) - nt := t.Len() - w.uint64(uint64(nt)) - for i := range nt { - term := t.Term(i) - w.bool(term.Tilde()) - w.typ(term.Type(), pkg) - } - - default: - panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t))) - } -} - -// objectPath writes the package and objectPath to use to look up obj in a -// different package, when encoding in "shallow" mode. -// -// When doing a shallow import, the importer creates only the local package, -// and requests package symbols for dependencies from the client. -// However, certain types defined in the local package may hold objects defined -// (perhaps deeply) within another package. -// -// For example, consider the following: -// -// package a -// func F() chan * map[string] struct { X int } -// -// package b -// import "a" -// var B = a.F() -// -// In this example, the type of b.B holds fields defined in package a. -// In order to have the correct canonical objects for the field defined in the -// type of B, they are encoded as objectPaths and later looked up in the -// importer. The same problem applies to interface methods. -func (w *exportWriter) objectPath(obj types.Object) { - if obj.Pkg() == nil || obj.Pkg() == w.p.localpkg { - // obj.Pkg() may be nil for the builtin error.Error. - // In this case, or if obj is declared in the local package, no need to - // encode. - w.string("") - return - } - objectPath, err := w.p.objectpathEncoder().For(obj) - if err != nil { - // Fall back to the empty string, which will cause the importer to create a - // new object, which matches earlier behavior. Creating a new object is - // sufficient for many purposes (such as type checking), but causes certain - // references algorithms to fail (golang/go#60819). However, we didn't - // notice this problem during months of gopls@v0.12.0 testing. - // - // TODO(golang/go#61674): this workaround is insufficient, as in the case - // where the field forwarded from an instantiated type that may not appear - // in the export data of the original package: - // - // // package a - // type A[P any] struct{ F P } - // - // // package b - // type B a.A[int] - // - // We need to update references algorithms not to depend on this - // de-duplication, at which point we may want to simply remove the - // workaround here. - w.string("") - return - } - w.string(string(objectPath)) - w.pkg(obj.Pkg()) -} - -func (w *exportWriter) signature(sig *types.Signature) { - w.paramList(sig.Params()) - w.paramList(sig.Results()) - if sig.Params().Len() > 0 { - w.bool(sig.Variadic()) - } -} - -func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) { - w.uint64(uint64(ts.Len())) - for t := range ts.Types() { - w.typ(t, pkg) - } -} - -func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) { - ll := uint64(list.Len()) - w.uint64(ll) - for tparam := range list.TypeParams() { - // Set the type parameter exportName before exporting its type. - exportName := tparamExportName(prefix, tparam) - w.p.tparamNames[tparam.Obj()] = exportName - w.typ(tparam, pkg) - } -} - -const blankMarker = "$" - -// tparamExportName returns the 'exported' name of a type parameter, which -// differs from its actual object name: it is prefixed with a qualifier, and -// blank type parameter names are disambiguated by their index in the type -// parameter list. -func tparamExportName(prefix string, tparam *types.TypeParam) string { - assert(prefix != "") - name := tparam.Obj().Name() - if name == "_" { - name = blankMarker + strconv.Itoa(tparam.Index()) - } - return prefix + "." + name -} - -// tparamName returns the real name of a type parameter, after stripping its -// qualifying prefix and reverting blank-name encoding. See tparamExportName -// for details. -func tparamName(exportName string) string { - // Remove the "path" from the type param name that makes it unique. - ix := strings.LastIndex(exportName, ".") - if ix < 0 { - errorf("malformed type parameter export name %s: missing prefix", exportName) - } - name := exportName[ix+1:] - if strings.HasPrefix(name, blankMarker) { - return "_" - } - return name -} - -func (w *exportWriter) paramList(tup *types.Tuple) { - n := tup.Len() - w.uint64(uint64(n)) - for i := range n { - w.param(tup.At(i)) - } -} - -func (w *exportWriter) param(obj types.Object) { - w.pos(obj.Pos()) - w.localIdent(obj) - w.typ(obj.Type(), obj.Pkg()) -} - -func (w *exportWriter) value(typ types.Type, v constant.Value) { - w.typ(typ, nil) - if w.p.version >= iexportVersionGo1_18 { - w.int64(int64(v.Kind())) - } - - if v.Kind() == constant.Unknown { - // golang/go#60605: treat unknown constant values as if they have invalid type - // - // This loses some fidelity over the package type-checked from source, but that - // is acceptable. - // - // TODO(rfindley): we should switch on the recorded constant kind rather - // than the constant type - return - } - - switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { - case types.IsBoolean: - w.bool(constant.BoolVal(v)) - case types.IsInteger: - var i big.Int - if i64, exact := constant.Int64Val(v); exact { - i.SetInt64(i64) - } else if ui64, exact := constant.Uint64Val(v); exact { - i.SetUint64(ui64) - } else { - i.SetString(v.ExactString(), 10) - } - w.mpint(&i, typ) - case types.IsFloat: - f := constantToFloat(v) - w.mpfloat(f, typ) - case types.IsComplex: - w.mpfloat(constantToFloat(constant.Real(v)), typ) - w.mpfloat(constantToFloat(constant.Imag(v)), typ) - case types.IsString: - w.string(constant.StringVal(v)) - default: - if b.Kind() == types.Invalid { - // package contains type errors - break - } - panic(internalErrorf("unexpected type %v (%v)", typ, typ.Underlying())) - } -} - -// constantToFloat converts a constant.Value with kind constant.Float to a -// big.Float. -func constantToFloat(x constant.Value) *big.Float { - x = constant.ToFloat(x) - // Use the same floating-point precision (512) as cmd/compile - // (see Mpprec in cmd/compile/internal/gc/mpfloat.go). - const mpprec = 512 - var f big.Float - f.SetPrec(mpprec) - if v, exact := constant.Float64Val(x); exact { - // float64 - f.SetFloat64(v) - } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int { - // TODO(gri): add big.Rat accessor to constant.Value. - n := valueToRat(num) - d := valueToRat(denom) - f.SetRat(n.Quo(n, d)) - } else { - // Value too large to represent as a fraction => inaccessible. - // TODO(gri): add big.Float accessor to constant.Value. - _, ok := f.SetString(x.ExactString()) - assert(ok) - } - return &f -} - -func valueToRat(x constant.Value) *big.Rat { - // Convert little-endian to big-endian. - // I can't believe this is necessary. - bytes := constant.Bytes(x) - for i := 0; i < len(bytes)/2; i++ { - bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i] - } - return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes)) -} - -// mpint exports a multi-precision integer. -// -// For unsigned types, small values are written out as a single -// byte. Larger values are written out as a length-prefixed big-endian -// byte string, where the length prefix is encoded as its complement. -// For example, bytes 0, 1, and 2 directly represent the integer -// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-, -// 2-, and 3-byte big-endian string follow. -// -// Encoding for signed types use the same general approach as for -// unsigned types, except small values use zig-zag encoding and the -// bottom bit of length prefix byte for large values is reserved as a -// sign bit. -// -// The exact boundary between small and large encodings varies -// according to the maximum number of bytes needed to encode a value -// of type typ. As a special case, 8-bit types are always encoded as a -// single byte. -// -// TODO(mdempsky): Is this level of complexity really worthwhile? -func (w *exportWriter) mpint(x *big.Int, typ types.Type) { - basic, ok := typ.Underlying().(*types.Basic) - if !ok { - panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying())) - } - - signed, maxBytes := intSize(basic) - - negative := x.Sign() < 0 - if !signed && negative { - panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x)) - } - - b := x.Bytes() - if len(b) > 0 && b[0] == 0 { - panic(internalErrorf("leading zeros")) - } - if uint(len(b)) > maxBytes { - panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x)) - } - - maxSmall := 256 - maxBytes - if signed { - maxSmall = 256 - 2*maxBytes - } - if maxBytes == 1 { - maxSmall = 256 - } - - // Check if x can use small value encoding. - if len(b) <= 1 { - var ux uint - if len(b) == 1 { - ux = uint(b[0]) - } - if signed { - ux <<= 1 - if negative { - ux-- - } - } - if ux < maxSmall { - w.data.WriteByte(byte(ux)) - return - } - } - - n := 256 - uint(len(b)) - if signed { - n = 256 - 2*uint(len(b)) - if negative { - n |= 1 - } - } - if n < maxSmall || n >= 256 { - panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n)) - } - - w.data.WriteByte(byte(n)) - w.data.Write(b) -} - -// mpfloat exports a multi-precision floating point number. -// -// The number's value is decomposed into mantissa × 2**exponent, where -// mantissa is an integer. The value is written out as mantissa (as a -// multi-precision integer) and then the exponent, except exponent is -// omitted if mantissa is zero. -func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) { - if f.IsInf() { - panic("infinite constant") - } - - // Break into f = mant × 2**exp, with 0.5 <= mant < 1. - var mant big.Float - exp := int64(f.MantExp(&mant)) - - // Scale so that mant is an integer. - prec := mant.MinPrec() - mant.SetMantExp(&mant, int(prec)) - exp -= int64(prec) - - manti, acc := mant.Int(nil) - if acc != big.Exact { - panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc)) - } - w.mpint(manti, typ) - if manti.Sign() != 0 { - w.int64(exp) - } -} - -func (w *exportWriter) bool(b bool) bool { - var x uint64 - if b { - x = 1 - } - w.uint64(x) - return b -} - -func (w *exportWriter) int64(x int64) { w.data.int64(x) } -func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) } -func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) } - -func (w *exportWriter) localIdent(obj types.Object) { - // Anonymous parameters. - if obj == nil { - w.string("") - return - } - - name := obj.Name() - if name == "_" { - w.string("_") - return - } - - w.string(name) -} - -type intWriter struct { - bytes.Buffer -} - -func (w *intWriter) int64(x int64) { - var buf [binary.MaxVarintLen64]byte - n := binary.PutVarint(buf[:], x) - w.Write(buf[:n]) -} - -func (w *intWriter) uint64(x uint64) { - var buf [binary.MaxVarintLen64]byte - n := binary.PutUvarint(buf[:], x) - w.Write(buf[:n]) -} - -func assert(cond bool) { - if !cond { - panic("internal error: assertion failed") - } -} - -// The below is copied from go/src/cmd/compile/internal/gc/syntax.go. - -// objQueue is a FIFO queue of types.Object. The zero value of objQueue is -// a ready-to-use empty queue. -type objQueue struct { - ring []types.Object - head, tail int -} - -// empty returns true if q contains no Nodes. -func (q *objQueue) empty() bool { - return q.head == q.tail -} - -// pushTail appends n to the tail of the queue. -func (q *objQueue) pushTail(obj types.Object) { - if len(q.ring) == 0 { - q.ring = make([]types.Object, 16) - } else if q.head+len(q.ring) == q.tail { - // Grow the ring. - nring := make([]types.Object, len(q.ring)*2) - // Copy the old elements. - part := q.ring[q.head%len(q.ring):] - if q.tail-q.head <= len(part) { - part = part[:q.tail-q.head] - copy(nring, part) - } else { - pos := copy(nring, part) - copy(nring[pos:], q.ring[:q.tail%len(q.ring)]) - } - q.ring, q.head, q.tail = nring, 0, q.tail-q.head - } - - q.ring[q.tail%len(q.ring)] = obj - q.tail++ -} - -// popHead pops a node from the head of the queue. It panics if q is empty. -func (q *objQueue) popHead() types.Object { - if q.empty() { - panic("dequeue empty") - } - obj := q.ring[q.head%len(q.ring)] - q.head++ - return obj -} - -// internalError represents an error generated inside this package. -type internalError string - -func (e internalError) Error() string { return "gcimporter: " + string(e) } - -// TODO(adonovan): make this call panic, so that it's symmetric with errorf. -// Otherwise it's easy to forget to do anything with the error. -// -// TODO(adonovan): also, consider switching the names "errorf" and -// "internalErrorf" as the former is used for bugs, whose cause is -// internal inconsistency, whereas the latter is used for ordinary -// situations like bad input, whose cause is external. -func internalErrorf(format string, args ...any) error { - return internalError(fmt.Sprintf(format, args...)) -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go deleted file mode 100644 index 1ee4e935..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go +++ /dev/null @@ -1,1118 +0,0 @@ -// Copyright 2018 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. - -// Indexed package import. -// See iexport.go for the export data format. - -package gcimporter - -import ( - "bytes" - "encoding/binary" - "fmt" - "go/constant" - "go/token" - "go/types" - "io" - "math/big" - "slices" - "sort" - "strings" - - "golang.org/x/tools/go/types/objectpath" - "golang.org/x/tools/internal/aliases" - "golang.org/x/tools/internal/typesinternal" -) - -type intReader struct { - *bytes.Reader - path string -} - -func (r *intReader) int64() int64 { - i, err := binary.ReadVarint(r.Reader) - if err != nil { - errorf("import %q: read varint error: %v", r.path, err) - } - return i -} - -func (r *intReader) uint64() uint64 { - i, err := binary.ReadUvarint(r.Reader) - if err != nil { - errorf("import %q: read varint error: %v", r.path, err) - } - return i -} - -// Keep this in sync with constants in iexport.go. -const ( - iexportVersionGo1_11 = 0 - iexportVersionPosCol = 1 - iexportVersionGo1_18 = 2 - iexportVersionGenerics = 2 - iexportVersion = iexportVersionGenerics - - iexportVersionCurrent = 2 -) - -type ident struct { - pkg *types.Package - name string -} - -const predeclReserved = 32 - -type itag uint64 - -const ( - // Types - definedType itag = iota - pointerType - sliceType - arrayType - chanType - mapType - signatureType - structType - interfaceType - typeParamType - instanceType - unionType - aliasType -) - -// Object tags -const ( - varTag = 'V' - funcTag = 'F' - genericFuncTag = 'G' - constTag = 'C' - aliasTag = 'A' - genericAliasTag = 'B' - typeParamTag = 'P' - typeTag = 'T' - genericTypeTag = 'U' -) - -// IImportData imports a package from the serialized package data -// and returns 0 and a reference to the package. -// If the export data version is not recognized or the format is otherwise -// compromised, an error is returned. -func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) { - pkgs, err := iimportCommon(fset, GetPackagesFromMap(imports), data, false, path, false, nil) - if err != nil { - return 0, nil, err - } - return 0, pkgs[0], nil -} - -// IImportBundle imports a set of packages from the serialized package bundle. -func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) { - return iimportCommon(fset, GetPackagesFromMap(imports), data, true, "", false, nil) -} - -// A GetPackagesFunc function obtains the non-nil symbols for a set of -// packages, creating and recursively importing them as needed. An -// implementation should store each package symbol is in the Pkg -// field of the items array. -// -// Any error causes importing to fail. This can be used to quickly read -// the import manifest of an export data file without fully decoding it. -type GetPackagesFunc = func(items []GetPackagesItem) error - -// A GetPackagesItem is a request from the importer for the package -// symbol of the specified name and path. -type GetPackagesItem struct { - Name, Path string - Pkg *types.Package // to be filled in by GetPackagesFunc call - - // private importer state - pathOffset uint64 - nameIndex map[string]uint64 -} - -// GetPackagesFromMap returns a GetPackagesFunc that retrieves -// packages from the given map of package path to package. -// -// The returned function may mutate m: each requested package that is not -// found is created with types.NewPackage and inserted into m. -func GetPackagesFromMap(m map[string]*types.Package) GetPackagesFunc { - return func(items []GetPackagesItem) error { - for i, item := range items { - pkg, ok := m[item.Path] - if !ok { - pkg = types.NewPackage(item.Path, item.Name) - m[item.Path] = pkg - } - items[i].Pkg = pkg - } - return nil - } -} - -func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, bundle bool, path string, shallow bool, reportf ReportFunc) (pkgs []*types.Package, err error) { - const currentVersion = iexportVersionCurrent - version := int64(-1) - if !debug { - defer func() { - if e := recover(); e != nil { - if bundle { - err = fmt.Errorf("%v", e) - } else if version > currentVersion { - err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) - } else { - err = fmt.Errorf("internal error while importing %q (%v); please report an issue", path, e) - } - } - }() - } - - r := &intReader{bytes.NewReader(data), path} - - if bundle { - if v := r.uint64(); v != bundleVersion { - errorf("unknown bundle format version %d", v) - } - } - - version = int64(r.uint64()) - switch version { - case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11: - default: - if version > iexportVersionGo1_18 { - errorf("unstable iexport format version %d, just rebuild compiler and std library", version) - } else { - errorf("unknown iexport format version %d", version) - } - } - - sLen := int64(r.uint64()) - var fLen int64 - var fileOffset []uint64 - if shallow { - // Shallow mode uses a different position encoding. - fLen = int64(r.uint64()) - fileOffset = make([]uint64, r.uint64()) - for i := range fileOffset { - fileOffset[i] = r.uint64() - } - } - dLen := int64(r.uint64()) - - whence, _ := r.Seek(0, io.SeekCurrent) - stringData := data[whence : whence+sLen] - fileData := data[whence+sLen : whence+sLen+fLen] - declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen] - r.Seek(sLen+fLen+dLen, io.SeekCurrent) - - p := iimporter{ - version: int(version), - ipath: path, - shallow: shallow, - reportf: reportf, - - stringData: stringData, - stringCache: make(map[uint64]string), - fileOffset: fileOffset, - fileData: fileData, - fileCache: make([]*token.File, len(fileOffset)), - pkgCache: make(map[uint64]*types.Package), - - declData: declData, - pkgIndex: make(map[*types.Package]map[string]uint64), - typCache: make(map[uint64]types.Type), - // Separate map for typeparams, keyed by their package and unique - // name. - tparamIndex: make(map[ident]types.Type), - - fake: fakeFileSet{ - fset: fset, - files: make(map[string]*fileInfo), - }, - } - defer p.fake.setLines() // set lines for files in fset - - for i, pt := range predeclared() { - p.typCache[uint64(i)] = pt - } - - // Gather the relevant packages from the manifest. - items := make([]GetPackagesItem, r.uint64()) - uniquePkgPaths := make(map[string]bool) - for i := range items { - pkgPathOff := r.uint64() - pkgPath := p.stringAt(pkgPathOff) - pkgName := p.stringAt(r.uint64()) - _ = r.uint64() // package height; unused by go/types - - if pkgPath == "" { - pkgPath = path - } - items[i].Name = pkgName - items[i].Path = pkgPath - items[i].pathOffset = pkgPathOff - - // Read index for package. - nameIndex := make(map[string]uint64) - nSyms := r.uint64() - // In shallow mode, only the current package (i=0) has an index. - assert(!(shallow && i > 0 && nSyms != 0)) - for ; nSyms > 0; nSyms-- { - name := p.stringAt(r.uint64()) - nameIndex[name] = r.uint64() - } - - items[i].nameIndex = nameIndex - - uniquePkgPaths[pkgPath] = true - } - // Debugging #63822; hypothesis: there are duplicate PkgPaths. - if len(uniquePkgPaths) != len(items) { - reportf("found duplicate PkgPaths while reading export data manifest: %v", items) - } - - // Request packages all at once from the client, - // enabling a parallel implementation. - if err := getPackages(items); err != nil { - return nil, err // don't wrap this error - } - - // Check the results and complete the index. - pkgList := make([]*types.Package, len(items)) - for i, item := range items { - pkg := item.Pkg - if pkg == nil { - errorf("internal error: getPackages returned nil package for %q", item.Path) - } else if pkg.Path() != item.Path { - errorf("internal error: getPackages returned wrong path %q, want %q", pkg.Path(), item.Path) - } else if pkg.Name() != item.Name { - errorf("internal error: getPackages returned wrong name %s for package %q, want %s", pkg.Name(), item.Path, item.Name) - } - p.pkgCache[item.pathOffset] = pkg - p.pkgIndex[pkg] = item.nameIndex - pkgList[i] = pkg - } - - if bundle { - pkgs = make([]*types.Package, r.uint64()) - for i := range pkgs { - pkg := p.pkgAt(r.uint64()) - imps := make([]*types.Package, r.uint64()) - for j := range imps { - imps[j] = p.pkgAt(r.uint64()) - } - pkg.SetImports(imps) - pkgs[i] = pkg - } - } else { - if len(pkgList) == 0 { - errorf("no packages found for %s", path) - panic("unreachable") - } - pkgs = pkgList[:1] - - // record all referenced packages as imports - list := slices.Clone(pkgList[1:]) - sort.Sort(byPath(list)) - pkgs[0].SetImports(list) - } - - for _, pkg := range pkgs { - if pkg.Complete() { - continue - } - - names := make([]string, 0, len(p.pkgIndex[pkg])) - for name := range p.pkgIndex[pkg] { - names = append(names, name) - } - sort.Strings(names) - for _, name := range names { - p.doDecl(pkg, name) - } - - // package was imported completely and without errors - pkg.MarkComplete() - } - - // SetConstraint can't be called if the constraint type is not yet complete. - // When type params are created in the typeParamTag case of (*importReader).obj(), - // the associated constraint type may not be complete due to recursion. - // Therefore, we defer calling SetConstraint there, and call it here instead - // after all types are complete. - for _, d := range p.later { - d.t.SetConstraint(d.constraint) - } - - for _, typ := range p.interfaceList { - typ.Complete() - } - - // Workaround for golang/go#61561. See the doc for instanceList for details. - for _, typ := range p.instanceList { - if iface, _ := typ.Underlying().(*types.Interface); iface != nil { - iface.Complete() - } - } - - return pkgs, nil -} - -type setConstraintArgs struct { - t *types.TypeParam - constraint types.Type -} - -type iimporter struct { - version int - ipath string - - shallow bool - reportf ReportFunc // if non-nil, used to report bugs - - stringData []byte - stringCache map[uint64]string - fileOffset []uint64 // fileOffset[i] is offset in fileData for info about file encoded as i - fileData []byte - fileCache []*token.File // memoized decoding of file encoded as i - pkgCache map[uint64]*types.Package - - declData []byte - pkgIndex map[*types.Package]map[string]uint64 - typCache map[uint64]types.Type - tparamIndex map[ident]types.Type - - fake fakeFileSet - interfaceList []*types.Interface - - // Workaround for the go/types bug golang/go#61561: instances produced during - // instantiation may contain incomplete interfaces. Here we only complete the - // underlying type of the instance, which is the most common case but doesn't - // handle parameterized interface literals defined deeper in the type. - instanceList []types.Type // instances for later completion (see golang/go#61561) - - // Arguments for calls to SetConstraint that are deferred due to recursive types - later []setConstraintArgs - - indent int // for tracing support -} - -func (p *iimporter) trace(format string, args ...any) { - if !trace { - // Call sites should also be guarded, but having this check here allows - // easily enabling/disabling debug trace statements. - return - } - fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...) -} - -func (p *iimporter) doDecl(pkg *types.Package, name string) { - if debug { - p.trace("import decl %s", name) - p.indent++ - defer func() { - p.indent-- - p.trace("=> %s", name) - }() - } - // See if we've already imported this declaration. - if obj := pkg.Scope().Lookup(name); obj != nil { - return - } - - off, ok := p.pkgIndex[pkg][name] - if !ok { - // In deep mode, the index should be complete. In shallow - // mode, we should have already recursively loaded necessary - // dependencies so the above Lookup succeeds. - errorf("%v.%v not in index", pkg, name) - } - - r := &importReader{p: p} - r.declReader.Reset(p.declData[off:]) - - r.obj(pkg, name) -} - -func (p *iimporter) stringAt(off uint64) string { - if s, ok := p.stringCache[off]; ok { - return s - } - - slen, n := binary.Uvarint(p.stringData[off:]) - if n <= 0 { - errorf("varint failed") - } - spos := off + uint64(n) - s := string(p.stringData[spos : spos+slen]) - p.stringCache[off] = s - return s -} - -func (p *iimporter) fileAt(index uint64) *token.File { - file := p.fileCache[index] - if file == nil { - off := p.fileOffset[index] - file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath}) - p.fileCache[index] = file - } - return file -} - -func (p *iimporter) decodeFile(rd intReader) *token.File { - filename := p.stringAt(rd.uint64()) - size := int(rd.uint64()) - file := p.fake.fset.AddFile(filename, -1, size) - - // SetLines requires a nondecreasing sequence. - // Because it is common for clients to derive the interval - // [start, start+len(name)] from a start position, and we - // want to ensure that the end offset is on the same line, - // we fill in the gaps of the sparse encoding with values - // that strictly increase by the largest possible amount. - // This allows us to avoid having to record the actual end - // offset of each needed line. - - lines := make([]int, int(rd.uint64())) - var index, offset int - for i, n := 0, int(rd.uint64()); i < n; i++ { - index += int(rd.uint64()) - offset += int(rd.uint64()) - lines[index] = offset - - // Ensure monotonicity between points. - for j := index - 1; j > 0 && lines[j] == 0; j-- { - lines[j] = lines[j+1] - 1 - } - } - - // Ensure monotonicity after last point. - for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- { - size-- - lines[j] = size - } - - if !file.SetLines(lines) { - errorf("SetLines failed: %d", lines) // can't happen - } - return file -} - -func (p *iimporter) pkgAt(off uint64) *types.Package { - if pkg, ok := p.pkgCache[off]; ok { - return pkg - } - path := p.stringAt(off) - errorf("missing package %q in %q", path, p.ipath) - return nil -} - -func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { - if t, ok := p.typCache[off]; ok && canReuse(base, t) { - return t - } - - if off < predeclReserved { - errorf("predeclared type missing from cache: %v", off) - } - - r := &importReader{p: p} - r.declReader.Reset(p.declData[off-predeclReserved:]) - t := r.doType(base) - - if canReuse(base, t) { - p.typCache[off] = t - } - return t -} - -// canReuse reports whether the type rhs on the RHS of the declaration for def -// may be re-used. -// -// Specifically, if def is non-nil and rhs is an interface type with methods, it -// may not be re-used because we have a convention of setting the receiver type -// for interface methods to def. -func canReuse(def *types.Named, rhs types.Type) bool { - if def == nil { - return true - } - iface, _ := types.Unalias(rhs).(*types.Interface) - if iface == nil { - return true - } - // Don't use iface.Empty() here as iface may not be complete. - return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 -} - -type importReader struct { - p *iimporter - declReader bytes.Reader - prevFile string - prevLine int64 - prevColumn int64 -} - -// markBlack is redefined in iimport_go123.go, to work around golang/go#69912. -// -// If TypeNames are not marked black (in the sense of go/types cycle -// detection), they may be mutated when dot-imported. Fix this by punching a -// hole through the type, when compiling with Go 1.23. (The bug has been fixed -// for 1.24, but the fix was not worth back-porting). -var markBlack = func(name *types.TypeName) {} - -// obj decodes and declares the package-level object denoted by (pkg, name). -func (r *importReader) obj(pkg *types.Package, name string) { - tag := r.byte() - pos := r.pos() - - switch tag { - case aliasTag, genericAliasTag: - var tparams []*types.TypeParam - if tag == genericAliasTag { - tparams = r.tparamList() - } - typ := r.typ() - obj := aliases.New(pos, pkg, name, typ, tparams) - markBlack(obj) // workaround for golang/go#69912 - r.declare(obj) - - case constTag: - typ, val := r.value() - - r.declare(types.NewConst(pos, pkg, name, typ, val)) - - case funcTag, genericFuncTag: - var tparams []*types.TypeParam - if tag == genericFuncTag { - tparams = r.tparamList() - } - sig := r.signature(pkg, nil, nil, tparams) - r.declare(types.NewFunc(pos, pkg, name, sig)) - - case typeTag, genericTypeTag: - // Types can be recursive. We need to setup a stub - // declaration before recursing. - obj := types.NewTypeName(pos, pkg, name, nil) - named := types.NewNamed(obj, nil, nil) - - markBlack(obj) // workaround for golang/go#69912 - - // Declare obj before calling r.tparamList, so the new type name is recognized - // if used in the constraint of one of its own typeparams (see #48280). - r.declare(obj) - if tag == genericTypeTag { - tparams := r.tparamList() - named.SetTypeParams(tparams) - } - - underlying := r.p.typAt(r.uint64(), named).Underlying() - named.SetUnderlying(underlying) - - if !isInterface(underlying) { - for n := r.uint64(); n > 0; n-- { - mpos := r.pos() - mname := r.ident() - recv := r.param(pkg) - - // If the receiver has any targs, set those as the - // rparams of the method (since those are the - // typeparams being used in the method sig/body). - _, recvNamed := typesinternal.ReceiverNamed(recv) - targs := recvNamed.TypeArgs() - var rparams []*types.TypeParam - if targs.Len() > 0 { - rparams = make([]*types.TypeParam, targs.Len()) - for i := range rparams { - rparams[i] = types.Unalias(targs.At(i)).(*types.TypeParam) - } - } - msig := r.signature(pkg, recv, rparams, nil) - - named.AddMethod(types.NewFunc(mpos, pkg, mname, msig)) - } - } - - case typeParamTag: - // We need to "declare" a typeparam in order to have a name that - // can be referenced recursively (if needed) in the type param's - // bound. - if r.p.version < iexportVersionGenerics { - errorf("unexpected type param type") - } - name0 := tparamName(name) - tn := types.NewTypeName(pos, pkg, name0, nil) - t := types.NewTypeParam(tn, nil) - - // To handle recursive references to the typeparam within its - // bound, save the partial type in tparamIndex before reading the bounds. - id := ident{pkg, name} - r.p.tparamIndex[id] = t - var implicit bool - if r.p.version >= iexportVersionGo1_18 { - implicit = r.bool() - } - constraint := r.typ() - if implicit { - iface, _ := types.Unalias(constraint).(*types.Interface) - if iface == nil { - errorf("non-interface constraint marked implicit") - } - iface.MarkImplicit() - } - // The constraint type may not be complete, if we - // are in the middle of a type recursion involving type - // constraints. So, we defer SetConstraint until we have - // completely set up all types in ImportData. - r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint}) - - case varTag: - typ := r.typ() - - v := types.NewVar(pos, pkg, name, typ) - typesinternal.SetVarKind(v, typesinternal.PackageVar) - r.declare(v) - - default: - errorf("unexpected tag: %v", tag) - } -} - -func (r *importReader) declare(obj types.Object) { - obj.Pkg().Scope().Insert(obj) -} - -func (r *importReader) value() (typ types.Type, val constant.Value) { - typ = r.typ() - if r.p.version >= iexportVersionGo1_18 { - // TODO: add support for using the kind. - _ = constant.Kind(r.int64()) - } - - switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { - case types.IsBoolean: - val = constant.MakeBool(r.bool()) - - case types.IsString: - val = constant.MakeString(r.string()) - - case types.IsInteger: - var x big.Int - r.mpint(&x, b) - val = constant.Make(&x) - - case types.IsFloat: - val = r.mpfloat(b) - - case types.IsComplex: - re := r.mpfloat(b) - im := r.mpfloat(b) - val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) - - default: - if b.Kind() == types.Invalid { - val = constant.MakeUnknown() - return - } - errorf("unexpected type %v", typ) // panics - panic("unreachable") - } - - return -} - -func intSize(b *types.Basic) (signed bool, maxBytes uint) { - if (b.Info() & types.IsUntyped) != 0 { - return true, 64 - } - - switch b.Kind() { - case types.Float32, types.Complex64: - return true, 3 - case types.Float64, types.Complex128: - return true, 7 - } - - signed = (b.Info() & types.IsUnsigned) == 0 - switch b.Kind() { - case types.Int8, types.Uint8: - maxBytes = 1 - case types.Int16, types.Uint16: - maxBytes = 2 - case types.Int32, types.Uint32: - maxBytes = 4 - default: - maxBytes = 8 - } - - return -} - -func (r *importReader) mpint(x *big.Int, typ *types.Basic) { - signed, maxBytes := intSize(typ) - - maxSmall := 256 - maxBytes - if signed { - maxSmall = 256 - 2*maxBytes - } - if maxBytes == 1 { - maxSmall = 256 - } - - n, _ := r.declReader.ReadByte() - if uint(n) < maxSmall { - v := int64(n) - if signed { - v >>= 1 - if n&1 != 0 { - v = ^v - } - } - x.SetInt64(v) - return - } - - v := -n - if signed { - v = -(n &^ 1) >> 1 - } - if v < 1 || uint(v) > maxBytes { - errorf("weird decoding: %v, %v => %v", n, signed, v) - } - b := make([]byte, v) - io.ReadFull(&r.declReader, b) - x.SetBytes(b) - if signed && n&1 != 0 { - x.Neg(x) - } -} - -func (r *importReader) mpfloat(typ *types.Basic) constant.Value { - var mant big.Int - r.mpint(&mant, typ) - var f big.Float - f.SetInt(&mant) - if f.Sign() != 0 { - f.SetMantExp(&f, int(r.int64())) - } - return constant.Make(&f) -} - -func (r *importReader) ident() string { - return r.string() -} - -func (r *importReader) qualifiedIdent() (*types.Package, string) { - name := r.string() - pkg := r.pkg() - return pkg, name -} - -func (r *importReader) pos() token.Pos { - if r.p.shallow { - // precise offsets are encoded only in shallow mode - return r.posv2() - } - if r.p.version >= iexportVersionPosCol { - r.posv1() - } else { - r.posv0() - } - - if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 { - return token.NoPos - } - return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn)) -} - -func (r *importReader) posv0() { - delta := r.int64() - if delta != deltaNewFile { - r.prevLine += delta - } else if l := r.int64(); l == -1 { - r.prevLine += deltaNewFile - } else { - r.prevFile = r.string() - r.prevLine = l - } -} - -func (r *importReader) posv1() { - delta := r.int64() - r.prevColumn += delta >> 1 - if delta&1 != 0 { - delta = r.int64() - r.prevLine += delta >> 1 - if delta&1 != 0 { - r.prevFile = r.string() - } - } -} - -func (r *importReader) posv2() token.Pos { - file := r.uint64() - if file == 0 { - return token.NoPos - } - tf := r.p.fileAt(file - 1) - return tf.Pos(int(r.uint64())) -} - -func (r *importReader) typ() types.Type { - return r.p.typAt(r.uint64(), nil) -} - -func isInterface(t types.Type) bool { - _, ok := types.Unalias(t).(*types.Interface) - return ok -} - -func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } -func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } - -func (r *importReader) doType(base *types.Named) (res types.Type) { - k := r.kind() - if debug { - r.p.trace("importing type %d (base: %v)", k, base) - r.p.indent++ - defer func() { - r.p.indent-- - r.p.trace("=> %s", res) - }() - } - switch k { - default: - errorf("unexpected kind tag in %q: %v", r.p.ipath, k) - return nil - - case aliasType, definedType: - pkg, name := r.qualifiedIdent() - r.p.doDecl(pkg, name) - return pkg.Scope().Lookup(name).(*types.TypeName).Type() - case pointerType: - return types.NewPointer(r.typ()) - case sliceType: - return types.NewSlice(r.typ()) - case arrayType: - n := r.uint64() - return types.NewArray(r.typ(), int64(n)) - case chanType: - dir := chanDir(int(r.uint64())) - return types.NewChan(dir, r.typ()) - case mapType: - return types.NewMap(r.typ(), r.typ()) - case signatureType: - paramPkg := r.pkg() - return r.signature(paramPkg, nil, nil, nil) - - case structType: - fieldPkg := r.pkg() - - fields := make([]*types.Var, r.uint64()) - tags := make([]string, len(fields)) - for i := range fields { - var field *types.Var - if r.p.shallow { - field, _ = r.objectPathObject().(*types.Var) - } - - fpos := r.pos() - fname := r.ident() - ftyp := r.typ() - emb := r.bool() - tag := r.string() - - // Either this is not a shallow import, the field is local, or the - // encoded objectPath failed to produce an object (a bug). - // - // Even in this last, buggy case, fall back on creating a new field. As - // discussed in iexport.go, this is not correct, but mostly works and is - // preferable to failing (for now at least). - if field == nil { - field = types.NewField(fpos, fieldPkg, fname, ftyp, emb) - } - - fields[i] = field - tags[i] = tag - } - return types.NewStruct(fields, tags) - - case interfaceType: - methodPkg := r.pkg() // qualifies methods and their param/result vars - - embeddeds := make([]types.Type, r.uint64()) - for i := range embeddeds { - _ = r.pos() - embeddeds[i] = r.typ() - } - - methods := make([]*types.Func, r.uint64()) - for i := range methods { - var method *types.Func - if r.p.shallow { - method, _ = r.objectPathObject().(*types.Func) - } - - mpos := r.pos() - mname := r.ident() - - // TODO(mdempsky): Matches bimport.go, but I - // don't agree with this. - var recv *types.Var - if base != nil { - recv = types.NewVar(token.NoPos, methodPkg, "", base) - } - msig := r.signature(methodPkg, recv, nil, nil) - - if method == nil { - method = types.NewFunc(mpos, methodPkg, mname, msig) - } - methods[i] = method - } - - typ := types.NewInterfaceType(methods, embeddeds) - r.p.interfaceList = append(r.p.interfaceList, typ) - return typ - - case typeParamType: - if r.p.version < iexportVersionGenerics { - errorf("unexpected type param type") - } - pkg, name := r.qualifiedIdent() - id := ident{pkg, name} - if t, ok := r.p.tparamIndex[id]; ok { - // We're already in the process of importing this typeparam. - return t - } - // Otherwise, import the definition of the typeparam now. - r.p.doDecl(pkg, name) - return r.p.tparamIndex[id] - - case instanceType: - if r.p.version < iexportVersionGenerics { - errorf("unexpected instantiation type") - } - // pos does not matter for instances: they are positioned on the original - // type. - _ = r.pos() - len := r.uint64() - targs := make([]types.Type, len) - for i := range targs { - targs[i] = r.typ() - } - baseType := r.typ() - // The imported instantiated type doesn't include any methods, so - // we must always use the methods of the base (orig) type. - // TODO provide a non-nil *Environment - t, _ := types.Instantiate(nil, baseType, targs, false) - - // Workaround for golang/go#61561. See the doc for instanceList for details. - r.p.instanceList = append(r.p.instanceList, t) - return t - - case unionType: - if r.p.version < iexportVersionGenerics { - errorf("unexpected instantiation type") - } - terms := make([]*types.Term, r.uint64()) - for i := range terms { - terms[i] = types.NewTerm(r.bool(), r.typ()) - } - return types.NewUnion(terms) - } -} - -func (r *importReader) kind() itag { - return itag(r.uint64()) -} - -// objectPathObject is the inverse of exportWriter.objectPath. -// -// In shallow mode, certain fields and methods may need to be looked up in an -// imported package. See the doc for exportWriter.objectPath for a full -// explanation. -func (r *importReader) objectPathObject() types.Object { - objPath := objectpath.Path(r.string()) - if objPath == "" { - return nil - } - pkg := r.pkg() - obj, err := objectpath.Object(pkg, objPath) - if err != nil { - if r.p.reportf != nil { - r.p.reportf("failed to find object for objectPath %q: %v", objPath, err) - } - } - return obj -} - -func (r *importReader) signature(paramPkg *types.Package, recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature { - params := r.paramList(paramPkg) - results := r.paramList(paramPkg) - variadic := params.Len() > 0 && r.bool() - return types.NewSignatureType(recv, rparams, tparams, params, results, variadic) -} - -func (r *importReader) tparamList() []*types.TypeParam { - n := r.uint64() - if n == 0 { - return nil - } - xs := make([]*types.TypeParam, n) - for i := range xs { - // Note: the standard library importer is tolerant of nil types here, - // though would panic in SetTypeParams. - xs[i] = types.Unalias(r.typ()).(*types.TypeParam) - } - return xs -} - -func (r *importReader) paramList(pkg *types.Package) *types.Tuple { - xs := make([]*types.Var, r.uint64()) - for i := range xs { - xs[i] = r.param(pkg) - } - return types.NewTuple(xs...) -} - -func (r *importReader) param(pkg *types.Package) *types.Var { - pos := r.pos() - name := r.ident() - typ := r.typ() - return types.NewParam(pos, pkg, name, typ) -} - -func (r *importReader) bool() bool { - return r.uint64() != 0 -} - -func (r *importReader) int64() int64 { - n, err := binary.ReadVarint(&r.declReader) - if err != nil { - errorf("readVarint: %v", err) - } - return n -} - -func (r *importReader) uint64() uint64 { - n, err := binary.ReadUvarint(&r.declReader) - if err != nil { - errorf("readUvarint: %v", err) - } - return n -} - -func (r *importReader) byte() byte { - x, err := r.declReader.ReadByte() - if err != nil { - errorf("declReader.ReadByte: %v", err) - } - return x -} - -type byPath []*types.Package - -func (a byPath) Len() int { return len(a) } -func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/predeclared.go b/vendor/golang.org/x/tools/internal/gcimporter/predeclared.go deleted file mode 100644 index 907c8557..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/predeclared.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2024 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 gcimporter - -import ( - "go/types" - "sync" -) - -// predecl is a cache for the predeclared types in types.Universe. -// -// Cache a distinct result based on the runtime value of any. -// The pointer value of the any type varies based on GODEBUG settings. -var predeclMu sync.Mutex -var predecl map[types.Type][]types.Type - -func predeclared() []types.Type { - anyt := types.Universe.Lookup("any").Type() - - predeclMu.Lock() - defer predeclMu.Unlock() - - if pre, ok := predecl[anyt]; ok { - return pre - } - - if predecl == nil { - predecl = make(map[types.Type][]types.Type) - } - - decls := []types.Type{ // basic types - types.Typ[types.Bool], - types.Typ[types.Int], - types.Typ[types.Int8], - types.Typ[types.Int16], - types.Typ[types.Int32], - types.Typ[types.Int64], - types.Typ[types.Uint], - types.Typ[types.Uint8], - types.Typ[types.Uint16], - types.Typ[types.Uint32], - types.Typ[types.Uint64], - types.Typ[types.Uintptr], - types.Typ[types.Float32], - types.Typ[types.Float64], - types.Typ[types.Complex64], - types.Typ[types.Complex128], - types.Typ[types.String], - - // basic type aliases - types.Universe.Lookup("byte").Type(), - types.Universe.Lookup("rune").Type(), - - // error - types.Universe.Lookup("error").Type(), - - // untyped types - types.Typ[types.UntypedBool], - types.Typ[types.UntypedInt], - types.Typ[types.UntypedRune], - types.Typ[types.UntypedFloat], - types.Typ[types.UntypedComplex], - types.Typ[types.UntypedString], - types.Typ[types.UntypedNil], - - // package unsafe - types.Typ[types.UnsafePointer], - - // invalid type - types.Typ[types.Invalid], // only appears in packages with errors - - // used internally by gc; never used by this package or in .a files - anyType{}, - - // comparable - types.Universe.Lookup("comparable").Type(), - - // any - anyt, - } - - predecl[anyt] = decls - return decls -} - -type anyType struct{} - -func (t anyType) Underlying() types.Type { return t } -func (t anyType) String() string { return "any" } diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support.go b/vendor/golang.org/x/tools/internal/gcimporter/support.go deleted file mode 100644 index 4af810dc..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/support.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2024 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 gcimporter - -import ( - "bufio" - "io" - "strconv" - "strings" -) - -// Copy of $GOROOT/src/cmd/internal/archive.ReadHeader. -func readArchiveHeader(b *bufio.Reader, name string) int { - // architecture-independent object file output - const HeaderSize = 60 - - var buf [HeaderSize]byte - if _, err := io.ReadFull(b, buf[:]); err != nil { - return -1 - } - aname := strings.Trim(string(buf[0:16]), " ") - if !strings.HasPrefix(aname, name) { - return -1 - } - asize := strings.Trim(string(buf[48:58]), " ") - i, _ := strconv.Atoi(asize) - return i -} diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader.go deleted file mode 100644 index 3db62b89..00000000 --- a/vendor/golang.org/x/tools/internal/gcimporter/ureader.go +++ /dev/null @@ -1,787 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Derived from go/internal/gcimporter/ureader.go - -package gcimporter - -import ( - "fmt" - "go/token" - "go/types" - "sort" - - "golang.org/x/tools/internal/aliases" - "golang.org/x/tools/internal/pkgbits" - "golang.org/x/tools/internal/typesinternal" -) - -// A pkgReader holds the shared state for reading a unified IR package -// description. -type pkgReader struct { - pkgbits.PkgDecoder - - fake fakeFileSet - - ctxt *types.Context - imports map[string]*types.Package // previously imported packages, indexed by path - - // lazily initialized arrays corresponding to the unified IR - // PosBase, Pkg, and Type sections, respectively. - posBases []string // position bases (i.e., file names) - pkgs []*types.Package - typs []types.Type - - // laterFns holds functions that need to be invoked at the end of - // import reading. - // - // TODO(mdempsky): Is it safe to have a single "later" slice or do - // we need to have multiple passes? See comments on CL 386002 and - // go.dev/issue/52104. - laterFns []func() - // laterFors is used in case of 'type A B' to ensure that B is processed before A. - laterFors map[types.Type]int - - // ifaces holds a list of constructed Interfaces, which need to have - // Complete called after importing is done. - ifaces []*types.Interface -} - -// later adds a function to be invoked at the end of import reading. -func (pr *pkgReader) later(fn func()) { - pr.laterFns = append(pr.laterFns, fn) -} - -// See cmd/compile/internal/noder.derivedInfo. -type derivedInfo struct { - idx pkgbits.Index -} - -// See cmd/compile/internal/noder.typeInfo. -type typeInfo struct { - idx pkgbits.Index - derived bool -} - -func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { - if !debug { - defer func() { - if x := recover(); x != nil { - err = fmt.Errorf("internal error in importing %q (%v); please report an issue", path, x) - } - }() - } - - s := string(data) - input := pkgbits.NewPkgDecoder(path, s) - pkg = readUnifiedPackage(fset, nil, imports, input) - return -} - -// laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing. -func (pr *pkgReader) laterFor(t types.Type, fn func()) { - if pr.laterFors == nil { - pr.laterFors = make(map[types.Type]int) - } - pr.laterFors[t] = len(pr.laterFns) - pr.laterFns = append(pr.laterFns, fn) -} - -// readUnifiedPackage reads a package description from the given -// unified IR export data decoder. -func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package { - pr := pkgReader{ - PkgDecoder: input, - - fake: fakeFileSet{ - fset: fset, - files: make(map[string]*fileInfo), - }, - - ctxt: ctxt, - imports: imports, - - posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), - pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), - typs: make([]types.Type, input.NumElems(pkgbits.RelocType)), - } - defer pr.fake.setLines() - - r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) - pkg := r.pkg() - if r.Version().Has(pkgbits.HasInit) { - r.Bool() - } - - for i, n := 0, r.Len(); i < n; i++ { - // As if r.obj(), but avoiding the Scope.Lookup call, - // to avoid eager loading of imports. - r.Sync(pkgbits.SyncObject) - if r.Version().Has(pkgbits.DerivedFuncInstance) { - assert(!r.Bool()) - } - r.p.objIdx(r.Reloc(pkgbits.RelocObj)) - assert(r.Len() == 0) - } - - r.Sync(pkgbits.SyncEOF) - - for _, fn := range pr.laterFns { - fn() - } - - for _, iface := range pr.ifaces { - iface.Complete() - } - - // Imports() of pkg are all of the transitive packages that were loaded. - var imps []*types.Package - for _, imp := range pr.pkgs { - if imp != nil && imp != pkg { - imps = append(imps, imp) - } - } - sort.Sort(byPath(imps)) - pkg.SetImports(imps) - - pkg.MarkComplete() - return pkg -} - -// A reader holds the state for reading a single unified IR element -// within a package. -type reader struct { - pkgbits.Decoder - - p *pkgReader - - dict *readerDict -} - -// A readerDict holds the state for type parameters that parameterize -// the current unified IR element. -type readerDict struct { - rtbounds []typeInfo // contains constraint types for each parameter in rtparams - rtparams []*types.TypeParam // contains receiver type parameters for an element - - tbounds []typeInfo // contains constraint types for each parameter in tparams - tparams []*types.TypeParam // contains type parameters for an element - - // derived is a slice of types derived from tparams, which may be - // instantiated while reading the current element. - derived []derivedInfo - derivedTypes []types.Type // lazily instantiated from derived -} - -func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { - return &reader{ - Decoder: pr.NewDecoder(k, idx, marker), - p: pr, - } -} - -func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { - return &reader{ - Decoder: pr.TempDecoder(k, idx, marker), - p: pr, - } -} - -func (pr *pkgReader) retireReader(r *reader) { - pr.RetireDecoder(&r.Decoder) -} - -// @@@ Positions - -func (r *reader) pos() token.Pos { - r.Sync(pkgbits.SyncPos) - if !r.Bool() { - return token.NoPos - } - - // TODO(mdempsky): Delta encoding. - posBase := r.posBase() - line := r.Uint() - col := r.Uint() - return r.p.fake.pos(posBase, int(line), int(col)) -} - -func (r *reader) posBase() string { - return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)) -} - -func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string { - if b := pr.posBases[idx]; b != "" { - return b - } - - var filename string - { - r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase) - - // Within types2, position bases have a lot more details (e.g., - // keeping track of where //line directives appeared exactly). - // - // For go/types, we just track the file name. - - filename = r.String() - - if r.Bool() { // file base - // Was: "b = token.NewTrimmedFileBase(filename, true)" - } else { // line base - pos := r.pos() - line := r.Uint() - col := r.Uint() - - // Was: "b = token.NewLineBase(pos, filename, true, line, col)" - _, _, _ = pos, line, col - } - pr.retireReader(r) - } - b := filename - pr.posBases[idx] = b - return b -} - -// @@@ Packages - -func (r *reader) pkg() *types.Package { - r.Sync(pkgbits.SyncPkg) - return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg)) -} - -func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package { - // TODO(mdempsky): Consider using some non-nil pointer to indicate - // the universe scope, so we don't need to keep re-reading it. - if pkg := pr.pkgs[idx]; pkg != nil { - return pkg - } - - pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg() - pr.pkgs[idx] = pkg - return pkg -} - -func (r *reader) doPkg() *types.Package { - path := r.String() - switch path { - // cmd/compile emits path="main" for main packages because - // that's the linker symbol prefix it used; but we need - // the package's path as it would be reported by go list, - // hence "main" below. - // See test at go/packages.TestMainPackagePathInModeTypes. - case "", "main": - path = r.p.PkgPath() - case "builtin": - return nil // universe - case "unsafe": - return types.Unsafe - } - - if pkg := r.p.imports[path]; pkg != nil { - return pkg - } - - name := r.String() - - pkg := types.NewPackage(path, name) - r.p.imports[path] = pkg - - return pkg -} - -// @@@ Types - -func (r *reader) typ() types.Type { - return r.p.typIdx(r.typInfo(), r.dict) -} - -func (r *reader) typInfo() typeInfo { - r.Sync(pkgbits.SyncType) - if r.Bool() { - return typeInfo{idx: pkgbits.Index(r.Len()), derived: true} - } - return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false} -} - -func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type { - idx := info.idx - var where *types.Type - if info.derived { - where = &dict.derivedTypes[idx] - idx = dict.derived[idx].idx - } else { - where = &pr.typs[idx] - } - - if typ := *where; typ != nil { - return typ - } - - var typ types.Type - { - r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx) - r.dict = dict - - typ = r.doTyp() - assert(typ != nil) - pr.retireReader(r) - } - // See comment in pkgReader.typIdx explaining how this happens. - if prev := *where; prev != nil { - return prev - } - - *where = typ - return typ -} - -func (r *reader) doTyp() (res types.Type) { - switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag { - default: - errorf("unhandled type tag: %v", tag) - panic("unreachable") - - case pkgbits.TypeBasic: - return types.Typ[r.Len()] - - case pkgbits.TypeNamed: - obj, targs := r.obj() - name := obj.(*types.TypeName) - if len(targs) != 0 { - t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false) - return t - } - return name.Type() - - case pkgbits.TypeTypeParam: - n := r.Len() - if n < len(r.dict.rtbounds) { - return r.dict.rtparams[n] - } - return r.dict.tparams[n-len(r.dict.rtbounds)] - - case pkgbits.TypeArray: - len := int64(r.Uint64()) - return types.NewArray(r.typ(), len) - case pkgbits.TypeChan: - dir := types.ChanDir(r.Len()) - return types.NewChan(dir, r.typ()) - case pkgbits.TypeMap: - return types.NewMap(r.typ(), r.typ()) - case pkgbits.TypePointer: - return types.NewPointer(r.typ()) - case pkgbits.TypeSignature: - return r.signature(nil, nil, nil) - case pkgbits.TypeSlice: - return types.NewSlice(r.typ()) - case pkgbits.TypeStruct: - return r.structType() - case pkgbits.TypeInterface: - return r.interfaceType() - case pkgbits.TypeUnion: - return r.unionType() - } -} - -func (r *reader) structType() *types.Struct { - fields := make([]*types.Var, r.Len()) - var tags []string - for i := range fields { - pos := r.pos() - pkg, name := r.selector() - ftyp := r.typ() - tag := r.String() - embedded := r.Bool() - - fields[i] = types.NewField(pos, pkg, name, ftyp, embedded) - if tag != "" { - for len(tags) < i { - tags = append(tags, "") - } - tags = append(tags, tag) - } - } - return types.NewStruct(fields, tags) -} - -func (r *reader) unionType() *types.Union { - terms := make([]*types.Term, r.Len()) - for i := range terms { - terms[i] = types.NewTerm(r.Bool(), r.typ()) - } - return types.NewUnion(terms) -} - -func (r *reader) interfaceType() *types.Interface { - methods := make([]*types.Func, r.Len()) - embeddeds := make([]types.Type, r.Len()) - implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool() - - for i := range methods { - pos := r.pos() - pkg, name := r.selector() - mtyp := r.signature(nil, nil, nil) - methods[i] = types.NewFunc(pos, pkg, name, mtyp) - } - - for i := range embeddeds { - embeddeds[i] = r.typ() - } - - iface := types.NewInterfaceType(methods, embeddeds) - if implicit { - iface.MarkImplicit() - } - - // We need to call iface.Complete(), but if there are any embedded - // defined types, then we may not have set their underlying - // interface type yet. So we need to defer calling Complete until - // after we've called SetUnderlying everywhere. - // - // TODO(mdempsky): After CL 424876 lands, it should be safe to call - // iface.Complete() immediately. - r.p.ifaces = append(r.p.ifaces, iface) - - return iface -} - -func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature { - r.Sync(pkgbits.SyncSignature) - - params := r.params() - results := r.params() - variadic := r.Bool() - - return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic) -} - -func (r *reader) params() *types.Tuple { - r.Sync(pkgbits.SyncParams) - - params := make([]*types.Var, r.Len()) - for i := range params { - params[i] = r.param() - } - - return types.NewTuple(params...) -} - -func (r *reader) param() *types.Var { - r.Sync(pkgbits.SyncParam) - - pos := r.pos() - pkg, name := r.localIdent() - typ := r.typ() - - return types.NewParam(pos, pkg, name, typ) -} - -// @@@ Objects - -func (r *reader) obj() (types.Object, []types.Type) { - r.Sync(pkgbits.SyncObject) - - if r.Version().Has(pkgbits.DerivedFuncInstance) { - assert(!r.Bool()) - } - - pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj)) - obj := pkgScope(pkg).Lookup(name) - - targs := make([]types.Type, r.Len()) - for i := range targs { - targs[i] = r.typ() - } - - return obj, targs -} - -func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { - - var objPkg *types.Package - var objName string - var tag pkgbits.CodeObj - { - rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1) - - objPkg, objName = rname.qualifiedIdent() - assert(objName != "") - - tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj)) - pr.retireReader(rname) - } - - if tag == pkgbits.ObjStub { - assert(objPkg == nil || objPkg == types.Unsafe) - return objPkg, objName - } - - // Ignore local types promoted to global scope (#55110). - if _, suffix := splitVargenSuffix(objName); suffix != "" { - return objPkg, objName - } - - if objPkg.Scope().Lookup(objName) == nil { - dict := pr.objDictIdx(idx) - - r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) - r.dict = dict - - declare := func(obj types.Object) { - objPkg.Scope().Insert(obj) - } - - switch tag { - default: - panic("weird") - - case pkgbits.ObjAlias: - pos := r.pos() - var tparams []*types.TypeParam - if r.Version().Has(pkgbits.AliasTypeParamNames) { - tparams = r.typeParamNames(false) - } - typ := r.typ() - declare(aliases.New(pos, objPkg, objName, typ, tparams)) - - case pkgbits.ObjConst: - pos := r.pos() - typ := r.typ() - val := r.Value() - declare(types.NewConst(pos, objPkg, objName, typ, val)) - - case pkgbits.ObjFunc: - pos := r.pos() - var rtparams []*types.TypeParam - var recv *types.Var - if r.Version().Has(pkgbits.GenericMethods) && r.Bool() { - r.selector() - rtparams = r.typeParamNames(true) - recv = r.param() - } - tparams := r.typeParamNames(false) - sig := r.signature(recv, rtparams, tparams) - declare(types.NewFunc(pos, objPkg, objName, sig)) - - case pkgbits.ObjType: - pos := r.pos() - - obj := types.NewTypeName(pos, objPkg, objName, nil) - named := types.NewNamed(obj, nil, nil) - declare(obj) - - named.SetTypeParams(r.typeParamNames(false)) - - setUnderlying := func(underlying types.Type) { - // If the underlying type is an interface, we need to - // duplicate its methods so we can replace the receiver - // parameter's type (#49906). - if iface, ok := types.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 { - methods := make([]*types.Func, iface.NumExplicitMethods()) - for i := range methods { - fn := iface.ExplicitMethod(i) - sig := fn.Type().(*types.Signature) - - recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named) - typesinternal.SetVarKind(recv, typesinternal.RecvVar) - methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignatureType(recv, nil, nil, sig.Params(), sig.Results(), sig.Variadic())) - } - - embeds := make([]types.Type, iface.NumEmbeddeds()) - for i := range embeds { - embeds[i] = iface.EmbeddedType(i) - } - - newIface := types.NewInterfaceType(methods, embeds) - r.p.ifaces = append(r.p.ifaces, newIface) - underlying = newIface - } - - named.SetUnderlying(underlying) - } - - // Since go.dev/cl/455279, we can assume rhs.Underlying() will - // always be non-nil. However, to temporarily support users of - // older snapshot releases, we continue to fallback to the old - // behavior for now. - // - // TODO(mdempsky): Remove fallback code and simplify after - // allowing time for snapshot users to upgrade. - rhs := r.typ() - if underlying := rhs.Underlying(); underlying != nil { - setUnderlying(underlying) - } else { - pk := r.p - pk.laterFor(named, func() { - // First be sure that the rhs is initialized, if it needs to be initialized. - delete(pk.laterFors, named) // prevent cycles - if i, ok := pk.laterFors[rhs]; ok { - f := pk.laterFns[i] - pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op - f() // initialize RHS - } - setUnderlying(rhs.Underlying()) - }) - } - - for i, n := 0, r.Len(); i < n; i++ { - named.AddMethod(r.method()) - } - - case pkgbits.ObjVar: - pos := r.pos() - typ := r.typ() - v := types.NewVar(pos, objPkg, objName, typ) - typesinternal.SetVarKind(v, typesinternal.PackageVar) - declare(v) - } - } - - return objPkg, objName -} - -func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { - - var dict readerDict - - { - r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1) - if implicits := r.Len(); implicits != 0 { - errorf("unexpected object with %v implicit type parameter(s)", implicits) - } - - nreceivers := 0 - if r.Version().Has(pkgbits.GenericMethods) && r.Bool() { - nreceivers = r.Len() - } - nexplicits := r.Len() - - dict.rtbounds = make([]typeInfo, nreceivers) - for i := range dict.rtbounds { - dict.rtbounds[i] = r.typInfo() - } - - dict.tbounds = make([]typeInfo, nexplicits) - for i := range dict.tbounds { - dict.tbounds[i] = r.typInfo() - } - - dict.derived = make([]derivedInfo, r.Len()) - dict.derivedTypes = make([]types.Type, len(dict.derived)) - for i := range dict.derived { - dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.RelocType)} - if r.Version().Has(pkgbits.DerivedInfoNeeded) { - assert(!r.Bool()) - } - } - - pr.retireReader(r) - } - // function references follow, but reader doesn't need those - - return &dict -} - -func (r *reader) typeParamNames(isGenMeth bool) []*types.TypeParam { - r.Sync(pkgbits.SyncTypeParamNames) - - // Note: This code assumes there are no implicit type parameters. - // This is fine since it only reads exported declarations, which - // never have implicits. - - var in []typeInfo - var out *[]*types.TypeParam - if isGenMeth { - in = r.dict.rtbounds - out = &r.dict.rtparams - } else { - in = r.dict.tbounds - out = &r.dict.tparams - } - - if len(in) == 0 { - return nil - } - - // Careful: Type parameter lists may have cycles. To allow for this, - // we construct the type parameter list in two passes: first we - // create all the TypeNames and TypeParams, then we construct and - // set the bound type. - - // We have to save tparams outside of the closure, because typeParamNames - // can be called multiple times with the same dictionary instance. - tparams := make([]*types.TypeParam, len(in)) - *out = tparams - - for i := range in { - pos := r.pos() - pkg, name := r.localIdent() - - tname := types.NewTypeName(pos, pkg, name, nil) - tparams[i] = types.NewTypeParam(tname, nil) - } - - // The reader dictionary will continue mutating before we have time - // to call delayed functions; make a local copy of the constraints. - types := make([]types.Type, len(in)) - for i, info := range in { - types[i] = r.p.typIdx(info, r.dict) - } - - // This needs to happen later to make sure SetUnderlying has been called. - r.p.later(func() { - for i, typ := range types { - tparams[i].SetConstraint(typ) - } - }) - - return tparams -} - -func (r *reader) method() *types.Func { - r.Sync(pkgbits.SyncMethod) - pos := r.pos() - pkg, name := r.selector() - - rparams := r.typeParamNames(false) - sig := r.signature(r.param(), rparams, nil) - - _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go. - return types.NewFunc(pos, pkg, name, sig) -} - -func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) } -func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) } -func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) } - -func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) { - r.Sync(marker) - return r.pkg(), r.String() -} - -// pkgScope returns pkg.Scope(). -// If pkg is nil, it returns types.Universe instead. -// -// TODO(mdempsky): Remove after x/tools can depend on Go 1.19. -func pkgScope(pkg *types.Package) *types.Scope { - if pkg != nil { - return pkg.Scope() - } - return types.Universe -} - -// See cmd/compile/internal/types.SplitVargenSuffix. -func splitVargenSuffix(name string) (base, suffix string) { - i := len(name) - for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' { - i-- - } - const dot = "·" - if i >= len(dot) && name[i-len(dot):i] == dot { - i -= len(dot) - return name[:i], name[i:] - } - return name, "" -} diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go deleted file mode 100644 index 58721202..00000000 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go +++ /dev/null @@ -1,567 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package gocommand is a helper for calling the go command. -package gocommand - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "log" - "os" - "os/exec" - "path/filepath" - "regexp" - "runtime" - "strconv" - "strings" - "sync" - "time" - - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/event/keys" - "golang.org/x/tools/internal/event/label" -) - -// A Runner will run go command invocations and serialize -// them if it sees a concurrency error. -type Runner struct { - // once guards the runner initialization. - once sync.Once - - // inFlight tracks available workers. - inFlight chan struct{} - - // serialized guards the ability to run a go command serially, - // to avoid deadlocks when claiming workers. - serialized chan struct{} -} - -const maxInFlight = 10 - -func (runner *Runner) initialize() { - runner.once.Do(func() { - runner.inFlight = make(chan struct{}, maxInFlight) - runner.serialized = make(chan struct{}, 1) - }) -} - -// 1.13: go: updates to go.mod needed, but contents have changed -// 1.14: go: updating go.mod: existing contents have changed since last read -var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`) - -// event keys for go command invocations -var ( - verb = keys.NewString("verb", "go command verb") - directory = keys.NewString("directory", "") -) - -func invLabels(inv Invocation) []label.Label { - return []label.Label{verb.Of(inv.Verb), directory.Of(inv.WorkingDir)} -} - -// Run is a convenience wrapper around RunRaw. -// It returns only stdout and a "friendly" error. -func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) { - ctx, done := event.Start(ctx, "gocommand.Runner.Run", invLabels(inv)...) - defer done() - - stdout, _, friendly, _ := runner.RunRaw(ctx, inv) - return stdout, friendly -} - -// RunPiped runs the invocation serially, always waiting for any concurrent -// invocations to complete first. -func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) error { - ctx, done := event.Start(ctx, "gocommand.Runner.RunPiped", invLabels(inv)...) - defer done() - - _, err := runner.runPiped(ctx, inv, stdout, stderr) - return err -} - -// RunRaw runs the invocation, serializing requests only if they fight over -// go.mod changes. -// Postcondition: both error results have same nilness. -func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { - ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...) - defer done() - // Make sure the runner is always initialized. - runner.initialize() - - // First, try to run the go command concurrently. - stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv) - - // If we encounter a load concurrency error, we need to retry serially. - if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) { - event.Error(ctx, "Load concurrency error, will retry serially", err) - - // Run serially by calling runPiped. - stdout.Reset() - stderr.Reset() - friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr) - } - - return stdout, stderr, friendlyErr, err -} - -// Postcondition: both error results have same nilness. -func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { - // Wait for 1 worker to become available. - select { - case <-ctx.Done(): - return nil, nil, ctx.Err(), ctx.Err() - case runner.inFlight <- struct{}{}: - defer func() { <-runner.inFlight }() - } - - stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} - friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr) - return stdout, stderr, friendlyErr, err -} - -// Postcondition: both error results have same nilness. -func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) { - // Make sure the runner is always initialized. - runner.initialize() - - // Acquire the serialization lock. This avoids deadlocks between two - // runPiped commands. - select { - case <-ctx.Done(): - return ctx.Err(), ctx.Err() - case runner.serialized <- struct{}{}: - defer func() { <-runner.serialized }() - } - - // Wait for all in-progress go commands to return before proceeding, - // to avoid load concurrency errors. - for range maxInFlight { - select { - case <-ctx.Done(): - return ctx.Err(), ctx.Err() - case runner.inFlight <- struct{}{}: - // Make sure we always "return" any workers we took. - defer func() { <-runner.inFlight }() - } - } - - return inv.runWithFriendlyError(ctx, stdout, stderr) -} - -// An Invocation represents a call to the go command. -type Invocation struct { - Verb string - Args []string - BuildFlags []string - - // If ModFlag is set, the go command is invoked with -mod=ModFlag. - // TODO(rfindley): remove, in favor of Args. - ModFlag string - - // If ModFile is set, the go command is invoked with -modfile=ModFile. - // TODO(rfindley): remove, in favor of Args. - ModFile string - - // Overlay is the name of the JSON overlay file that describes - // unsaved editor buffers; see [WriteOverlays]. - // If set, the go command is invoked with -overlay=Overlay. - // TODO(rfindley): remove, in favor of Args. - Overlay string - - // If CleanEnv is set, the invocation will run only with the environment - // in Env, not starting with os.Environ. - CleanEnv bool - Env []string - WorkingDir string - Logf func(format string, args ...any) -} - -// Postcondition: both error results have same nilness. -func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) { - rawError = i.run(ctx, stdout, stderr) - if rawError != nil { - friendlyError = rawError - // Check for 'go' executable not being found. - if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound { - friendlyError = fmt.Errorf("go command required, not found: %v", ee) - } - if ctx.Err() != nil { - friendlyError = ctx.Err() - } - friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr) - } - return -} - -// logf logs if i.Logf is non-nil. -func (i *Invocation) logf(format string, args ...any) { - if i.Logf != nil { - i.Logf(format, args...) - } -} - -func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { - goArgs := []string{i.Verb} - - appendModFile := func() { - if i.ModFile != "" { - goArgs = append(goArgs, "-modfile="+i.ModFile) - } - } - appendModFlag := func() { - if i.ModFlag != "" { - goArgs = append(goArgs, "-mod="+i.ModFlag) - } - } - appendOverlayFlag := func() { - if i.Overlay != "" { - goArgs = append(goArgs, "-overlay="+i.Overlay) - } - } - - switch i.Verb { - case "env", "version": - goArgs = append(goArgs, i.Args...) - case "mod": - // mod needs the sub-verb before flags. - goArgs = append(goArgs, i.Args[0]) - appendModFile() - goArgs = append(goArgs, i.Args[1:]...) - case "get": - goArgs = append(goArgs, i.BuildFlags...) - appendModFile() - goArgs = append(goArgs, i.Args...) - - default: // notably list and build. - goArgs = append(goArgs, i.BuildFlags...) - appendModFile() - appendModFlag() - appendOverlayFlag() - goArgs = append(goArgs, i.Args...) - } - cmd := exec.Command("go", goArgs...) - cmd.Stdout = stdout - cmd.Stderr = stderr - - // https://go.dev/issue/59541: don't wait forever copying stderr - // after the command has exited. - // After CL 484741 we copy stdout manually, so we we'll stop reading that as - // soon as ctx is done. However, we also don't want to wait around forever - // for stderr. Give a much-longer-than-reasonable delay and then assume that - // something has wedged in the kernel or runtime. - cmd.WaitDelay = 30 * time.Second - - // The cwd gets resolved to the real path. On Darwin, where - // /tmp is a symlink, this breaks anything that expects the - // working directory to keep the original path, including the - // go command when dealing with modules. - // - // os.Getwd has a special feature where if the cwd and the PWD - // are the same node then it trusts the PWD, so by setting it - // in the env for the child process we fix up all the paths - // returned by the go command. - if !i.CleanEnv { - cmd.Env = os.Environ() - } - cmd.Env = append(cmd.Env, i.Env...) - if i.WorkingDir != "" { - cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir) - cmd.Dir = i.WorkingDir - } - - debugStr := cmdDebugStr(cmd) - i.logf("starting %v", debugStr) - start := time.Now() - defer func() { - i.logf("%s for %v", time.Since(start), debugStr) - }() - - return runCmdContext(ctx, cmd) -} - -// DebugHangingGoCommands may be set by tests to enable additional -// instrumentation (including panics) for debugging hanging Go commands. -// -// See golang/go#54461 for details. -var DebugHangingGoCommands = false - -// runCmdContext is like exec.CommandContext except it sends os.Interrupt -// before os.Kill. -func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) { - // If cmd.Stdout is not an *os.File, the exec package will create a pipe and - // copy it to the Writer in a goroutine until the process has finished and - // either the pipe reaches EOF or command's WaitDelay expires. - // - // However, the output from 'go list' can be quite large, and we don't want to - // keep reading (and allocating buffers) if we've already decided we don't - // care about the output. We don't want to wait for the process to finish, and - // we don't wait to wait for the WaitDelay to expire either. - // - // Instead, if cmd.Stdout requires a copying goroutine we explicitly replace - // it with a pipe (which is an *os.File), which we can close in order to stop - // copying output as soon as we realize we don't care about it. - var stdoutW *os.File - if cmd.Stdout != nil { - if _, ok := cmd.Stdout.(*os.File); !ok { - var stdoutR *os.File - stdoutR, stdoutW, err = os.Pipe() - if err != nil { - return err - } - prevStdout := cmd.Stdout - cmd.Stdout = stdoutW - - stdoutErr := make(chan error, 1) - go func() { - _, err := io.Copy(prevStdout, stdoutR) - if err != nil { - err = fmt.Errorf("copying stdout: %w", err) - } - stdoutErr <- err - }() - defer func() { - // We started a goroutine to copy a stdout pipe. - // Wait for it to finish, or terminate it if need be. - var err2 error - select { - case err2 = <-stdoutErr: - stdoutR.Close() - case <-ctx.Done(): - stdoutR.Close() - // Per https://pkg.go.dev/os#File.Close, the call to stdoutR.Close - // should cause the Read call in io.Copy to unblock and return - // immediately, but we still need to receive from stdoutErr to confirm - // that it has happened. - <-stdoutErr - err2 = ctx.Err() - } - if err == nil { - err = err2 - } - }() - - // Per https://pkg.go.dev/os/exec#Cmd, “If Stdout and Stderr are the - // same writer, and have a type that can be compared with ==, at most - // one goroutine at a time will call Write.” - // - // Since we're starting a goroutine that writes to cmd.Stdout, we must - // also update cmd.Stderr so that it still holds. - func() { - defer func() { recover() }() - if cmd.Stderr == prevStdout { - cmd.Stderr = cmd.Stdout - } - }() - } - } - - startTime := time.Now() - err = cmd.Start() - if stdoutW != nil { - // The child process has inherited the pipe file, - // so close the copy held in this process. - stdoutW.Close() - stdoutW = nil - } - if err != nil { - return err - } - - resChan := make(chan error, 1) - go func() { - resChan <- cmd.Wait() - }() - - // If we're interested in debugging hanging Go commands, stop waiting after a - // minute and panic with interesting information. - debug := DebugHangingGoCommands - if debug { - timer := time.NewTimer(1 * time.Minute) - defer timer.Stop() - select { - case err := <-resChan: - return err - case <-timer.C: - // HandleHangingGoCommand terminates this process. - // Pass off resChan in case we can collect the command error. - handleHangingGoCommand(startTime, cmd, resChan) - case <-ctx.Done(): - } - } else { - select { - case err := <-resChan: - return err - case <-ctx.Done(): - } - } - - // Cancelled. Interrupt and see if it ends voluntarily. - if err := cmd.Process.Signal(os.Interrupt); err == nil { - // (We used to wait only 1s but this proved - // fragile on loaded builder machines.) - timer := time.NewTimer(5 * time.Second) - defer timer.Stop() - select { - case err := <-resChan: - return err - case <-timer.C: - } - } - - // Didn't shut down in response to interrupt. Kill it hard. - if err := cmd.Process.Kill(); err != nil && !errors.Is(err, os.ErrProcessDone) && debug { - log.Printf("error killing the Go command: %v", err) - } - - return <-resChan -} - -// handleHangingGoCommand outputs debugging information to help diagnose the -// cause of a hanging Go command, and then exits with log.Fatalf. -func handleHangingGoCommand(start time.Time, cmd *exec.Cmd, resChan chan error) { - switch runtime.GOOS { - case "linux", "darwin", "freebsd", "netbsd", "openbsd": - fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND - - The gopls test runner has detected a hanging go command. In order to debug - this, the output of ps and lsof/fstat is printed below. - - See golang/go#54461 for more details.`) - - fmt.Fprintln(os.Stderr, "\nps axo ppid,pid,command:") - fmt.Fprintln(os.Stderr, "-------------------------") - psCmd := exec.Command("ps", "axo", "ppid,pid,command") - psCmd.Stdout = os.Stderr - psCmd.Stderr = os.Stderr - if err := psCmd.Run(); err != nil { - log.Printf("Handling hanging Go command: running ps: %v", err) - } - - listFiles := "lsof" - if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" { - listFiles = "fstat" - } - - fmt.Fprintln(os.Stderr, "\n"+listFiles+":") - fmt.Fprintln(os.Stderr, "-----") - listFilesCmd := exec.Command(listFiles) - listFilesCmd.Stdout = os.Stderr - listFilesCmd.Stderr = os.Stderr - if err := listFilesCmd.Run(); err != nil { - log.Printf("Handling hanging Go command: running %s: %v", listFiles, err) - } - // Try to extract information about the slow go process by issuing a SIGQUIT. - if err := cmd.Process.Signal(sigStuckProcess); err == nil { - select { - case err := <-resChan: - stderr := "not a bytes.Buffer" - if buf, _ := cmd.Stderr.(*bytes.Buffer); buf != nil { - stderr = buf.String() - } - log.Printf("Quit hanging go command:\n\terr:%v\n\tstderr:\n%v\n\n", err, stderr) - case <-time.After(5 * time.Second): - } - } else { - log.Printf("Sending signal %d to hanging go command: %v", sigStuckProcess, err) - } - } - log.Fatalf("detected hanging go command (golang/go#54461); waited %s\n\tcommand:%s\n\tpid:%d", time.Since(start), cmd, cmd.Process.Pid) -} - -func cmdDebugStr(cmd *exec.Cmd) string { - env := make(map[string]string) - for _, kv := range cmd.Env { - split := strings.SplitN(kv, "=", 2) - if len(split) == 2 { - k, v := split[0], split[1] - env[k] = v - } - } - - var args []string - for _, arg := range cmd.Args { - quoted := strconv.Quote(arg) - if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") { - args = append(args, quoted) - } else { - args = append(args, arg) - } - } - return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " ")) -} - -// WriteOverlays writes each value in the overlay (see the Overlay -// field of go/packages.Config) to a temporary file and returns the name -// of a JSON file describing the mapping that is suitable for the "go -// list -overlay" flag. -// -// On success, the caller must call the cleanup function exactly once -// when the files are no longer needed. -func WriteOverlays(overlay map[string][]byte) (filename string, cleanup func(), err error) { - // Do nothing if there are no overlays in the config. - if len(overlay) == 0 { - return "", func() {}, nil - } - - dir, err := os.MkdirTemp("", "gocommand-*") - if err != nil { - return "", nil, err - } - - // The caller must clean up this directory, - // unless this function returns an error. - // (The cleanup operand of each return - // statement below is ignored.) - defer func() { - cleanup = func() { - os.RemoveAll(dir) - } - if err != nil { - cleanup() - cleanup = nil - } - }() - - // Write each map entry to a temporary file. - overlays := make(map[string]string) - for k, v := range overlay { - // Use a unique basename for each file (001-foo.go), - // to avoid creating nested directories. - base := fmt.Sprintf("%d-%s", 1+len(overlays), filepath.Base(k)) - filename := filepath.Join(dir, base) - err := os.WriteFile(filename, v, 0666) - if err != nil { - return "", nil, err - } - overlays[k] = filename - } - - // Write the JSON overlay file that maps logical file names to temp files. - // - // OverlayJSON is the format overlay files are expected to be in. - // The Replace map maps from overlaid paths to replacement paths: - // the Go command will forward all reads trying to open - // each overlaid path to its replacement path, or consider the overlaid - // path not to exist if the replacement path is empty. - // - // From golang/go#39958. - type OverlayJSON struct { - Replace map[string]string `json:"replace,omitempty"` - } - b, err := json.Marshal(OverlayJSON{Replace: overlays}) - if err != nil { - return "", nil, err - } - filename = filepath.Join(dir, "overlay.json") - if err := os.WriteFile(filename, b, 0666); err != nil { - return "", nil, err - } - - return filename, nil, nil -} diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke_notunix.go b/vendor/golang.org/x/tools/internal/gocommand/invoke_notunix.go deleted file mode 100644 index 469c648e..00000000 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke_notunix.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2025 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 !unix - -package gocommand - -import "os" - -// sigStuckProcess is the signal to send to kill a hanging subprocess. -// On Unix we send SIGQUIT, but on non-Unix we only have os.Kill. -var sigStuckProcess = os.Kill diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke_unix.go b/vendor/golang.org/x/tools/internal/gocommand/invoke_unix.go deleted file mode 100644 index 169d37c8..00000000 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke_unix.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2025 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 unix - -package gocommand - -import "syscall" - -// Sigstuckprocess is the signal to send to kill a hanging subprocess. -// Send SIGQUIT to get a stack trace. -var sigStuckProcess = syscall.SIGQUIT diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go deleted file mode 100644 index e38d1fb4..00000000 --- a/vendor/golang.org/x/tools/internal/gocommand/vendor.go +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gocommand - -import ( - "bytes" - "context" - "fmt" - "os" - "path/filepath" - "regexp" - "strings" - "time" - - "golang.org/x/mod/semver" -) - -// ModuleJSON holds information about a module. -type ModuleJSON struct { - Path string // module path - Version string // module version - Versions []string // available module versions (with -versions) - Replace *ModuleJSON // replaced by this module - Time *time.Time // time version was created - Update *ModuleJSON // available update, if any (with -u) - Main bool // is this the main module? - Indirect bool // is this module only an indirect dependency of main module? - Dir string // directory holding files for this module, if any - GoMod string // path to go.mod file used when loading this module, if any - GoVersion string // go version used in module -} - -var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`) - -// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands -// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, -// of which only Verb and Args are modified to run the appropriate Go command. -// Inspired by setDefaultBuildMod in modload/init.go -func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, *ModuleJSON, error) { - mainMod, go114, err := getMainModuleAnd114(ctx, inv, r) - if err != nil { - return false, nil, err - } - - // We check the GOFLAGS to see if there is anything overridden or not. - inv.Verb = "env" - inv.Args = []string{"GOFLAGS"} - stdout, err := r.Run(ctx, inv) - if err != nil { - return false, nil, err - } - goflags := string(bytes.TrimSpace(stdout.Bytes())) - matches := modFlagRegexp.FindStringSubmatch(goflags) - var modFlag string - if len(matches) != 0 { - modFlag = matches[1] - } - // Don't override an explicit '-mod=' argument. - if modFlag == "vendor" { - return true, mainMod, nil - } else if modFlag != "" { - return false, nil, nil - } - if mainMod == nil || !go114 { - return false, nil, nil - } - // Check 1.14's automatic vendor mode. - if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() { - if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 { - // The Go version is at least 1.14, and a vendor directory exists. - // Set -mod=vendor by default. - return true, mainMod, nil - } - } - return false, nil, nil -} - -// getMainModuleAnd114 gets one of the main modules' information and whether the -// go command in use is 1.14+. This is the information needed to figure out -// if vendoring should be enabled. -func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { - const format = `{{.Path}} -{{.Dir}} -{{.GoMod}} -{{.GoVersion}} -{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}} -` - inv.Verb = "list" - inv.Args = []string{"-m", "-f", format} - stdout, err := r.Run(ctx, inv) - if err != nil { - return nil, false, err - } - - lines := strings.Split(stdout.String(), "\n") - if len(lines) < 5 { - return nil, false, fmt.Errorf("unexpected stdout: %q", stdout.String()) - } - mod := &ModuleJSON{ - Path: lines[0], - Dir: lines[1], - GoMod: lines[2], - GoVersion: lines[3], - Main: true, - } - return mod, lines[4] == "go1.14", nil -} - -// WorkspaceVendorEnabled reports whether workspace vendoring is enabled. It takes a *Runner to execute Go commands -// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, -// of which only Verb and Args are modified to run the appropriate Go command. -// Inspired by setDefaultBuildMod in modload/init.go -func WorkspaceVendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, []*ModuleJSON, error) { - inv.Verb = "env" - inv.Args = []string{"GOWORK"} - stdout, err := r.Run(ctx, inv) - if err != nil { - return false, nil, err - } - goWork := string(bytes.TrimSpace(stdout.Bytes())) - if fi, err := os.Stat(filepath.Join(filepath.Dir(goWork), "vendor")); err == nil && fi.IsDir() { - mainMods, err := getWorkspaceMainModules(ctx, inv, r) - if err != nil { - return false, nil, err - } - return true, mainMods, nil - } - return false, nil, nil -} - -// getWorkspaceMainModules gets the main modules' information. -// This is the information needed to figure out if vendoring should be enabled. -func getWorkspaceMainModules(ctx context.Context, inv Invocation, r *Runner) ([]*ModuleJSON, error) { - const format = `{{.Path}} -{{.Dir}} -{{.GoMod}} -{{.GoVersion}} -` - inv.Verb = "list" - inv.Args = []string{"-m", "-f", format} - stdout, err := r.Run(ctx, inv) - if err != nil { - return nil, err - } - - lines := strings.Split(strings.TrimSuffix(stdout.String(), "\n"), "\n") - if len(lines) < 4 { - return nil, fmt.Errorf("unexpected stdout: %q", stdout.String()) - } - mods := make([]*ModuleJSON, 0, len(lines)/4) - for i := 0; i < len(lines); i += 4 { - mods = append(mods, &ModuleJSON{ - Path: lines[i], - Dir: lines[i+1], - GoMod: lines[i+2], - GoVersion: lines[i+3], - Main: true, - }) - } - return mods, nil -} diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go deleted file mode 100644 index cce290c4..00000000 --- a/vendor/golang.org/x/tools/internal/gocommand/version.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gocommand - -import ( - "context" - "fmt" - "regexp" - "strings" -) - -// GoVersion reports the minor version number of the highest release -// tag built into the go command on the PATH. -// -// Note that this may be higher than the version of the go tool used -// to build this application, and thus the versions of the standard -// go/{scanner,parser,ast,types} packages that are linked into it. -// In that case, callers should either downgrade to the version of -// go used to build the application, or report an error that the -// application is too old to use the go command on the PATH. -func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) { - inv.Verb = "list" - inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`} - inv.BuildFlags = nil // This is not a build command. - inv.ModFlag = "" - inv.ModFile = "" - // Set GO111MODULE=off so that we are immune to errors in go.{work,mod}. - // Unfortunately, this breaks the Go 1.21+ toolchain directive and - // may affect the set of ReleaseTags; see #68495. - inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off") - - stdoutBytes, err := r.Run(ctx, inv) - if err != nil { - return 0, err - } - stdout := stdoutBytes.String() - if len(stdout) < 3 { - return 0, fmt.Errorf("bad ReleaseTags output: %q", stdout) - } - // Split up "[go1.1 go1.15]" and return highest go1.X value. - tags := strings.Fields(stdout[1 : len(stdout)-2]) - for i := len(tags) - 1; i >= 0; i-- { - var version int - if _, err := fmt.Sscanf(tags[i], "go1.%d", &version); err != nil { - continue - } - return version, nil - } - return 0, fmt.Errorf("no parseable ReleaseTags in %v", tags) -} - -// GoVersionOutput returns the complete output of the go version command. -func GoVersionOutput(ctx context.Context, inv Invocation, r *Runner) (string, error) { - inv.Verb = "version" - goVersion, err := r.Run(ctx, inv) - if err != nil { - return "", err - } - return goVersion.String(), nil -} - -// ParseGoVersionOutput extracts the Go version string -// from the output of the "go version" command. -// Given an unrecognized form, it returns an empty string. -func ParseGoVersionOutput(data string) string { - re := regexp.MustCompile(`^go version (go\S+|devel \S+)`) - m := re.FindStringSubmatch(data) - if len(m) != 2 { - return "" // unrecognized version - } - return m[1] -} diff --git a/vendor/golang.org/x/tools/internal/gopathwalk/walk.go b/vendor/golang.org/x/tools/internal/gopathwalk/walk.go deleted file mode 100644 index 5252144d..00000000 --- a/vendor/golang.org/x/tools/internal/gopathwalk/walk.go +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright 2018 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 gopathwalk is like filepath.Walk but specialized for finding Go -// packages, particularly in $GOPATH and $GOROOT. -package gopathwalk - -import ( - "bufio" - "bytes" - "io" - "io/fs" - "os" - "path/filepath" - "runtime" - "slices" - "strings" - "sync" - "time" -) - -// Options controls the behavior of a Walk call. -type Options struct { - // If Logf is non-nil, debug logging is enabled through this function. - Logf func(format string, args ...any) - - // Search module caches. Also disables legacy goimports ignore rules. - ModulesEnabled bool - - // Maximum number of concurrent calls to user-provided callbacks, - // or 0 for GOMAXPROCS. - Concurrency int -} - -// RootType indicates the type of a Root. -type RootType int - -const ( - RootUnknown RootType = iota - RootGOROOT - RootGOPATH - RootCurrentModule - RootModuleCache - RootOther -) - -// A Root is a starting point for a Walk. -type Root struct { - Path string - Type RootType -} - -// Walk concurrently walks Go source directories ($GOROOT, $GOPATH, etc) to find packages. -// -// For each package found, add will be called with the absolute -// paths of the containing source directory and the package directory. -// -// Unlike filepath.WalkDir, Walk follows symbolic links -// (while guarding against cycles). -func Walk(roots []Root, add func(root Root, dir string), opts Options) { - WalkSkip(roots, add, func(Root, string) bool { return false }, opts) -} - -// WalkSkip concurrently walks Go source directories ($GOROOT, $GOPATH, etc) to -// find packages. -// -// For each package found, add will be called with the absolute -// paths of the containing source directory and the package directory. -// For each directory that will be scanned, skip will be called -// with the absolute paths of the containing source directory and the directory. -// If skip returns false on a directory it will be processed. -// -// Unlike filepath.WalkDir, WalkSkip follows symbolic links -// (while guarding against cycles). -func WalkSkip(roots []Root, add func(root Root, dir string), skip func(root Root, dir string) bool, opts Options) { - for _, root := range roots { - walkDir(root, add, skip, opts) - } -} - -// walkDir creates a walker and starts fastwalk with this walker. -func walkDir(root Root, add func(Root, string), skip func(root Root, dir string) bool, opts Options) { - if opts.Logf == nil { - opts.Logf = func(format string, args ...any) {} - } - if _, err := os.Stat(root.Path); os.IsNotExist(err) { - opts.Logf("skipping nonexistent directory: %v", root.Path) - return - } - start := time.Now() - opts.Logf("scanning %s", root.Path) - - concurrency := opts.Concurrency - if concurrency == 0 { - // The walk be either CPU-bound or I/O-bound, depending on what the - // caller-supplied add function does and the details of the user's platform - // and machine. Rather than trying to fine-tune the concurrency level for a - // specific environment, we default to GOMAXPROCS: it is likely to be a good - // choice for a CPU-bound add function, and if it is instead I/O-bound, then - // dealing with I/O saturation is arguably the job of the kernel and/or - // runtime. (Oversaturating I/O seems unlikely to harm performance as badly - // as failing to saturate would.) - concurrency = runtime.GOMAXPROCS(0) - } - w := &walker{ - root: root, - add: add, - skip: skip, - opts: opts, - sem: make(chan struct{}, concurrency), - } - w.init() - - w.sem <- struct{}{} - path := root.Path - if path == "" { - path = "." - } - if fi, err := os.Lstat(path); err == nil { - w.walk(path, nil, fs.FileInfoToDirEntry(fi)) - } else { - w.opts.Logf("scanning directory %v: %v", root.Path, err) - } - <-w.sem - w.walking.Wait() - - opts.Logf("scanned %s in %v", root.Path, time.Since(start)) -} - -// walker is the callback for fastwalk.Walk. -type walker struct { - root Root // The source directory to scan. - add func(Root, string) // The callback that will be invoked for every possible Go package dir. - skip func(Root, string) bool // The callback that will be invoked for every dir. dir is skipped if it returns true. - opts Options // Options passed to Walk by the user. - - walking sync.WaitGroup - sem chan struct{} // Channel of semaphore tokens; send to acquire, receive to release. - ignoredDirs []string - - added sync.Map // map[string]bool -} - -// A symlinkList is a linked list of os.FileInfos for parent directories -// reached via symlinks. -type symlinkList struct { - info os.FileInfo - prev *symlinkList -} - -// init initializes the walker based on its Options -func (w *walker) init() { - var ignoredPaths []string - if w.root.Type == RootModuleCache { - ignoredPaths = []string{"cache"} - } - if !w.opts.ModulesEnabled && w.root.Type == RootGOPATH { - ignoredPaths = w.getIgnoredDirs(w.root.Path) - ignoredPaths = append(ignoredPaths, "v", "mod") - } - - for _, p := range ignoredPaths { - full := filepath.Join(w.root.Path, p) - w.ignoredDirs = append(w.ignoredDirs, full) - w.opts.Logf("Directory added to ignore list: %s", full) - } -} - -// getIgnoredDirs reads an optional config file at /.goimportsignore -// of relative directories to ignore when scanning for go files. -// The provided path is one of the $GOPATH entries with "src" appended. -func (w *walker) getIgnoredDirs(path string) []string { - file := filepath.Join(path, ".goimportsignore") - slurp, err := os.ReadFile(file) - if err != nil { - w.opts.Logf("%v", err) - } else { - w.opts.Logf("Read %s", file) - } - if err != nil { - return nil - } - - var ignoredDirs []string - bs := bufio.NewScanner(bytes.NewReader(slurp)) - for bs.Scan() { - line := strings.TrimSpace(bs.Text()) - if line == "" || strings.HasPrefix(line, "#") { - continue - } - ignoredDirs = append(ignoredDirs, line) - } - return ignoredDirs -} - -// shouldSkipDir reports whether the file should be skipped or not. -func (w *walker) shouldSkipDir(dir string) bool { - if slices.Contains(w.ignoredDirs, dir) { - return true - } - if w.skip != nil { - // Check with the user specified callback. - return w.skip(w.root, dir) - } - return false -} - -// walk walks through the given path. -// -// Errors are logged if w.opts.Logf is non-nil, but otherwise ignored. -func (w *walker) walk(path string, pathSymlinks *symlinkList, d fs.DirEntry) { - if d.Type()&os.ModeSymlink != 0 { - // Walk the symlink's target rather than the symlink itself. - // - // (Note that os.Stat, unlike the lower-lever os.Readlink, - // follows arbitrarily many layers of symlinks, so it will eventually - // reach either a non-symlink or a nonexistent target.) - // - // TODO(bcmills): 'go list all' itself ignores symlinks within GOROOT/src - // and GOPATH/src. Do we really need to traverse them here? If so, why? - - fi, err := os.Stat(path) - if err != nil { - w.opts.Logf("%v", err) - return - } - - // Avoid walking symlink cycles: if we have already followed a symlink to - // this directory as a parent of itself, don't follow it again. - // - // This doesn't catch the first time through a cycle, but it also minimizes - // the number of extra stat calls we make if we *don't* encounter a cycle. - // Since we don't actually expect to encounter symlink cycles in practice, - // this seems like the right tradeoff. - for parent := pathSymlinks; parent != nil; parent = parent.prev { - if os.SameFile(fi, parent.info) { - return - } - } - - pathSymlinks = &symlinkList{ - info: fi, - prev: pathSymlinks, - } - d = fs.FileInfoToDirEntry(fi) - } - - if d.Type().IsRegular() { - if !strings.HasSuffix(path, ".go") { - return - } - - dir := filepath.Dir(path) - if dir == w.root.Path && (w.root.Type == RootGOROOT || w.root.Type == RootGOPATH) { - // Doesn't make sense to have regular files - // directly in your $GOPATH/src or $GOROOT/src. - // - // TODO(bcmills): there are many levels of directory within - // RootModuleCache where this also wouldn't make sense, - // Can we generalize this to any directory without a corresponding - // import path? - return - } - - if _, dup := w.added.LoadOrStore(dir, true); !dup { - w.add(w.root, dir) - } - } - - if !d.IsDir() { - return - } - - base := filepath.Base(path) - if base == "" || base[0] == '.' || base[0] == '_' || - base == "testdata" || - (w.root.Type == RootGOROOT && w.opts.ModulesEnabled && base == "vendor") || - (!w.opts.ModulesEnabled && base == "node_modules") || - w.shouldSkipDir(path) { - return - } - - // Read the directory and walk its entries. - - f, err := os.Open(path) - if err != nil { - w.opts.Logf("%v", err) - return - } - defer f.Close() - - for { - // We impose an arbitrary limit on the number of ReadDir results per - // directory to limit the amount of memory consumed for stale or upcoming - // directory entries. The limit trades off CPU (number of syscalls to read - // the whole directory) against RAM (reachable directory entries other than - // the one currently being processed). - // - // Since we process the directories recursively, we will end up maintaining - // a slice of entries for each level of the directory tree. - // (Compare https://go.dev/issue/36197.) - ents, err := f.ReadDir(1024) - if err != nil { - if err != io.EOF { - w.opts.Logf("%v", err) - } - break - } - - for _, d := range ents { - nextPath := filepath.Join(path, d.Name()) - if d.IsDir() { - select { - case w.sem <- struct{}{}: - // Got a new semaphore token, so we can traverse the directory concurrently. - d := d - w.walking.Add(1) - go func() { - defer func() { - <-w.sem - w.walking.Done() - }() - w.walk(nextPath, pathSymlinks, d) - }() - continue - - default: - // No tokens available, so traverse serially. - } - } - - w.walk(nextPath, pathSymlinks, d) - } - } -} diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go deleted file mode 100644 index 1b4dc0cb..00000000 --- a/vendor/golang.org/x/tools/internal/imports/fix.go +++ /dev/null @@ -1,1896 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package imports - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "go/ast" - "go/build" - "go/parser" - "go/token" - "go/types" - "io/fs" - "io/ioutil" - "maps" - "os" - "path" - "path/filepath" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "unicode" - "unicode/utf8" - - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/gopathwalk" - "golang.org/x/tools/internal/stdlib" -) - -// importToGroup is a list of functions which map from an import path to -// a group number. -var importToGroup = []func(localPrefix, importPath string) (num int, ok bool){ - func(localPrefix, importPath string) (num int, ok bool) { - if localPrefix == "" { - return - } - for p := range strings.SplitSeq(localPrefix, ",") { - if strings.HasPrefix(importPath, p) || strings.TrimSuffix(p, "/") == importPath { - return 3, true - } - } - return - }, - func(_, importPath string) (num int, ok bool) { - if strings.HasPrefix(importPath, "appengine") { - return 2, true - } - return - }, - func(_, importPath string) (num int, ok bool) { - firstComponent := strings.Split(importPath, "/")[0] - if strings.Contains(firstComponent, ".") { - return 1, true - } - return - }, -} - -func importGroup(localPrefix, importPath string) int { - for _, fn := range importToGroup { - if n, ok := fn(localPrefix, importPath); ok { - return n - } - } - return 0 -} - -type ImportFixType int - -const ( - AddImport ImportFixType = iota - DeleteImport - SetImportName -) - -type ImportFix struct { - // StmtInfo represents the import statement this fix will add, remove, or change. - StmtInfo ImportInfo - // IdentName is the identifier that this fix will add or remove. - IdentName string - // FixType is the type of fix this is (AddImport, DeleteImport, SetImportName). - FixType ImportFixType - Relevance float64 // see pkg -} - -// parseOtherFiles parses all the Go files in srcDir except filename, including -// test files if filename looks like a test. -// -// It returns an error only if ctx is cancelled. Files with parse errors are -// ignored. -func parseOtherFiles(ctx context.Context, fset *token.FileSet, srcDir, filename string) ([]*ast.File, error) { - // This could use go/packages but it doesn't buy much, and it fails - // with https://golang.org/issue/26296 in LoadFiles mode in some cases. - considerTests := strings.HasSuffix(filename, "_test.go") - - fileBase := filepath.Base(filename) - packageFileInfos, err := os.ReadDir(srcDir) - if err != nil { - return nil, ctx.Err() - } - - var files []*ast.File - for _, fi := range packageFileInfos { - if ctx.Err() != nil { - return nil, ctx.Err() - } - if fi.Name() == fileBase || !strings.HasSuffix(fi.Name(), ".go") { - continue - } - if !considerTests && strings.HasSuffix(fi.Name(), "_test.go") { - continue - } - - f, err := parser.ParseFile(fset, filepath.Join(srcDir, fi.Name()), nil, parser.SkipObjectResolution) - if err != nil { - continue - } - - files = append(files, f) - } - - return files, ctx.Err() -} - -// addGlobals puts the names of package vars into the provided map. -func addGlobals(f *ast.File, globals map[string]bool) { - for _, decl := range f.Decls { - genDecl, ok := decl.(*ast.GenDecl) - if !ok { - continue - } - - for _, spec := range genDecl.Specs { - valueSpec, ok := spec.(*ast.ValueSpec) - if !ok { - continue - } - globals[valueSpec.Names[0].Name] = true - } - } -} - -// collectReferences builds a map of selector expressions, from -// left hand side (X) to a set of right hand sides (Sel). -func collectReferences(f *ast.File) References { - refs := References{} - - var visitor visitFn - visitor = func(node ast.Node) ast.Visitor { - if node == nil { - return visitor - } - switch v := node.(type) { - case *ast.SelectorExpr: - xident, ok := v.X.(*ast.Ident) - if !ok { - break - } - if xident.Obj != nil { - // If the parser can resolve it, it's not a package ref. - break - } - if !ast.IsExported(v.Sel.Name) { - // Whatever this is, it's not exported from a package. - break - } - pkgName := xident.Name - r := refs[pkgName] - if r == nil { - r = make(map[string]bool) - refs[pkgName] = r - } - r[v.Sel.Name] = true - } - return visitor - } - ast.Walk(visitor, f) - return refs -} - -// collectImports returns all the imports in f. -// Unnamed imports (., _) and "C" are ignored. -func collectImports(f *ast.File) []*ImportInfo { - var imports []*ImportInfo - for _, imp := range f.Imports { - var name string - if imp.Name != nil { - name = imp.Name.Name - } - if imp.Path.Value == `"C"` || name == "_" || name == "." { - continue - } - path := strings.Trim(imp.Path.Value, `"`) - imports = append(imports, &ImportInfo{ - Name: name, - ImportPath: path, - }) - } - return imports -} - -// findMissingImport searches pass's candidates for an import that provides -// pkg, containing all of syms. -func (p *pass) findMissingImport(pkg string, syms map[string]bool) *ImportInfo { - for _, candidate := range p.candidates { - pkgInfo, ok := p.knownPackages[candidate.ImportPath] - if !ok { - continue - } - if p.importIdentifier(candidate) != pkg { - continue - } - - allFound := true - for right := range syms { - if !pkgInfo.Exports[right] { - allFound = false - break - } - } - - if allFound { - return candidate - } - } - return nil -} - -// A pass contains all the inputs and state necessary to fix a file's imports. -// It can be modified in some ways during use; see comments below. -type pass struct { - // Inputs. These must be set before a call to load, and not modified after. - fset *token.FileSet // fset used to parse f and its siblings. - f *ast.File // the file being fixed. - srcDir string // the directory containing f. - logf func(string, ...any) - source Source // the environment to use for go commands, etc. - loadRealPackageNames bool // if true, load package names from disk rather than guessing them. - otherFiles []*ast.File // sibling files. - goroot string - - // Intermediate state, generated by load. - existingImports map[string][]*ImportInfo - allRefs References - missingRefs References - - // Inputs to fix. These can be augmented between successive fix calls. - lastTry bool // indicates that this is the last call and fix should clean up as best it can. - candidates []*ImportInfo // candidate imports in priority order. - knownPackages map[string]*PackageInfo // information about all known packages. -} - -// loadPackageNames saves the package names for everything referenced by imports. -func (p *pass) loadPackageNames(ctx context.Context, imports []*ImportInfo) error { - if p.logf != nil { - p.logf("loading package names for %v packages", len(imports)) - defer func() { - p.logf("done loading package names for %v packages", len(imports)) - }() - } - var unknown []string - for _, imp := range imports { - if _, ok := p.knownPackages[imp.ImportPath]; ok { - continue - } - unknown = append(unknown, imp.ImportPath) - } - - names, err := p.source.LoadPackageNames(ctx, p.srcDir, unknown) - if err != nil { - return err - } - - // TODO(rfindley): revisit this. Why do we need to store known packages with - // no exports? The inconsistent data is confusing. - for path, name := range names { - p.knownPackages[path] = &PackageInfo{ - Name: name, - Exports: map[string]bool{}, - } - } - return nil -} - -// WithoutVersion removes a trailing major version, if there is one. -func WithoutVersion(nm string) string { - if v := path.Base(nm); len(v) > 0 && v[0] == 'v' { - if _, err := strconv.Atoi(v[1:]); err == nil { - // this is, for instance, called with rand/v2 and returns rand - if len(v) < len(nm) { - xnm := nm[:len(nm)-len(v)-1] - return path.Base(xnm) - } - } - } - return nm -} - -// importIdentifier returns the identifier that imp will introduce. It will -// guess if the package name has not been loaded, e.g. because the source -// is not available. -func (p *pass) importIdentifier(imp *ImportInfo) string { - if imp.Name != "" { - return imp.Name - } - known := p.knownPackages[imp.ImportPath] - if known != nil && known.Name != "" { - return WithoutVersion(known.Name) - } - return ImportPathToAssumedName(imp.ImportPath) -} - -// load reads in everything necessary to run a pass, and reports whether the -// file already has all the imports it needs. It fills in p.missingRefs with the -// file's missing symbols, if any, or removes unused imports if not. -func (p *pass) load(ctx context.Context) ([]*ImportFix, bool) { - p.knownPackages = map[string]*PackageInfo{} - p.missingRefs = References{} - p.existingImports = map[string][]*ImportInfo{} - - // Load basic information about the file in question. - p.allRefs = collectReferences(p.f) - - // Load stuff from other files in the same package: - // global variables so we know they don't need resolving, and imports - // that we might want to mimic. - globals := map[string]bool{} - for _, otherFile := range p.otherFiles { - // Don't load globals from files that are in the same directory - // but a different package. Using them to suggest imports is OK. - if p.f.Name.Name == otherFile.Name.Name { - addGlobals(otherFile, globals) - } - p.candidates = append(p.candidates, collectImports(otherFile)...) - } - - // Resolve all the import paths we've seen to package names, and store - // f's imports by the identifier they introduce. - imports := collectImports(p.f) - if p.loadRealPackageNames { - err := p.loadPackageNames(ctx, append(imports, p.candidates...)) - if err != nil { - if p.logf != nil { - p.logf("loading package names: %v", err) - } - return nil, false - } - } - for _, imp := range imports { - p.existingImports[p.importIdentifier(imp)] = append(p.existingImports[p.importIdentifier(imp)], imp) - } - - // Find missing references. - for left, rights := range p.allRefs { - if globals[left] { - continue - } - _, ok := p.existingImports[left] - if !ok { - p.missingRefs[left] = rights - continue - } - } - if len(p.missingRefs) != 0 { - return nil, false - } - - return p.fix() -} - -// fix attempts to satisfy missing imports using p.candidates. If it finds -// everything, or if p.lastTry is true, it updates fixes to add the imports it found, -// delete anything unused, and update import names, and returns true. -func (p *pass) fix() ([]*ImportFix, bool) { - // Find missing imports. - var selected []*ImportInfo - for left, rights := range p.missingRefs { - if imp := p.findMissingImport(left, rights); imp != nil { - selected = append(selected, imp) - } - } - - if !p.lastTry && len(selected) != len(p.missingRefs) { - return nil, false - } - - // Found everything, or giving up. Add the new imports and remove any unused. - var fixes []*ImportFix - for _, identifierImports := range p.existingImports { - for _, imp := range identifierImports { - // We deliberately ignore globals here, because we can't be sure - // they're in the same package. People do things like put multiple - // main packages in the same directory, and we don't want to - // remove imports if they happen to have the same name as a var in - // a different package. - if _, ok := p.allRefs[p.importIdentifier(imp)]; !ok { - fixes = append(fixes, &ImportFix{ - StmtInfo: *imp, - IdentName: p.importIdentifier(imp), - FixType: DeleteImport, - }) - continue - } - - // An existing import may need to update its import name to be correct. - if name := p.importSpecName(imp); name != imp.Name { - fixes = append(fixes, &ImportFix{ - StmtInfo: ImportInfo{ - Name: name, - ImportPath: imp.ImportPath, - }, - IdentName: p.importIdentifier(imp), - FixType: SetImportName, - }) - } - } - } - // Collecting fixes involved map iteration, so sort for stability. See - // golang/go#59976. - sortFixes(fixes) - - // collect selected fixes in a separate slice, so that it can be sorted - // separately. Note that these fixes must occur after fixes to existing - // imports. TODO(rfindley): figure out why. - var selectedFixes []*ImportFix - for _, imp := range selected { - selectedFixes = append(selectedFixes, &ImportFix{ - StmtInfo: ImportInfo{ - Name: p.importSpecName(imp), - ImportPath: imp.ImportPath, - }, - IdentName: p.importIdentifier(imp), - FixType: AddImport, - }) - } - sortFixes(selectedFixes) - - return append(fixes, selectedFixes...), true -} - -func sortFixes(fixes []*ImportFix) { - sort.Slice(fixes, func(i, j int) bool { - fi, fj := fixes[i], fixes[j] - if fi.StmtInfo.ImportPath != fj.StmtInfo.ImportPath { - return fi.StmtInfo.ImportPath < fj.StmtInfo.ImportPath - } - if fi.StmtInfo.Name != fj.StmtInfo.Name { - return fi.StmtInfo.Name < fj.StmtInfo.Name - } - if fi.IdentName != fj.IdentName { - return fi.IdentName < fj.IdentName - } - return fi.FixType < fj.FixType - }) -} - -// importSpecName gets the import name of imp in the import spec. -// -// When the import identifier matches the assumed import name, the import name does -// not appear in the import spec. -func (p *pass) importSpecName(imp *ImportInfo) string { - // If we did not load the real package names, or the name is already set, - // we just return the existing name. - if !p.loadRealPackageNames || imp.Name != "" { - return imp.Name - } - - ident := p.importIdentifier(imp) - if ident == ImportPathToAssumedName(imp.ImportPath) { - return "" // ident not needed since the assumed and real names are the same. - } - return ident -} - -// apply will perform the fixes on f in order. -func apply(fset *token.FileSet, f *ast.File, fixes []*ImportFix) { - for _, fix := range fixes { - switch fix.FixType { - case DeleteImport: - astutil.DeleteNamedImport(fset, f, fix.StmtInfo.Name, fix.StmtInfo.ImportPath) - case AddImport: - astutil.AddNamedImport(fset, f, fix.StmtInfo.Name, fix.StmtInfo.ImportPath) - case SetImportName: - // Find the matching import path and change the name. - for _, spec := range f.Imports { - path := strings.Trim(spec.Path.Value, `"`) - if path == fix.StmtInfo.ImportPath { - spec.Name = &ast.Ident{ - Name: fix.StmtInfo.Name, - NamePos: spec.Pos(), - } - } - } - } - } -} - -// assumeSiblingImportsValid assumes that siblings' use of packages is valid, -// adding the exports they use. -func (p *pass) assumeSiblingImportsValid() { - for _, f := range p.otherFiles { - refs := collectReferences(f) - imports := collectImports(f) - importsByName := map[string]*ImportInfo{} - for _, imp := range imports { - importsByName[p.importIdentifier(imp)] = imp - } - for left, rights := range refs { - if imp, ok := importsByName[left]; ok { - if m, ok := stdlib.PackageSymbols[imp.ImportPath]; ok { - // We have the stdlib in memory; no need to guess. - rights = symbolNameSet(m) - } - // TODO(rfindley): we should set package name here, for consistency. - p.addCandidate(imp, &PackageInfo{ - // no name; we already know it. - Exports: rights, - }) - } - } - } -} - -// addCandidate adds a candidate import to p, and merges in the information -// in pkg. -func (p *pass) addCandidate(imp *ImportInfo, pkg *PackageInfo) { - p.candidates = append(p.candidates, imp) - if existing, ok := p.knownPackages[imp.ImportPath]; ok { - if existing.Name == "" { - existing.Name = pkg.Name - } - for export := range pkg.Exports { - existing.Exports[export] = true - } - } else { - p.knownPackages[imp.ImportPath] = pkg - } -} - -// fixImports adds and removes imports from f so that all its references are -// satisfied and there are no unused imports. -// -// This is declared as a variable rather than a function so goimports can -// easily be extended by adding a file with an init function. -// -// DO NOT REMOVE: used internally at Google. -var fixImports = fixImportsDefault - -func fixImportsDefault(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) error { - fixes, err := getFixes(context.Background(), fset, f, filename, env) - if err != nil { - return err - } - apply(fset, f, fixes) - return nil -} - -// getFixes gets the import fixes that need to be made to f in order to fix the imports. -// It does not modify the ast. -func getFixes(ctx context.Context, fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) ([]*ImportFix, error) { - source, err := NewProcessEnvSource(env, filename, f.Name.Name) - if err != nil { - return nil, err - } - goEnv, err := env.goEnv() - if err != nil { - return nil, err - } - return getFixesWithSource(ctx, fset, f, filename, goEnv["GOROOT"], env.logf, source) -} - -func getFixesWithSource(ctx context.Context, fset *token.FileSet, f *ast.File, filename string, goroot string, logf func(string, ...any), source Source) ([]*ImportFix, error) { - // This logic is defensively duplicated from getFixes. - abs, err := filepath.Abs(filename) - if err != nil { - return nil, err - } - srcDir := filepath.Dir(abs) - - if logf != nil { - logf("fixImports(filename=%q), srcDir=%q ...", filename, srcDir) - } - - // First pass: looking only at f, and using the naive algorithm to - // derive package names from import paths, see if the file is already - // complete. We can't add any imports yet, because we don't know - // if missing references are actually package vars. - p := &pass{ - fset: fset, - f: f, - srcDir: srcDir, - logf: logf, - goroot: goroot, - source: source, - } - if fixes, done := p.load(ctx); done { - return fixes, nil - } - - otherFiles, err := parseOtherFiles(ctx, fset, srcDir, filename) - if err != nil { - return nil, err - } - - // Second pass: add information from other files in the same package, - // like their package vars and imports. - p.otherFiles = otherFiles - if fixes, done := p.load(ctx); done { - return fixes, nil - } - - // Now we can try adding imports from the stdlib. - p.assumeSiblingImportsValid() - addStdlibCandidates(p, p.missingRefs) - if fixes, done := p.fix(); done { - return fixes, nil - } - - // Third pass: get real package names where we had previously used - // the naive algorithm. - p = &pass{ - fset: fset, - f: f, - srcDir: srcDir, - logf: logf, - goroot: goroot, - source: p.source, // safe to reuse, as it's just a wrapper around env - } - p.loadRealPackageNames = true - p.otherFiles = otherFiles - if fixes, done := p.load(ctx); done { - return fixes, nil - } - - if err := addStdlibCandidates(p, p.missingRefs); err != nil { - return nil, err - } - p.assumeSiblingImportsValid() - if fixes, done := p.fix(); done { - return fixes, nil - } - - // Go look for candidates in $GOPATH, etc. We don't necessarily load - // the real exports of sibling imports, so keep assuming their contents. - if err := addExternalCandidates(ctx, p, p.missingRefs, filename); err != nil { - return nil, err - } - - p.lastTry = true - fixes, _ := p.fix() - return fixes, nil -} - -// MaxRelevance is the highest relevance, used for the standard library. -// Chosen arbitrarily to match pre-existing gopls code. -const MaxRelevance = 7.0 - -// getCandidatePkgs works with the passed callback to find all acceptable packages. -// It deduplicates by import path, and uses a cached stdlib rather than reading -// from disk. -func getCandidatePkgs(ctx context.Context, wrappedCallback *scanCallback, filename, filePkg string, env *ProcessEnv) error { - notSelf := func(p *pkg) bool { - return p.packageName != filePkg || p.dir != filepath.Dir(filename) - } - goenv, err := env.goEnv() - if err != nil { - return err - } - - var mu sync.Mutex // to guard asynchronous access to dupCheck - dupCheck := map[string]struct{}{} - - // Start off with the standard library. - for importPath, symbols := range stdlib.PackageSymbols { - p := &pkg{ - dir: filepath.Join(goenv["GOROOT"], "src", importPath), - importPathShort: importPath, - packageName: path.Base(importPath), - relevance: MaxRelevance, - } - dupCheck[importPath] = struct{}{} - if notSelf(p) && wrappedCallback.dirFound(p) && wrappedCallback.packageNameLoaded(p) { - var exports []stdlib.Symbol - for _, sym := range symbols { - switch sym.Kind { - case stdlib.Func, stdlib.Type, stdlib.Var, stdlib.Const: - exports = append(exports, sym) - } - } - wrappedCallback.exportsLoaded(p, exports) - } - } - - scanFilter := &scanCallback{ - rootFound: func(root gopathwalk.Root) bool { - // Exclude goroot results -- getting them is relatively expensive, not cached, - // and generally redundant with the in-memory version. - return root.Type != gopathwalk.RootGOROOT && wrappedCallback.rootFound(root) - }, - dirFound: wrappedCallback.dirFound, - packageNameLoaded: func(pkg *pkg) bool { - mu.Lock() - defer mu.Unlock() - if _, ok := dupCheck[pkg.importPathShort]; ok { - return false - } - dupCheck[pkg.importPathShort] = struct{}{} - return notSelf(pkg) && wrappedCallback.packageNameLoaded(pkg) - }, - exportsLoaded: func(pkg *pkg, exports []stdlib.Symbol) { - // If we're an x_test, load the package under test's test variant. - if strings.HasSuffix(filePkg, "_test") && pkg.dir == filepath.Dir(filename) { - var err error - _, exports, err = loadExportsFromFiles(ctx, env, pkg.dir, true) - if err != nil { - return - } - } - wrappedCallback.exportsLoaded(pkg, exports) - }, - } - resolver, err := env.GetResolver() - if err != nil { - return err - } - return resolver.scan(ctx, scanFilter) -} - -func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) (map[string]float64, error) { - result := make(map[string]float64) - resolver, err := env.GetResolver() - if err != nil { - return nil, err - } - for _, path := range paths { - result[path] = resolver.scoreImportPath(ctx, path) - } - return result, nil -} - -func PrimeCache(ctx context.Context, resolver Resolver) error { - // Fully scan the disk for directories, but don't actually read any Go files. - callback := &scanCallback{ - rootFound: func(root gopathwalk.Root) bool { - // See getCandidatePkgs: walking GOROOT is apparently expensive and - // unnecessary. - return root.Type != gopathwalk.RootGOROOT - }, - dirFound: func(pkg *pkg) bool { - return false - }, - // packageNameLoaded and exportsLoaded must never be called. - } - - return resolver.scan(ctx, callback) -} - -func candidateImportName(pkg *pkg) string { - if ImportPathToAssumedName(pkg.importPathShort) != pkg.packageName { - return pkg.packageName - } - return "" -} - -// GetAllCandidates calls wrapped for each package whose name starts with -// searchPrefix, and can be imported from filename with the package name filePkg. -// -// Beware that the wrapped function may be called multiple times concurrently. -// TODO(adonovan): encapsulate the concurrency. -func GetAllCandidates(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error { - callback := &scanCallback{ - rootFound: func(gopathwalk.Root) bool { - return true - }, - dirFound: func(pkg *pkg) bool { - if !CanUse(filename, pkg.dir) { - return false - } - // Try the assumed package name first, then a simpler path match - // in case of packages named vN, which are not uncommon. - return strings.HasPrefix(ImportPathToAssumedName(pkg.importPathShort), searchPrefix) || - strings.HasPrefix(path.Base(pkg.importPathShort), searchPrefix) - }, - packageNameLoaded: func(pkg *pkg) bool { - if !strings.HasPrefix(pkg.packageName, searchPrefix) { - return false - } - wrapped(ImportFix{ - StmtInfo: ImportInfo{ - ImportPath: pkg.importPathShort, - Name: candidateImportName(pkg), - }, - IdentName: pkg.packageName, - FixType: AddImport, - Relevance: pkg.relevance, - }) - return false - }, - } - return getCandidatePkgs(ctx, callback, filename, filePkg, env) -} - -// GetImportPaths calls wrapped for each package whose import path starts with -// searchPrefix, and can be imported from filename with the package name filePkg. -func GetImportPaths(ctx context.Context, wrapped func(ImportFix), searchPrefix, filename, filePkg string, env *ProcessEnv) error { - callback := &scanCallback{ - rootFound: func(gopathwalk.Root) bool { - return true - }, - dirFound: func(pkg *pkg) bool { - if !CanUse(filename, pkg.dir) { - return false - } - return strings.HasPrefix(pkg.importPathShort, searchPrefix) - }, - packageNameLoaded: func(pkg *pkg) bool { - wrapped(ImportFix{ - StmtInfo: ImportInfo{ - ImportPath: pkg.importPathShort, - Name: candidateImportName(pkg), - }, - IdentName: pkg.packageName, - FixType: AddImport, - Relevance: pkg.relevance, - }) - return false - }, - } - return getCandidatePkgs(ctx, callback, filename, filePkg, env) -} - -// A PackageExport is a package and its exports. -type PackageExport struct { - Fix *ImportFix - Exports []stdlib.Symbol -} - -// GetPackageExports returns all known packages with name pkg and their exports. -func GetPackageExports(ctx context.Context, wrapped func(PackageExport), searchPkg, filename, filePkg string, env *ProcessEnv) error { - callback := &scanCallback{ - rootFound: func(gopathwalk.Root) bool { - return true - }, - dirFound: func(pkg *pkg) bool { - return pkgIsCandidate(filename, References{searchPkg: nil}, pkg) - }, - packageNameLoaded: func(pkg *pkg) bool { - return pkg.packageName == searchPkg - }, - exportsLoaded: func(pkg *pkg, exports []stdlib.Symbol) { - sortSymbols(exports) - wrapped(PackageExport{ - Fix: &ImportFix{ - StmtInfo: ImportInfo{ - ImportPath: pkg.importPathShort, - Name: candidateImportName(pkg), - }, - IdentName: pkg.packageName, - FixType: AddImport, - Relevance: pkg.relevance, - }, - Exports: exports, - }) - }, - } - return getCandidatePkgs(ctx, callback, filename, filePkg, env) -} - -// TODO(rfindley): we should depend on GOOS and GOARCH, to provide accurate -// imports when doing cross-platform development. -var requiredGoEnvVars = []string{ - "GO111MODULE", - "GOFLAGS", - "GOINSECURE", - "GOMOD", - "GOMODCACHE", - "GONOPROXY", - "GONOSUMDB", - "GOPATH", - "GOPROXY", - "GOROOT", - "GOSUMDB", - "GOWORK", -} - -// ProcessEnv contains environment variables and settings that affect the use of -// the go command, the go/build package, etc. -// -// ...a ProcessEnv *also* overwrites its Env along with derived state in the -// form of the resolver. And because it is lazily initialized, an env may just -// be broken and unusable, but there is no way for the caller to detect that: -// all queries will just fail. -// -// TODO(rfindley): refactor this package so that this type (perhaps renamed to -// just Env or Config) is an immutable configuration struct, to be exchanged -// for an initialized object via a constructor that returns an error. Perhaps -// the signature should be `func NewResolver(*Env) (*Resolver, error)`, where -// resolver is a concrete type used for resolving imports. Via this -// refactoring, we can avoid the need to call ProcessEnv.init and -// ProcessEnv.GoEnv everywhere, and implicitly fix all the places where this -// these are misused. Also, we'd delegate the caller the decision of how to -// handle a broken environment. -type ProcessEnv struct { - GocmdRunner *gocommand.Runner - - BuildFlags []string - ModFlag string - - // SkipPathInScan returns true if the path should be skipped from scans of - // the RootCurrentModule root type. The function argument is a clean, - // absolute path. - SkipPathInScan func(string) bool - - // Env overrides the OS environment, and can be used to specify - // GOPROXY, GO111MODULE, etc. PATH cannot be set here, because - // exec.Command will not honor it. - // Specifying all of requiredGoEnvVars avoids a call to `go env`. - Env map[string]string - - WorkingDir string - - // If Logf is non-nil, debug logging is enabled through this function. - Logf func(format string, args ...any) - - // If set, ModCache holds a shared cache of directory info to use across - // multiple ProcessEnvs. - ModCache *DirInfoCache - - initialized bool // see TODO above - - // resolver and resolverErr are lazily evaluated (see GetResolver). - // This is unclean, but see the big TODO in the docstring for ProcessEnv - // above: for now, we can't be sure that the ProcessEnv is fully initialized. - resolver Resolver - resolverErr error -} - -func (e *ProcessEnv) goEnv() (map[string]string, error) { - if err := e.init(); err != nil { - return nil, err - } - return e.Env, nil -} - -func (e *ProcessEnv) matchFile(dir, name string) (bool, error) { - bctx, err := e.buildContext() - if err != nil { - return false, err - } - return bctx.MatchFile(dir, name) -} - -// CopyConfig copies the env's configuration into a new env. -func (e *ProcessEnv) CopyConfig() *ProcessEnv { - copy := &ProcessEnv{ - GocmdRunner: e.GocmdRunner, - initialized: e.initialized, - BuildFlags: e.BuildFlags, - Logf: e.Logf, - WorkingDir: e.WorkingDir, - resolver: nil, - Env: map[string]string{}, - } - maps.Copy(copy.Env, e.Env) - return copy -} - -func (e *ProcessEnv) init() error { - if e.initialized { - return nil - } - - foundAllRequired := true - for _, k := range requiredGoEnvVars { - if _, ok := e.Env[k]; !ok { - foundAllRequired = false - break - } - } - if foundAllRequired { - e.initialized = true - return nil - } - - if e.Env == nil { - e.Env = map[string]string{} - } - - goEnv := map[string]string{} - stdout, err := e.invokeGo(context.TODO(), "env", append([]string{"-json"}, requiredGoEnvVars...)...) - if err != nil { - return err - } - if err := json.Unmarshal(stdout.Bytes(), &goEnv); err != nil { - return err - } - maps.Copy(e.Env, goEnv) - e.initialized = true - return nil -} - -func (e *ProcessEnv) env() []string { - var env []string // the gocommand package will prepend os.Environ. - for k, v := range e.Env { - env = append(env, k+"="+v) - } - return env -} - -func (e *ProcessEnv) GetResolver() (Resolver, error) { - if err := e.init(); err != nil { - return nil, err - } - - if e.resolver == nil && e.resolverErr == nil { - // TODO(rfindley): we should only use a gopathResolver here if the working - // directory is actually *in* GOPATH. (I seem to recall an open gopls issue - // for this behavior, but I can't find it). - // - // For gopls, we can optionally explicitly choose a resolver type, since we - // already know the view type. - if e.Env["GOMOD"] == "" && (e.Env["GOWORK"] == "" || e.Env["GOWORK"] == "off") { - e.resolver = newGopathResolver(e) - e.logf("created gopath resolver") - } else if r, err := newModuleResolver(e, e.ModCache); err != nil { - e.resolverErr = err - e.logf("failed to create module resolver: %v", err) - } else { - e.resolver = Resolver(r) - e.logf("created module resolver") - } - } - - return e.resolver, e.resolverErr -} - -// logf logs if e.Logf is non-nil. -func (e *ProcessEnv) logf(format string, args ...any) { - if e.Logf != nil { - e.Logf(format, args...) - } -} - -// buildContext returns the build.Context to use for matching files. -// -// TODO(rfindley): support dynamic GOOS, GOARCH here, when doing cross-platform -// development. -func (e *ProcessEnv) buildContext() (*build.Context, error) { - ctx := build.Default - goenv, err := e.goEnv() - if err != nil { - return nil, err - } - ctx.GOROOT = goenv["GOROOT"] - ctx.GOPATH = goenv["GOPATH"] - - // As of Go 1.14, build.Context has a Dir field - // (see golang.org/issue/34860). - // Populate it only if present. - rc := reflect.ValueOf(&ctx).Elem() - dir := rc.FieldByName("Dir") - if dir.IsValid() && dir.Kind() == reflect.String { - dir.SetString(e.WorkingDir) - } - - // Since Go 1.11, go/build.Context.Import may invoke 'go list' depending on - // the value in GO111MODULE in the process's environment. We always want to - // run in GOPATH mode when calling Import, so we need to prevent this from - // happening. In Go 1.16, GO111MODULE defaults to "on", so this problem comes - // up more frequently. - // - // HACK: setting any of the Context I/O hooks prevents Import from invoking - // 'go list', regardless of GO111MODULE. This is undocumented, but it's - // unlikely to change before GOPATH support is removed. - ctx.ReadDir = ioutil.ReadDir - - return &ctx, nil -} - -func (e *ProcessEnv) invokeGo(ctx context.Context, verb string, args ...string) (*bytes.Buffer, error) { - inv := gocommand.Invocation{ - Verb: verb, - Args: args, - BuildFlags: e.BuildFlags, - Env: e.env(), - Logf: e.Logf, - WorkingDir: e.WorkingDir, - } - return e.GocmdRunner.Run(ctx, inv) -} - -func addStdlibCandidates(pass *pass, refs References) error { - localbase := func(nm string) string { - ans := path.Base(nm) - if ans[0] == 'v' { - // this is called, for instance, with math/rand/v2 and returns rand/v2 - if _, err := strconv.Atoi(ans[1:]); err == nil { - ix := strings.LastIndex(nm, ans) - more := path.Base(nm[:ix]) - ans = path.Join(more, ans) - } - } - return ans - } - add := func(pkg string) { - // Prevent self-imports. - if path.Base(pkg) == pass.f.Name.Name && filepath.Join(pass.goroot, "src", pkg) == pass.srcDir { - return - } - exports := symbolNameSet(stdlib.PackageSymbols[pkg]) - pass.addCandidate( - &ImportInfo{ImportPath: pkg}, - &PackageInfo{Name: localbase(pkg), Exports: exports}) - } - for left := range refs { - if left == "rand" { - // Make sure we try crypto/rand before any version of math/rand as both have Int() - // and our policy is to recommend crypto - add("crypto/rand") - // if the user's no later than go1.21, this should be "math/rand" - // but we have no way of figuring out what the user is using - // TODO: investigate using the toolchain version to disambiguate in the stdlib - add("math/rand/v2") - // math/rand has an overlapping API - // TestIssue66407 fails without this - add("math/rand") - continue - } - for importPath := range stdlib.PackageSymbols { - if path.Base(importPath) == left { - add(importPath) - } - } - } - return nil -} - -// A Resolver does the build-system-specific parts of goimports. -type Resolver interface { - // loadPackageNames loads the package names in importPaths. - loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) - - // scan works with callback to search for packages. See scanCallback for details. - scan(ctx context.Context, callback *scanCallback) error - - // loadExports returns the package name and set of exported symbols in the - // package at dir. loadExports may be called concurrently. - loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error) - - // scoreImportPath returns the relevance for an import path. - scoreImportPath(ctx context.Context, path string) float64 - - // ClearForNewScan returns a new Resolver based on the receiver that has - // cleared its internal caches of directory contents. - // - // The new resolver should be primed and then set via - // [ProcessEnv.UpdateResolver]. - ClearForNewScan() Resolver -} - -// A scanCallback controls a call to scan and receives its results. -// In general, minor errors will be silently discarded; a user should not -// expect to receive a full series of calls for everything. -type scanCallback struct { - // rootFound is called before scanning a new root dir. If it returns true, - // the root will be scanned. Returning false will not necessarily prevent - // directories from that root making it to dirFound. - rootFound func(gopathwalk.Root) bool - // dirFound is called when a directory is found that is possibly a Go package. - // pkg will be populated with everything except packageName. - // If it returns true, the package's name will be loaded. - dirFound func(pkg *pkg) bool - // packageNameLoaded is called when a package is found and its name is loaded. - // If it returns true, the package's exports will be loaded. - packageNameLoaded func(pkg *pkg) bool - // exportsLoaded is called when a package's exports have been loaded. - exportsLoaded func(pkg *pkg, exports []stdlib.Symbol) -} - -func addExternalCandidates(ctx context.Context, pass *pass, refs References, filename string) error { - ctx, done := event.Start(ctx, "imports.addExternalCandidates") - defer done() - - results, err := pass.source.ResolveReferences(ctx, filename, refs) - if err != nil { - return err - } - - for _, result := range results { - if result == nil { - continue - } - // Don't offer completions that would shadow predeclared - // names, such as github.com/coreos/etcd/error. - if types.Universe.Lookup(result.Package.Name) != nil { // predeclared - // Ideally we would skip this candidate only - // if the predeclared name is actually - // referenced by the file, but that's a lot - // trickier to compute and would still create - // an import that is likely to surprise the - // user before long. - continue - } - pass.addCandidate(result.Import, result.Package) - } - return nil -} - -// notIdentifier reports whether ch is an invalid identifier character. -func notIdentifier(ch rune) bool { - return !('a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || - '0' <= ch && ch <= '9' || - ch == '_' || - ch >= utf8.RuneSelf && (unicode.IsLetter(ch) || unicode.IsDigit(ch))) -} - -// ImportPathToAssumedName returns the assumed package name of an import path. -// It does this using only string parsing of the import path. -// It picks the last element of the path that does not look like a major -// version, and then picks the valid identifier off the start of that element. -// It is used to determine if a local rename should be added to an import for -// clarity. -// This function could be moved to a standard package and exported if we want -// for use in other tools. -func ImportPathToAssumedName(importPath string) string { - base := path.Base(importPath) - if strings.HasPrefix(base, "v") { - if _, err := strconv.Atoi(base[1:]); err == nil { - dir := path.Dir(importPath) - if dir != "." { - base = path.Base(dir) - } - } - } - base = strings.TrimPrefix(base, "go-") - if i := strings.IndexFunc(base, notIdentifier); i >= 0 { - base = base[:i] - } - return base -} - -// gopathResolver implements resolver for GOPATH workspaces. -type gopathResolver struct { - env *ProcessEnv - cache *DirInfoCache - scanSema chan struct{} // scanSema prevents concurrent scans. -} - -func newGopathResolver(env *ProcessEnv) *gopathResolver { - r := &gopathResolver{ - env: env, - cache: NewDirInfoCache(), - scanSema: make(chan struct{}, 1), - } - r.scanSema <- struct{}{} - return r -} - -func (r *gopathResolver) ClearForNewScan() Resolver { - return newGopathResolver(r.env) -} - -func (r *gopathResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) { - names := map[string]string{} - bctx, err := r.env.buildContext() - if err != nil { - return nil, err - } - for _, path := range importPaths { - names[path] = importPathToName(bctx, path, srcDir) - } - return names, nil -} - -// importPathToName finds out the actual package name, as declared in its .go files. -func importPathToName(bctx *build.Context, importPath, srcDir string) string { - // Fast path for standard library without going to disk. - if stdlib.HasPackage(importPath) { - return path.Base(importPath) // stdlib packages always match their paths. - } - - buildPkg, err := bctx.Import(importPath, srcDir, build.FindOnly) - if err != nil { - return "" - } - pkgName, err := packageDirToName(buildPkg.Dir) - if err != nil { - return "" - } - return pkgName -} - -// packageDirToName is a faster version of build.Import if -// the only thing desired is the package name. Given a directory, -// packageDirToName then only parses one file in the package, -// trusting that the files in the directory are consistent. -func packageDirToName(dir string) (packageName string, err error) { - d, err := os.Open(dir) - if err != nil { - return "", err - } - names, err := d.Readdirnames(-1) - d.Close() - if err != nil { - return "", err - } - sort.Strings(names) // to have predictable behavior - var lastErr error - var nfile int - for _, name := range names { - if !strings.HasSuffix(name, ".go") { - continue - } - if strings.HasSuffix(name, "_test.go") { - continue - } - nfile++ - fullFile := filepath.Join(dir, name) - - fset := token.NewFileSet() - f, err := parser.ParseFile(fset, fullFile, nil, parser.PackageClauseOnly) - if err != nil { - lastErr = err - continue - } - pkgName := f.Name.Name - if pkgName == "documentation" { - // Special case from go/build.ImportDir, not - // handled by ctx.MatchFile. - continue - } - if pkgName == "main" { - // Also skip package main, assuming it's a +build ignore generator or example. - // Since you can't import a package main anyway, there's no harm here. - continue - } - return pkgName, nil - } - if lastErr != nil { - return "", lastErr - } - return "", fmt.Errorf("no importable package found in %d Go files", nfile) -} - -type pkg struct { - dir string // absolute file path to pkg directory ("/usr/lib/go/src/net/http") - importPathShort string // vendorless import path ("net/http", "a/b") - packageName string // package name loaded from source if requested - relevance float64 // a weakly-defined score of how relevant a package is. 0 is most relevant. -} - -type pkgDistance struct { - pkg *pkg - distance int // relative distance to target -} - -// byDistanceOrImportPathShortLength sorts by relative distance breaking ties -// on the short import path length and then the import string itself. -type byDistanceOrImportPathShortLength []pkgDistance - -func (s byDistanceOrImportPathShortLength) Len() int { return len(s) } -func (s byDistanceOrImportPathShortLength) Less(i, j int) bool { - di, dj := s[i].distance, s[j].distance - if di == -1 { - return false - } - if dj == -1 { - return true - } - if di != dj { - return di < dj - } - - vi, vj := s[i].pkg.importPathShort, s[j].pkg.importPathShort - if len(vi) != len(vj) { - return len(vi) < len(vj) - } - return vi < vj -} -func (s byDistanceOrImportPathShortLength) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -func distance(basepath, targetpath string) int { - p, err := filepath.Rel(basepath, targetpath) - if err != nil { - return -1 - } - if p == "." { - return 0 - } - return strings.Count(p, string(filepath.Separator)) + 1 -} - -func (r *gopathResolver) scan(ctx context.Context, callback *scanCallback) error { - add := func(root gopathwalk.Root, dir string) { - // We assume cached directories have not changed. We can skip them and their - // children. - if _, ok := r.cache.Load(dir); ok { - return - } - - importpath := filepath.ToSlash(dir[len(root.Path)+len("/"):]) - info := directoryPackageInfo{ - status: directoryScanned, - dir: dir, - rootType: root.Type, - nonCanonicalImportPath: VendorlessPath(importpath), - } - r.cache.Store(dir, info) - } - processDir := func(info directoryPackageInfo) { - // Skip this directory if we were not able to get the package information successfully. - if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil { - return - } - - p := &pkg{ - importPathShort: info.nonCanonicalImportPath, - dir: info.dir, - relevance: MaxRelevance - 1, - } - if info.rootType == gopathwalk.RootGOROOT { - p.relevance = MaxRelevance - } - - if !callback.dirFound(p) { - return - } - var err error - p.packageName, err = r.cache.CachePackageName(info) - if err != nil { - return - } - - if !callback.packageNameLoaded(p) { - return - } - if _, exports, err := r.loadExports(ctx, p, false); err == nil { - callback.exportsLoaded(p, exports) - } - } - stop := r.cache.ScanAndListen(ctx, processDir) - defer stop() - - goenv, err := r.env.goEnv() - if err != nil { - return err - } - var roots []gopathwalk.Root - roots = append(roots, gopathwalk.Root{Path: filepath.Join(goenv["GOROOT"], "src"), Type: gopathwalk.RootGOROOT}) - for _, p := range filepath.SplitList(goenv["GOPATH"]) { - roots = append(roots, gopathwalk.Root{Path: filepath.Join(p, "src"), Type: gopathwalk.RootGOPATH}) - } - // The callback is not necessarily safe to use in the goroutine below. Process roots eagerly. - roots = filterRoots(roots, callback.rootFound) - // We can't cancel walks, because we need them to finish to have a usable - // cache. Instead, run them in a separate goroutine and detach. - scanDone := make(chan struct{}) - go func() { - select { - case <-ctx.Done(): - return - case <-r.scanSema: - } - defer func() { r.scanSema <- struct{}{} }() - gopathwalk.Walk(roots, add, gopathwalk.Options{Logf: r.env.Logf, ModulesEnabled: false}) - close(scanDone) - }() - select { - case <-ctx.Done(): - case <-scanDone: - } - return nil -} - -func (r *gopathResolver) scoreImportPath(ctx context.Context, path string) float64 { - if stdlib.HasPackage(path) { - return MaxRelevance - } - return MaxRelevance - 1 -} - -func filterRoots(roots []gopathwalk.Root, include func(gopathwalk.Root) bool) []gopathwalk.Root { - var result []gopathwalk.Root - for _, root := range roots { - if !include(root) { - continue - } - result = append(result, root) - } - return result -} - -func (r *gopathResolver) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error) { - if info, ok := r.cache.Load(pkg.dir); ok && !includeTest { - return r.cache.CacheExports(ctx, r.env, info) - } - return loadExportsFromFiles(ctx, r.env, pkg.dir, includeTest) -} - -// VendorlessPath returns the devendorized version of the import path ipath. -// For example, VendorlessPath("foo/bar/vendor/a/b") returns "a/b". -func VendorlessPath(ipath string) string { - // Devendorize for use in import statement. - if i := strings.LastIndex(ipath, "/vendor/"); i >= 0 { - return ipath[i+len("/vendor/"):] - } - if strings.HasPrefix(ipath, "vendor/") { - return ipath[len("vendor/"):] - } - return ipath -} - -func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, includeTest bool) (string, []stdlib.Symbol, error) { - // Look for non-test, buildable .go files which could provide exports. - all, err := os.ReadDir(dir) - if err != nil { - return "", nil, err - } - var files []fs.DirEntry - for _, fi := range all { - name := fi.Name() - if !strings.HasSuffix(name, ".go") || (!includeTest && strings.HasSuffix(name, "_test.go")) { - continue - } - match, err := env.matchFile(dir, fi.Name()) - if err != nil || !match { - continue - } - files = append(files, fi) - } - - if len(files) == 0 { - return "", nil, fmt.Errorf("dir %v contains no buildable, non-test .go files", dir) - } - - var pkgName string - var exports []stdlib.Symbol - fset := token.NewFileSet() - for _, fi := range files { - select { - case <-ctx.Done(): - return "", nil, ctx.Err() - default: - } - - fullFile := filepath.Join(dir, fi.Name()) - // Legacy ast.Object resolution is needed here. - f, err := parser.ParseFile(fset, fullFile, nil, 0) - if err != nil { - env.logf("error parsing %v: %v", fullFile, err) - continue - } - if f.Name.Name == "documentation" { - // Special case from go/build.ImportDir, not - // handled by MatchFile above. - continue - } - if includeTest && strings.HasSuffix(f.Name.Name, "_test") { - // x_test package. We want internal test files only. - continue - } - pkgName = f.Name.Name - for name, obj := range f.Scope.Objects { - if ast.IsExported(name) { - var kind stdlib.Kind - switch obj.Kind { - case ast.Con: - kind = stdlib.Const - case ast.Typ: - kind = stdlib.Type - case ast.Var: - kind = stdlib.Var - case ast.Fun: - kind = stdlib.Func - } - exports = append(exports, stdlib.Symbol{ - Name: name, - Kind: kind, - Version: 0, // unknown; be permissive - }) - } - } - } - sortSymbols(exports) - - env.logf("loaded exports in dir %v (package %v): %v", dir, pkgName, exports) - return pkgName, exports, nil -} - -func sortSymbols(syms []stdlib.Symbol) { - sort.Slice(syms, func(i, j int) bool { - return syms[i].Name < syms[j].Name - }) -} - -// A symbolSearcher searches for a package with a set of symbols, among a set -// of candidates. See [symbolSearcher.search]. -// -// The search occurs within the scope of a single file, with context captured -// in srcDir and xtest. -type symbolSearcher struct { - logf func(string, ...any) - srcDir string // directory containing the file - xtest bool // if set, the file containing is an x_test file - loadExports func(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error) -} - -// search searches the provided candidates for a package containing all -// exported symbols. -// -// If successful, returns the resulting package. -func (s *symbolSearcher) search(ctx context.Context, candidates []pkgDistance, pkgName string, symbols map[string]bool) (*pkg, error) { - // Sort the candidates by their import package length, - // assuming that shorter package names are better than long - // ones. Note that this sorts by the de-vendored name, so - // there's no "penalty" for vendoring. - sort.Sort(byDistanceOrImportPathShortLength(candidates)) - if s.logf != nil { - for i, c := range candidates { - s.logf("%s candidate %d/%d: %v in %v", pkgName, i+1, len(candidates), c.pkg.importPathShort, c.pkg.dir) - } - } - - // Arrange rescv so that we can we can await results in order of relevance - // and exit as soon as we find the first match. - // - // Search with bounded concurrency, returning as soon as the first result - // among rescv is non-nil. - rescv := make([]chan *pkg, len(candidates)) - for i := range candidates { - rescv[i] = make(chan *pkg, 1) - } - const maxConcurrentPackageImport = 4 - loadExportsSem := make(chan struct{}, maxConcurrentPackageImport) - - // Ensure that all work is completed at exit. - ctx, cancel := context.WithCancel(ctx) - var wg sync.WaitGroup - defer func() { - cancel() - wg.Wait() - }() - - // Start the search. - wg.Add(1) - go func() { - defer wg.Done() - for i, c := range candidates { - select { - case loadExportsSem <- struct{}{}: - case <-ctx.Done(): - return - } - - i := i - c := c - wg.Add(1) - go func() { - defer func() { - <-loadExportsSem - wg.Done() - }() - if s.logf != nil { - s.logf("loading exports in dir %s (seeking package %s)", c.pkg.dir, pkgName) - } - pkg, err := s.searchOne(ctx, c, symbols) - if err != nil { - if s.logf != nil && ctx.Err() == nil { - s.logf("loading exports in dir %s (seeking package %s): %v", c.pkg.dir, pkgName, err) - } - pkg = nil - } - rescv[i] <- pkg // may be nil - }() - } - }() - - // Await the first (best) result. - for _, resc := range rescv { - select { - case r := <-resc: - if r != nil { - return r, nil - } - case <-ctx.Done(): - return nil, ctx.Err() - } - } - return nil, nil -} - -func (s *symbolSearcher) searchOne(ctx context.Context, c pkgDistance, symbols map[string]bool) (*pkg, error) { - if ctx.Err() != nil { - return nil, ctx.Err() - } - // If we're considering the package under test from an x_test, load the - // test variant. - includeTest := s.xtest && c.pkg.dir == s.srcDir - _, exports, err := s.loadExports(ctx, c.pkg, includeTest) - if err != nil { - return nil, err - } - - exportsMap := make(map[string]bool, len(exports)) - for _, sym := range exports { - exportsMap[sym.Name] = true - } - for symbol := range symbols { - if !exportsMap[symbol] { - return nil, nil // no match - } - } - return c.pkg, nil -} - -// pkgIsCandidate reports whether pkg is a candidate for satisfying the -// finding which package pkgIdent in the file named by filename is trying -// to refer to. -// -// This check is purely lexical and is meant to be as fast as possible -// because it's run over all $GOPATH directories to filter out poor -// candidates in order to limit the CPU and I/O later parsing the -// exports in candidate packages. -// -// filename is the file being formatted. -// pkgIdent is the package being searched for, like "client" (if -// searching for "client.New") -func pkgIsCandidate(filename string, refs References, pkg *pkg) bool { - // Check "internal" and "vendor" visibility: - if !CanUse(filename, pkg.dir) { - return false - } - - // Speed optimization to minimize disk I/O: - // - // Use the matchesPath heuristic to filter to package paths that could - // reasonably match a dangling reference. - // - // This permits mismatch naming like directory "go-foo" being package "foo", - // or "pkg.v3" being "pkg", or directory - // "google.golang.org/api/cloudbilling/v1" being package "cloudbilling", but - // doesn't permit a directory "foo" to be package "bar", which is strongly - // discouraged anyway. There's no reason goimports needs to be slow just to - // accommodate that. - for pkgIdent := range refs { - if matchesPath(pkgIdent, pkg.importPathShort) { - return true - } - } - return false -} - -// CanUse reports whether the package in dir is usable from filename, -// respecting the Go "internal" and "vendor" visibility rules. -func CanUse(filename, dir string) bool { - // Fast path check, before any allocations. If it doesn't contain vendor - // or internal, it's not tricky: - // Note that this can false-negative on directories like "notinternal", - // but we check it correctly below. This is just a fast path. - if !strings.Contains(dir, "vendor") && !strings.Contains(dir, "internal") { - return true - } - - dirSlash := filepath.ToSlash(dir) - if !strings.Contains(dirSlash, "/vendor/") && !strings.Contains(dirSlash, "/internal/") && !strings.HasSuffix(dirSlash, "/internal") { - return true - } - // Vendor or internal directory only visible from children of parent. - // That means the path from the current directory to the target directory - // can contain ../vendor or ../internal but not ../foo/vendor or ../foo/internal - // or bar/vendor or bar/internal. - // After stripping all the leading ../, the only okay place to see vendor or internal - // is at the very beginning of the path. - absfile, err := filepath.Abs(filename) - if err != nil { - return false - } - absdir, err := filepath.Abs(dir) - if err != nil { - return false - } - rel, err := filepath.Rel(absfile, absdir) - if err != nil { - return false - } - relSlash := filepath.ToSlash(rel) - if i := strings.LastIndex(relSlash, "../"); i >= 0 { - relSlash = relSlash[i+len("../"):] - } - return !strings.Contains(relSlash, "/vendor/") && !strings.Contains(relSlash, "/internal/") && !strings.HasSuffix(relSlash, "/internal") -} - -// matchesPath reports whether ident may match a potential package name -// referred to by path, using heuristics to filter out unidiomatic package -// names. -// -// Specifically, it checks whether either of the last two '/'- or '\'-delimited -// path segments matches the identifier. The segment-matching heuristic must -// allow for various conventions around segment naming, including go-foo, -// foo-go, and foo.v3. To handle all of these, matching considers both (1) the -// entire segment, ignoring '-' and '.', as well as (2) the last subsegment -// separated by '-' or '.'. So the segment foo-go matches all of the following -// identifiers: foo, go, and foogo. All matches are case insensitive (for ASCII -// identifiers). -// -// See the docstring for [pkgIsCandidate] for an explanation of how this -// heuristic filters potential candidate packages. -func matchesPath(ident, path string) bool { - // Ignore case, for ASCII. - lowerIfASCII := func(b byte) byte { - if 'A' <= b && b <= 'Z' { - return b + ('a' - 'A') - } - return b - } - - // match reports whether path[start:end] matches ident, ignoring [.-]. - match := func(start, end int) bool { - ii := len(ident) - 1 // current byte in ident - pi := end - 1 // current byte in path - for ; pi >= start && ii >= 0; pi-- { - pb := path[pi] - if pb == '-' || pb == '.' { - continue - } - pb = lowerIfASCII(pb) - ib := lowerIfASCII(ident[ii]) - if pb != ib { - return false - } - ii-- - } - return ii < 0 && pi < start // all bytes matched - } - - // segmentEnd and subsegmentEnd hold the end points of the current segment - // and subsegment intervals. - segmentEnd := len(path) - subsegmentEnd := len(path) - - // Count slashes; we only care about the last two segments. - nslash := 0 - - for i := len(path) - 1; i >= 0; i-- { - switch b := path[i]; b { - // TODO(rfindley): we handle backlashes here only because the previous - // heuristic handled backslashes. This is perhaps overly defensive, but is - // the result of many lessons regarding Chesterton's fence and the - // goimports codebase. - // - // However, this function is only ever called with something called an - // 'importPath'. Is it possible that this is a real import path, and - // therefore we need only consider forward slashes? - case '/', '\\': - if match(i+1, segmentEnd) || match(i+1, subsegmentEnd) { - return true - } - nslash++ - if nslash == 2 { - return false // did not match above - } - segmentEnd, subsegmentEnd = i, i // reset - case '-', '.': - if match(i+1, subsegmentEnd) { - return true - } - subsegmentEnd = i - } - } - return match(0, segmentEnd) || match(0, subsegmentEnd) -} - -type visitFn func(node ast.Node) ast.Visitor - -func (fn visitFn) Visit(node ast.Node) ast.Visitor { - return fn(node) -} - -func symbolNameSet(symbols []stdlib.Symbol) map[string]bool { - names := make(map[string]bool) - for _, sym := range symbols { - switch sym.Kind { - case stdlib.Const, stdlib.Var, stdlib.Type, stdlib.Func: - names[sym.Name] = true - } - } - return names -} diff --git a/vendor/golang.org/x/tools/internal/imports/imports.go b/vendor/golang.org/x/tools/internal/imports/imports.go deleted file mode 100644 index b5f5218b..00000000 --- a/vendor/golang.org/x/tools/internal/imports/imports.go +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package imports implements a Go pretty-printer (like package "go/format") -// that also adds or removes import statements as necessary. -package imports - -import ( - "bufio" - "bytes" - "context" - "fmt" - "go/ast" - "go/format" - "go/parser" - "go/printer" - "go/token" - "io" - "regexp" - "strconv" - "strings" - - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/internal/event" -) - -// Options is golang.org/x/tools/imports.Options with extra internal-only options. -type Options struct { - Env *ProcessEnv // The environment to use. Note: this contains the cached module and filesystem state. - - // LocalPrefix is a comma-separated string of import path prefixes, which, if - // set, instructs Process to sort the import paths with the given prefixes - // into another group after 3rd-party packages. - LocalPrefix string - - Fragment bool // Accept fragment of a source file (no package statement) - AllErrors bool // Report all errors (not just the first 10 on different lines) - - Comments bool // Print comments (true if nil *Options provided) - TabIndent bool // Use tabs for indent (true if nil *Options provided) - TabWidth int // Tab width (8 if nil *Options provided) - - FormatOnly bool // Disable the insertion and deletion of imports -} - -// Process implements golang.org/x/tools/imports.Process with explicit context in opt.Env. -func Process(filename string, src []byte, opt *Options) (formatted []byte, err error) { - fileSet := token.NewFileSet() - var parserMode parser.Mode - if opt.Comments { - parserMode |= parser.ParseComments - } - if opt.AllErrors { - parserMode |= parser.AllErrors - } - file, adjust, err := parse(fileSet, filename, src, parserMode, opt.Fragment) - if err != nil { - return nil, err - } - - if !opt.FormatOnly { - if err := fixImports(fileSet, file, filename, opt.Env); err != nil { - return nil, err - } - } - return formatFile(fileSet, file, src, adjust, opt) -} - -// FixImports returns a list of fixes to the imports that, when applied, -// will leave the imports in the same state as Process. src and opt must -// be specified. -// -// Note that filename's directory influences which imports can be chosen, -// so it is important that filename be accurate. -func FixImports(ctx context.Context, filename string, src []byte, goroot string, logf func(string, ...any), source Source) (fixes []*ImportFix, err error) { - ctx, done := event.Start(ctx, "imports.FixImports") - defer done() - - fileSet := token.NewFileSet() - // TODO(rfindley): these default values for ParseComments and AllErrors were - // extracted from gopls, but are they even needed? - file, _, err := parse(fileSet, filename, src, parser.ParseComments|parser.AllErrors, true) - if err != nil { - return nil, err - } - - return getFixesWithSource(ctx, fileSet, file, filename, goroot, logf, source) -} - -// ApplyFixes applies all of the fixes to the file and formats it. extraMode -// is added in when parsing the file. src and opts must be specified, but no -// env is needed. -func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options, extraMode parser.Mode) (formatted []byte, err error) { - // Don't use parse() -- we don't care about fragments or statement lists - // here, and we need to work with unparsable files. - fileSet := token.NewFileSet() - parserMode := parser.SkipObjectResolution - if opt.Comments { - parserMode |= parser.ParseComments - } - if opt.AllErrors { - parserMode |= parser.AllErrors - } - parserMode |= extraMode - - file, err := parser.ParseFile(fileSet, filename, src, parserMode) - if file == nil { - return nil, err - } - - // Apply the fixes to the file. - apply(fileSet, file, fixes) - - return formatFile(fileSet, file, src, nil, opt) -} - -// formatFile formats the file syntax tree. -// It may mutate the token.FileSet and the ast.File. -// -// If an adjust function is provided, it is called after formatting -// with the original source (formatFile's src parameter) and the -// formatted file, and returns the postpocessed result. -func formatFile(fset *token.FileSet, file *ast.File, src []byte, adjust func(orig []byte, src []byte) []byte, opt *Options) ([]byte, error) { - mergeImports(file) - sortImports(opt.LocalPrefix, fset.File(file.FileStart), file) - var spacesBefore []string // import paths we need spaces before - for _, impSection := range astutil.Imports(fset, file) { - // Within each block of contiguous imports, see if any - // import lines are in different group numbers. If so, - // we'll need to put a space between them so it's - // compatible with gofmt. - lastGroup := -1 - for _, importSpec := range impSection { - importPath, _ := strconv.Unquote(importSpec.Path.Value) - groupNum := importGroup(opt.LocalPrefix, importPath) - if groupNum != lastGroup && lastGroup != -1 { - spacesBefore = append(spacesBefore, importPath) - } - lastGroup = groupNum - } - - } - - printerMode := printer.UseSpaces - if opt.TabIndent { - printerMode |= printer.TabIndent - } - printConfig := &printer.Config{Mode: printerMode, Tabwidth: opt.TabWidth} - - var buf bytes.Buffer - err := printConfig.Fprint(&buf, fset, file) - if err != nil { - return nil, err - } - out := buf.Bytes() - if adjust != nil { - out = adjust(src, out) - } - if len(spacesBefore) > 0 { - out, err = addImportSpaces(bytes.NewReader(out), spacesBefore) - if err != nil { - return nil, err - } - } - - out, err = format.Source(out) - if err != nil { - return nil, err - } - return out, nil -} - -// parse parses src, which was read from filename, -// as a Go source file or statement list. -func parse(fset *token.FileSet, filename string, src []byte, parserMode parser.Mode, fragment bool) (*ast.File, func(orig, src []byte) []byte, error) { - if parserMode&parser.SkipObjectResolution != 0 { - panic("legacy ast.Object resolution is required") - } - - // Try as whole source file. - file, err := parser.ParseFile(fset, filename, src, parserMode) - if err == nil { - return file, nil, nil - } - // If the error is that the source file didn't begin with a - // package line and we accept fragmented input, fall through to - // try as a source fragment. Stop and return on any other error. - if !fragment || !strings.Contains(err.Error(), "expected 'package'") { - return nil, nil, err - } - - // If this is a declaration list, make it a source file - // by inserting a package clause. - // Insert using a ;, not a newline, so that parse errors are on - // the correct line. - const prefix = "package main;" - psrc := append([]byte(prefix), src...) - file, err = parser.ParseFile(fset, filename, psrc, parserMode) - if err == nil { - // Gofmt will turn the ; into a \n. - // Do that ourselves now and update the file contents, - // so that positions and line numbers are correct going forward. - psrc[len(prefix)-1] = '\n' - fset.File(file.Package).SetLinesForContent(psrc) - - // If a main function exists, we will assume this is a main - // package and leave the file. - if containsMainFunc(file) { - return file, nil, nil - } - - adjust := func(orig, src []byte) []byte { - // Remove the package clause. - src = src[len(prefix):] - return matchSpace(orig, src) - } - return file, adjust, nil - } - // If the error is that the source file didn't begin with a - // declaration, fall through to try as a statement list. - // Stop and return on any other error. - if !strings.Contains(err.Error(), "expected declaration") { - return nil, nil, err - } - - // If this is a statement list, make it a source file - // by inserting a package clause and turning the list - // into a function body. This handles expressions too. - // Insert using a ;, not a newline, so that the line numbers - // in fsrc match the ones in src. - fsrc := append(append([]byte("package p; func _() {"), src...), '}') - file, err = parser.ParseFile(fset, filename, fsrc, parserMode) - if err == nil { - adjust := func(orig, src []byte) []byte { - // Remove the wrapping. - // Gofmt has turned the ; into a \n\n. - src = src[len("package p\n\nfunc _() {"):] - src = src[:len(src)-len("}\n")] - // Gofmt has also indented the function body one level. - // Remove that indent. - src = bytes.ReplaceAll(src, []byte("\n\t"), []byte("\n")) - return matchSpace(orig, src) - } - return file, adjust, nil - } - - // Failed, and out of options. - return nil, nil, err -} - -// containsMainFunc checks if a file contains a function declaration with the -// function signature 'func main()' -func containsMainFunc(file *ast.File) bool { - for _, decl := range file.Decls { - if f, ok := decl.(*ast.FuncDecl); ok { - if f.Name.Name != "main" { - continue - } - - if len(f.Type.Params.List) != 0 { - continue - } - - if f.Type.Results != nil && len(f.Type.Results.List) != 0 { - continue - } - - return true - } - } - - return false -} - -func cutSpace(b []byte) (before, middle, after []byte) { - i := 0 - for i < len(b) && (b[i] == ' ' || b[i] == '\t' || b[i] == '\n') { - i++ - } - j := len(b) - for j > 0 && (b[j-1] == ' ' || b[j-1] == '\t' || b[j-1] == '\n') { - j-- - } - if i <= j { - return b[:i], b[i:j], b[j:] - } - return nil, nil, b[j:] -} - -// matchSpace reformats src to use the same space context as orig. -// 1. If orig begins with blank lines, matchSpace inserts them at the beginning of src. -// 2. matchSpace copies the indentation of the first non-blank line in orig -// to every non-blank line in src. -// 3. matchSpace copies the trailing space from orig and uses it in place -// of src's trailing space. -func matchSpace(orig []byte, src []byte) []byte { - before, _, after := cutSpace(orig) - i := bytes.LastIndex(before, []byte{'\n'}) - before, indent := before[:i+1], before[i+1:] - - _, src, _ = cutSpace(src) - - var b bytes.Buffer - b.Write(before) - for len(src) > 0 { - line := src - if i := bytes.IndexByte(line, '\n'); i >= 0 { - line, src = line[:i+1], line[i+1:] - } else { - src = nil - } - if len(line) > 0 && line[0] != '\n' { // not blank - b.Write(indent) - } - b.Write(line) - } - b.Write(after) - return b.Bytes() -} - -var impLine = regexp.MustCompile(`^\s+(?:[\w\.]+\s+)?"(.+?)"`) - -func addImportSpaces(r io.Reader, breaks []string) ([]byte, error) { - var out bytes.Buffer - in := bufio.NewReader(r) - inImports := false - done := false - for { - s, err := in.ReadString('\n') - if err == io.EOF { - break - } else if err != nil { - return nil, err - } - - if !inImports && !done && strings.HasPrefix(s, "import") { - inImports = true - } - if inImports && (strings.HasPrefix(s, "var") || - strings.HasPrefix(s, "func") || - strings.HasPrefix(s, "const") || - strings.HasPrefix(s, "type")) { - done = true - inImports = false - } - if inImports && len(breaks) > 0 { - if m := impLine.FindStringSubmatch(s); m != nil { - if m[1] == breaks[0] { - out.WriteByte('\n') - breaks = breaks[1:] - } - } - } - - fmt.Fprint(&out, s) - } - return out.Bytes(), nil -} diff --git a/vendor/golang.org/x/tools/internal/imports/mod.go b/vendor/golang.org/x/tools/internal/imports/mod.go deleted file mode 100644 index df94ec81..00000000 --- a/vendor/golang.org/x/tools/internal/imports/mod.go +++ /dev/null @@ -1,841 +0,0 @@ -// Copyright 2019 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 imports - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "os" - "path" - "path/filepath" - "regexp" - "slices" - "sort" - "strconv" - "strings" - - "golang.org/x/mod/module" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/gopathwalk" - "golang.org/x/tools/internal/stdlib" -) - -// Notes(rfindley): ModuleResolver appears to be heavily optimized for scanning -// as fast as possible, which is desirable for a call to goimports from the -// command line, but it doesn't work as well for gopls, where it suffers from -// slow startup (golang/go#44863) and intermittent hanging (golang/go#59216), -// both caused by populating the cache, albeit in slightly different ways. -// -// A high level list of TODOs: -// - Optimize the scan itself, as there is some redundancy statting and -// reading go.mod files. -// - Invert the relationship between ProcessEnv and Resolver (see the -// docstring of ProcessEnv). -// - Make it easier to use an external resolver implementation. -// -// Smaller TODOs are annotated in the code below. - -// ModuleResolver implements the Resolver interface for a workspace using -// modules. -// -// A goal of the ModuleResolver is to invoke the Go command as little as -// possible. To this end, it runs the Go command only for listing module -// information (i.e. `go list -m -e -json ...`). Package scanning, the process -// of loading package information for the modules, is implemented internally -// via the scan method. -// -// It has two types of state: the state derived from the go command, which -// is populated by init, and the state derived from scans, which is populated -// via scan. A root is considered scanned if it has been walked to discover -// directories. However, if the scan did not require additional information -// from the directory (such as package name or exports), the directory -// information itself may be partially populated. It will be lazily filled in -// as needed by scans, using the scanCallback. -type ModuleResolver struct { - env *ProcessEnv - - // Module state, populated during construction - dummyVendorMod *gocommand.ModuleJSON // if vendoring is enabled, a pseudo-module to represent the /vendor directory - moduleCacheDir string // GOMODCACHE, inferred from GOPATH if unset - roots []gopathwalk.Root // roots to scan, in approximate order of importance - mains []*gocommand.ModuleJSON // main modules - mainByDir map[string]*gocommand.ModuleJSON // module information by dir, to join with roots - modsByModPath []*gocommand.ModuleJSON // all modules, ordered by # of path components in their module path - modsByDir []*gocommand.ModuleJSON // ...or by the number of path components in their Dir. - - // Scanning state, populated by scan - - // scanSema prevents concurrent scans, and guards scannedRoots and the cache - // fields below (though the caches themselves are concurrency safe). - // Receive to acquire, send to release. - scanSema chan struct{} - scannedRoots map[gopathwalk.Root]bool // if true, root has been walked - - // Caches of directory info, populated by scans and scan callbacks - // - // moduleCacheCache stores cached information about roots in the module - // cache, which are immutable and therefore do not need to be invalidated. - // - // otherCache stores information about all other roots (even GOROOT), which - // may change. - moduleCacheCache *DirInfoCache - otherCache *DirInfoCache -} - -// newModuleResolver returns a new module-aware goimports resolver. -// -// Note: use caution when modifying this constructor: changes must also be -// reflected in ModuleResolver.ClearForNewScan. -func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleResolver, error) { - r := &ModuleResolver{ - env: e, - scanSema: make(chan struct{}, 1), - } - r.scanSema <- struct{}{} // release - - goenv, err := r.env.goEnv() - if err != nil { - return nil, err - } - - // TODO(rfindley): can we refactor to share logic with r.env.invokeGo? - inv := gocommand.Invocation{ - BuildFlags: r.env.BuildFlags, - ModFlag: r.env.ModFlag, - Env: r.env.env(), - Logf: r.env.Logf, - WorkingDir: r.env.WorkingDir, - } - - vendorEnabled := false - var mainModVendor *gocommand.ModuleJSON // for module vendoring - var mainModsVendor []*gocommand.ModuleJSON // for workspace vendoring - - goWork := r.env.Env["GOWORK"] - if len(goWork) == 0 { - // TODO(rfindley): VendorEnabled runs the go command to get GOFLAGS, but - // they should be available from the ProcessEnv. Can we avoid the redundant - // invocation? - vendorEnabled, mainModVendor, err = gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner) - if err != nil { - return nil, err - } - } else { - vendorEnabled, mainModsVendor, err = gocommand.WorkspaceVendorEnabled(context.Background(), inv, r.env.GocmdRunner) - if err != nil { - return nil, err - } - } - - if vendorEnabled { - if mainModVendor != nil { - // Module vendor mode is on, so all the non-Main modules are irrelevant, - // and we need to search /vendor for everything. - r.mains = []*gocommand.ModuleJSON{mainModVendor} - r.dummyVendorMod = &gocommand.ModuleJSON{ - Path: "", - Dir: filepath.Join(mainModVendor.Dir, "vendor"), - } - r.modsByModPath = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod} - r.modsByDir = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod} - } else { - // Workspace vendor mode is on, so all the non-Main modules are irrelevant, - // and we need to search /vendor for everything. - r.mains = mainModsVendor - r.dummyVendorMod = &gocommand.ModuleJSON{ - Path: "", - Dir: filepath.Join(filepath.Dir(goWork), "vendor"), - } - r.modsByModPath = append(slices.Clone(mainModsVendor), r.dummyVendorMod) - r.modsByDir = append(slices.Clone(mainModsVendor), r.dummyVendorMod) - } - } else { - // Vendor mode is off, so run go list -m ... to find everything. - err := r.initAllMods() - // We expect an error when running outside of a module with - // GO111MODULE=on. Other errors are fatal. - if err != nil { - if errMsg := err.Error(); !strings.Contains(errMsg, "working directory is not part of a module") && !strings.Contains(errMsg, "go.mod file not found") { - return nil, err - } - } - } - - r.moduleCacheDir = gomodcacheForEnv(goenv) - if r.moduleCacheDir == "" { - return nil, fmt.Errorf("cannot resolve GOMODCACHE") - } - - sort.Slice(r.modsByModPath, func(i, j int) bool { - count := func(x int) int { - return strings.Count(r.modsByModPath[x].Path, "/") - } - return count(j) < count(i) // descending order - }) - sort.Slice(r.modsByDir, func(i, j int) bool { - count := func(x int) int { - return strings.Count(r.modsByDir[x].Dir, string(filepath.Separator)) - } - return count(j) < count(i) // descending order - }) - - r.roots = []gopathwalk.Root{} - if goenv["GOROOT"] != "" { // "" happens in tests - r.roots = append(r.roots, gopathwalk.Root{Path: filepath.Join(goenv["GOROOT"], "/src"), Type: gopathwalk.RootGOROOT}) - } - r.mainByDir = make(map[string]*gocommand.ModuleJSON) - for _, main := range r.mains { - r.roots = append(r.roots, gopathwalk.Root{Path: main.Dir, Type: gopathwalk.RootCurrentModule}) - r.mainByDir[main.Dir] = main - } - if vendorEnabled { - r.roots = append(r.roots, gopathwalk.Root{Path: r.dummyVendorMod.Dir, Type: gopathwalk.RootOther}) - } else { - addDep := func(mod *gocommand.ModuleJSON) { - if mod.Replace == nil { - // This is redundant with the cache, but we'll skip it cheaply enough - // when we encounter it in the module cache scan. - // - // Including it at a lower index in r.roots than the module cache dir - // helps prioritize matches from within existing dependencies. - r.roots = append(r.roots, gopathwalk.Root{Path: mod.Dir, Type: gopathwalk.RootModuleCache}) - } else { - r.roots = append(r.roots, gopathwalk.Root{Path: mod.Dir, Type: gopathwalk.RootOther}) - } - } - // Walk dependent modules before scanning the full mod cache, direct deps first. - for _, mod := range r.modsByModPath { - if !mod.Indirect && !mod.Main { - addDep(mod) - } - } - for _, mod := range r.modsByModPath { - if mod.Indirect && !mod.Main { - addDep(mod) - } - } - // If provided, share the moduleCacheCache. - // - // TODO(rfindley): The module cache is immutable. However, the loaded - // exports do depend on GOOS and GOARCH. Fortunately, the - // ProcessEnv.buildContext does not adjust these from build.DefaultContext - // (even though it should). So for now, this is OK to share, but we need to - // add logic for handling GOOS/GOARCH. - r.moduleCacheCache = moduleCacheCache - r.roots = append(r.roots, gopathwalk.Root{Path: r.moduleCacheDir, Type: gopathwalk.RootModuleCache}) - } - - r.scannedRoots = map[gopathwalk.Root]bool{} - if r.moduleCacheCache == nil { - r.moduleCacheCache = NewDirInfoCache() - } - r.otherCache = NewDirInfoCache() - return r, nil -} - -// gomodcacheForEnv returns the GOMODCACHE value to use based on the given env -// map, which must have GOMODCACHE and GOPATH populated. -// -// TODO(rfindley): this is defensive refactoring. -// 1. Is this even relevant anymore? Can't we just read GOMODCACHE. -// 2. Use this to separate module cache scanning from other scanning. -func gomodcacheForEnv(goenv map[string]string) string { - if gmc := goenv["GOMODCACHE"]; gmc != "" { - // golang/go#67156: ensure that the module cache is clean, since it is - // assumed as a prefix to directories scanned by gopathwalk, which are - // themselves clean. - return filepath.Clean(gmc) - } - gopaths := filepath.SplitList(goenv["GOPATH"]) - if len(gopaths) == 0 { - return "" - } - return filepath.Join(gopaths[0], "/pkg/mod") -} - -func (r *ModuleResolver) initAllMods() error { - stdout, err := r.env.invokeGo(context.TODO(), "list", "-m", "-e", "-json", "...") - if err != nil { - return err - } - for dec := json.NewDecoder(stdout); dec.More(); { - mod := &gocommand.ModuleJSON{} - if err := dec.Decode(mod); err != nil { - return err - } - if mod.Dir == "" { - r.env.logf("module %v has not been downloaded and will be ignored", mod.Path) - // Can't do anything with a module that's not downloaded. - continue - } - // golang/go#36193: the go command doesn't always clean paths. - mod.Dir = filepath.Clean(mod.Dir) - r.modsByModPath = append(r.modsByModPath, mod) - r.modsByDir = append(r.modsByDir, mod) - if mod.Main { - r.mains = append(r.mains, mod) - } - } - return nil -} - -// ClearForNewScan invalidates the last scan. -// -// It preserves the set of roots, but forgets about the set of directories. -// Though it forgets the set of module cache directories, it remembers their -// contents, since they are assumed to be immutable. -func (r *ModuleResolver) ClearForNewScan() Resolver { - <-r.scanSema // acquire r, to guard scannedRoots - r2 := &ModuleResolver{ - env: r.env, - dummyVendorMod: r.dummyVendorMod, - moduleCacheDir: r.moduleCacheDir, - roots: r.roots, - mains: r.mains, - mainByDir: r.mainByDir, - modsByModPath: r.modsByModPath, - - scanSema: make(chan struct{}, 1), - scannedRoots: make(map[gopathwalk.Root]bool), - otherCache: NewDirInfoCache(), - moduleCacheCache: r.moduleCacheCache, - } - r2.scanSema <- struct{}{} // r2 must start released - // Invalidate root scans. We don't need to invalidate module cache roots, - // because they are immutable. - // (We don't support a use case where GOMODCACHE is cleaned in the middle of - // e.g. a gopls session: the user must restart gopls to get accurate - // imports.) - // - // Scanning for new directories in GOMODCACHE should be handled elsewhere, - // via a call to ScanModuleCache. - for _, root := range r.roots { - if root.Type == gopathwalk.RootModuleCache && r.scannedRoots[root] { - r2.scannedRoots[root] = true - } - } - r.scanSema <- struct{}{} // release r - return r2 -} - -// ClearModuleInfo invalidates resolver state that depends on go.mod file -// contents (essentially, the output of go list -m -json ...). -// -// Notably, it does not forget directory contents, which are reset -// asynchronously via ClearForNewScan. -// -// If the ProcessEnv is a GOPATH environment, ClearModuleInfo is a no op. -// -// TODO(rfindley): move this to a new env.go, consolidating ProcessEnv methods. -func (e *ProcessEnv) ClearModuleInfo() { - if r, ok := e.resolver.(*ModuleResolver); ok { - resolver, err := newModuleResolver(e, e.ModCache) - if err != nil { - e.resolver = nil - e.resolverErr = err - return - } - - <-r.scanSema // acquire (guards caches) - resolver.moduleCacheCache = r.moduleCacheCache - resolver.otherCache = r.otherCache - r.scanSema <- struct{}{} // release - - e.UpdateResolver(resolver) - } -} - -// UpdateResolver sets the resolver for the ProcessEnv to use in imports -// operations. Only for use with the result of [Resolver.ClearForNewScan]. -// -// TODO(rfindley): this awkward API is a result of the (arguably) inverted -// relationship between configuration and state described in the doc comment -// for [ProcessEnv]. -func (e *ProcessEnv) UpdateResolver(r Resolver) { - e.resolver = r - e.resolverErr = nil -} - -// findPackage returns the module and directory from within the main modules -// and their dependencies that contains the package at the given import path, -// or returns nil, "" if no module is in scope. -func (r *ModuleResolver) findPackage(importPath string) (*gocommand.ModuleJSON, string) { - // This can't find packages in the stdlib, but that's harmless for all - // the existing code paths. - for _, m := range r.modsByModPath { - if !strings.HasPrefix(importPath, m.Path) { - continue - } - pathInModule := importPath[len(m.Path):] - pkgDir := filepath.Join(m.Dir, pathInModule) - if r.dirIsNestedModule(pkgDir, m) { - continue - } - - if info, ok := r.cacheLoad(pkgDir); ok { - if loaded, err := info.reachedStatus(nameLoaded); loaded { - if err != nil { - continue // No package in this dir. - } - return m, pkgDir - } - if scanned, err := info.reachedStatus(directoryScanned); scanned && err != nil { - continue // Dir is unreadable, etc. - } - // This is slightly wrong: a directory doesn't have to have an - // importable package to count as a package for package-to-module - // resolution. package main or _test files should count but - // don't. - // TODO(heschi): fix this. - if _, err := r.cachePackageName(info); err == nil { - return m, pkgDir - } - } - - // Not cached. Read the filesystem. - pkgFiles, err := os.ReadDir(pkgDir) - if err != nil { - continue - } - // A module only contains a package if it has buildable go - // files in that directory. If not, it could be provided by an - // outer module. See #29736. - for _, fi := range pkgFiles { - if ok, _ := r.env.matchFile(pkgDir, fi.Name()); ok { - return m, pkgDir - } - } - } - return nil, "" -} - -func (r *ModuleResolver) cacheLoad(dir string) (directoryPackageInfo, bool) { - if info, ok := r.moduleCacheCache.Load(dir); ok { - return info, ok - } - return r.otherCache.Load(dir) -} - -func (r *ModuleResolver) cacheStore(info directoryPackageInfo) { - if info.rootType == gopathwalk.RootModuleCache { - r.moduleCacheCache.Store(info.dir, info) - } else { - r.otherCache.Store(info.dir, info) - } -} - -// cachePackageName caches the package name for a dir already in the cache. -func (r *ModuleResolver) cachePackageName(info directoryPackageInfo) (string, error) { - if info.rootType == gopathwalk.RootModuleCache { - return r.moduleCacheCache.CachePackageName(info) - } - return r.otherCache.CachePackageName(info) -} - -func (r *ModuleResolver) cacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []stdlib.Symbol, error) { - if info.rootType == gopathwalk.RootModuleCache { - return r.moduleCacheCache.CacheExports(ctx, env, info) - } - return r.otherCache.CacheExports(ctx, env, info) -} - -// findModuleByDir returns the module that contains dir, or nil if no such -// module is in scope. -func (r *ModuleResolver) findModuleByDir(dir string) *gocommand.ModuleJSON { - // This is quite tricky and may not be correct. dir could be: - // - a package in the main module. - // - a replace target underneath the main module's directory. - // - a nested module in the above. - // - a replace target somewhere totally random. - // - a nested module in the above. - // - in the mod cache. - // - in /vendor/ in -mod=vendor mode. - // - nested module? Dunno. - // Rumor has it that replace targets cannot contain other replace targets. - // - // Note that it is critical here that modsByDir is sorted to have deeper dirs - // first. This ensures that findModuleByDir finds the innermost module. - // See also golang/go#56291. - for _, m := range r.modsByDir { - if !strings.HasPrefix(dir, m.Dir) { - continue - } - - if r.dirIsNestedModule(dir, m) { - continue - } - - return m - } - return nil -} - -// dirIsNestedModule reports if dir is contained in a nested module underneath -// mod, not actually in mod. -func (r *ModuleResolver) dirIsNestedModule(dir string, mod *gocommand.ModuleJSON) bool { - if !strings.HasPrefix(dir, mod.Dir) { - return false - } - if r.dirInModuleCache(dir) { - // Nested modules in the module cache are pruned, - // so it cannot be a nested module. - return false - } - if mod != nil && mod == r.dummyVendorMod { - // The /vendor pseudomodule is flattened and doesn't actually count. - return false - } - modDir, _ := r.modInfo(dir) - if modDir == "" { - return false - } - return modDir != mod.Dir -} - -func readModName(modFile string) string { - modBytes, err := os.ReadFile(modFile) - if err != nil { - return "" - } - return modulePath(modBytes) -} - -func (r *ModuleResolver) modInfo(dir string) (modDir, modName string) { - if r.dirInModuleCache(dir) { - if matches := modCacheRegexp.FindStringSubmatch(dir); len(matches) == 3 { - index := strings.Index(dir, matches[1]+"@"+matches[2]) - modDir := filepath.Join(dir[:index], matches[1]+"@"+matches[2]) - return modDir, readModName(filepath.Join(modDir, "go.mod")) - } - } - for { - if info, ok := r.cacheLoad(dir); ok { - return info.moduleDir, info.moduleName - } - f := filepath.Join(dir, "go.mod") - info, err := os.Stat(f) - if err == nil && !info.IsDir() { - return dir, readModName(f) - } - - d := filepath.Dir(dir) - if len(d) >= len(dir) { - return "", "" // reached top of file system, no go.mod - } - dir = d - } -} - -func (r *ModuleResolver) dirInModuleCache(dir string) bool { - if r.moduleCacheDir == "" { - return false - } - return strings.HasPrefix(dir, r.moduleCacheDir) -} - -func (r *ModuleResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) { - names := map[string]string{} - for _, path := range importPaths { - // TODO(rfindley): shouldn't this use the dirInfoCache? - _, packageDir := r.findPackage(path) - if packageDir == "" { - continue - } - name, err := packageDirToName(packageDir) - if err != nil { - continue - } - names[path] = name - } - return names, nil -} - -func (r *ModuleResolver) scan(ctx context.Context, callback *scanCallback) error { - ctx, done := event.Start(ctx, "imports.ModuleResolver.scan") - defer done() - - processDir := func(info directoryPackageInfo) { - // Skip this directory if we were not able to get the package information successfully. - if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil { - return - } - pkg, err := r.canonicalize(info) - if err != nil { - return - } - if !callback.dirFound(pkg) { - return - } - - pkg.packageName, err = r.cachePackageName(info) - if err != nil { - return - } - if !callback.packageNameLoaded(pkg) { - return - } - - _, exports, err := r.loadExports(ctx, pkg, false) - if err != nil { - return - } - callback.exportsLoaded(pkg, exports) - } - - // Start processing everything in the cache, and listen for the new stuff - // we discover in the walk below. - stop1 := r.moduleCacheCache.ScanAndListen(ctx, processDir) - defer stop1() - stop2 := r.otherCache.ScanAndListen(ctx, processDir) - defer stop2() - - // We assume cached directories are fully cached, including all their - // children, and have not changed. We can skip them. - skip := func(root gopathwalk.Root, dir string) bool { - if r.env.SkipPathInScan != nil && root.Type == gopathwalk.RootCurrentModule { - if root.Path == dir { - return false - } - - if r.env.SkipPathInScan(filepath.Clean(dir)) { - return true - } - } - - info, ok := r.cacheLoad(dir) - if !ok { - return false - } - // This directory can be skipped as long as we have already scanned it. - // Packages with errors will continue to have errors, so there is no need - // to rescan them. - packageScanned, _ := info.reachedStatus(directoryScanned) - return packageScanned - } - - add := func(root gopathwalk.Root, dir string) { - r.cacheStore(r.scanDirForPackage(root, dir)) - } - - // r.roots and the callback are not necessarily safe to use in the - // goroutine below. Process them eagerly. - roots := filterRoots(r.roots, callback.rootFound) - // We can't cancel walks, because we need them to finish to have a usable - // cache. Instead, run them in a separate goroutine and detach. - scanDone := make(chan struct{}) - go func() { - select { - case <-ctx.Done(): - return - case <-r.scanSema: // acquire - } - defer func() { r.scanSema <- struct{}{} }() // release - // We have the lock on r.scannedRoots, and no other scans can run. - for _, root := range roots { - if ctx.Err() != nil { - return - } - - if r.scannedRoots[root] { - continue - } - gopathwalk.WalkSkip([]gopathwalk.Root{root}, add, skip, gopathwalk.Options{Logf: r.env.Logf, ModulesEnabled: true}) - r.scannedRoots[root] = true - } - close(scanDone) - }() - select { - case <-ctx.Done(): - case <-scanDone: - } - return nil -} - -func (r *ModuleResolver) scoreImportPath(ctx context.Context, path string) float64 { - if stdlib.HasPackage(path) { - return MaxRelevance - } - mod, _ := r.findPackage(path) - return modRelevance(mod) -} - -func modRelevance(mod *gocommand.ModuleJSON) float64 { - var relevance float64 - switch { - case mod == nil: // out of scope - return MaxRelevance - 4 - case mod.Indirect: - relevance = MaxRelevance - 3 - case !mod.Main: - relevance = MaxRelevance - 2 - default: - relevance = MaxRelevance - 1 // main module ties with stdlib - } - - _, versionString, ok := module.SplitPathVersion(mod.Path) - if ok { - index := strings.Index(versionString, "v") - if index == -1 { - return relevance - } - if versionNumber, err := strconv.ParseFloat(versionString[index+1:], 64); err == nil { - relevance += versionNumber / 1000 - } - } - - return relevance -} - -// canonicalize gets the result of canonicalizing the packages using the results -// of initializing the resolver from 'go list -m'. -func (r *ModuleResolver) canonicalize(info directoryPackageInfo) (*pkg, error) { - // Packages in GOROOT are already canonical, regardless of the std/cmd modules. - if info.rootType == gopathwalk.RootGOROOT { - return &pkg{ - importPathShort: info.nonCanonicalImportPath, - dir: info.dir, - packageName: path.Base(info.nonCanonicalImportPath), - relevance: MaxRelevance, - }, nil - } - - importPath := info.nonCanonicalImportPath - mod := r.findModuleByDir(info.dir) - // Check if the directory is underneath a module that's in scope. - if mod != nil { - // It is. If dir is the target of a replace directive, - // our guessed import path is wrong. Use the real one. - if mod.Dir == info.dir { - importPath = mod.Path - } else { - dirInMod := info.dir[len(mod.Dir)+len("/"):] - importPath = path.Join(mod.Path, filepath.ToSlash(dirInMod)) - } - } else if !strings.HasPrefix(importPath, info.moduleName) { - // The module's name doesn't match the package's import path. It - // probably needs a replace directive we don't have. - return nil, fmt.Errorf("package in %q is not valid without a replace statement", info.dir) - } - - res := &pkg{ - importPathShort: importPath, - dir: info.dir, - relevance: modRelevance(mod), - } - // We may have discovered a package that has a different version - // in scope already. Canonicalize to that one if possible. - if _, canonicalDir := r.findPackage(importPath); canonicalDir != "" { - res.dir = canonicalDir - } - return res, nil -} - -func (r *ModuleResolver) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []stdlib.Symbol, error) { - if info, ok := r.cacheLoad(pkg.dir); ok && !includeTest { - return r.cacheExports(ctx, r.env, info) - } - return loadExportsFromFiles(ctx, r.env, pkg.dir, includeTest) -} - -func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) directoryPackageInfo { - subdir := "" - if prefix := root.Path + string(filepath.Separator); strings.HasPrefix(dir, prefix) { - subdir = dir[len(prefix):] - } - importPath := filepath.ToSlash(subdir) - if strings.HasPrefix(importPath, "vendor/") { - // Only enter vendor directories if they're explicitly requested as a root. - return directoryPackageInfo{ - status: directoryScanned, - err: fmt.Errorf("unwanted vendor directory"), - } - } - switch root.Type { - case gopathwalk.RootCurrentModule: - importPath = path.Join(r.mainByDir[root.Path].Path, filepath.ToSlash(subdir)) - case gopathwalk.RootModuleCache: - matches := modCacheRegexp.FindStringSubmatch(subdir) - if len(matches) == 0 { - return directoryPackageInfo{ - status: directoryScanned, - err: fmt.Errorf("invalid module cache path: %v", subdir), - } - } - modPath, err := module.UnescapePath(filepath.ToSlash(matches[1])) - if err != nil { - r.env.logf("decoding module cache path %q: %v", subdir, err) - return directoryPackageInfo{ - status: directoryScanned, - err: fmt.Errorf("decoding module cache path %q: %v", subdir, err), - } - } - importPath = path.Join(modPath, filepath.ToSlash(matches[3])) - } - - modDir, modName := r.modInfo(dir) - result := directoryPackageInfo{ - status: directoryScanned, - dir: dir, - rootType: root.Type, - nonCanonicalImportPath: importPath, - moduleDir: modDir, - moduleName: modName, - } - if root.Type == gopathwalk.RootGOROOT { - // stdlib packages are always in scope, despite the confusing go.mod - return result - } - return result -} - -// modCacheRegexp splits a path in a module cache into module, module version, and package. -var modCacheRegexp = regexp.MustCompile(`(.*)@([^/\\]*)(.*)`) - -var ( - slashSlash = []byte("//") - moduleStr = []byte("module") -) - -// modulePath returns the module path from the gomod file text. -// If it cannot find a module path, it returns an empty string. -// It is tolerant of unrelated problems in the go.mod file. -// -// Copied from cmd/go/internal/modfile. -func modulePath(mod []byte) string { - for len(mod) > 0 { - line := mod - mod = nil - if i := bytes.IndexByte(line, '\n'); i >= 0 { - line, mod = line[:i], line[i+1:] - } - if i := bytes.Index(line, slashSlash); i >= 0 { - line = line[:i] - } - line = bytes.TrimSpace(line) - if !bytes.HasPrefix(line, moduleStr) { - continue - } - line = line[len(moduleStr):] - n := len(line) - line = bytes.TrimSpace(line) - if len(line) == n || len(line) == 0 { - continue - } - - if line[0] == '"' || line[0] == '`' { - p, err := strconv.Unquote(string(line)) - if err != nil { - return "" // malformed quoted string or multiline module path - } - return p - } - - return string(line) - } - return "" // missing module path -} diff --git a/vendor/golang.org/x/tools/internal/imports/mod_cache.go b/vendor/golang.org/x/tools/internal/imports/mod_cache.go deleted file mode 100644 index b96c9d4b..00000000 --- a/vendor/golang.org/x/tools/internal/imports/mod_cache.go +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright 2019 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 imports - -import ( - "context" - "fmt" - "path" - "path/filepath" - "strings" - "sync" - - "golang.org/x/mod/module" - "golang.org/x/tools/internal/gopathwalk" - "golang.org/x/tools/internal/stdlib" -) - -// To find packages to import, the resolver needs to know about all of -// the packages that could be imported. This includes packages that are -// already in modules that are in (1) the current module, (2) replace targets, -// and (3) packages in the module cache. Packages in (1) and (2) may change over -// time, as the client may edit the current module and locally replaced modules. -// The module cache (which includes all of the packages in (3)) can only -// ever be added to. -// -// The resolver can thus save state about packages in the module cache -// and guarantee that this will not change over time. To obtain information -// about new modules added to the module cache, the module cache should be -// rescanned. -// -// It is OK to serve information about modules that have been deleted, -// as they do still exist. -// TODO(suzmue): can we share information with the caller about -// what module needs to be downloaded to import this package? - -type directoryPackageStatus int - -const ( - _ directoryPackageStatus = iota - directoryScanned - nameLoaded - exportsLoaded -) - -// directoryPackageInfo holds (possibly incomplete) information about packages -// contained in a given directory. -type directoryPackageInfo struct { - // status indicates the extent to which this struct has been filled in. - status directoryPackageStatus - // err is non-nil when there was an error trying to reach status. - err error - - // Set when status >= directoryScanned. - - // dir is the absolute directory of this package. - dir string - rootType gopathwalk.RootType - // nonCanonicalImportPath is the package's expected import path. It may - // not actually be importable at that path. - nonCanonicalImportPath string - - // Module-related information. - moduleDir string // The directory that is the module root of this dir. - moduleName string // The module name that contains this dir. - - // Set when status >= nameLoaded. - - packageName string // the package name, as declared in the source. - - // Set when status >= exportsLoaded. - // TODO(rfindley): it's hard to see this, but exports depend implicitly on - // the default build context GOOS and GOARCH. - // - // We can make this explicit, and key exports by GOOS, GOARCH. - exports []stdlib.Symbol -} - -// reachedStatus returns true when info has a status at least target and any error associated with -// an attempt to reach target. -func (info *directoryPackageInfo) reachedStatus(target directoryPackageStatus) (bool, error) { - if info.err == nil { - return info.status >= target, nil - } - if info.status == target { - return true, info.err - } - return true, nil -} - -// DirInfoCache is a concurrency-safe map for storing information about -// directories that may contain packages. -// -// The information in this cache is built incrementally. Entries are initialized in scan. -// No new keys should be added in any other functions, as all directories containing -// packages are identified in scan. -// -// Other functions, including loadExports and findPackage, may update entries in this cache -// as they discover new things about the directory. -// -// The information in the cache is not expected to change for the cache's -// lifetime, so there is no protection against competing writes. Users should -// take care not to hold the cache across changes to the underlying files. -type DirInfoCache struct { - mu sync.Mutex - // dirs stores information about packages in directories, keyed by absolute path. - dirs map[string]*directoryPackageInfo - listeners map[*int]cacheListener -} - -func NewDirInfoCache() *DirInfoCache { - return &DirInfoCache{ - dirs: make(map[string]*directoryPackageInfo), - listeners: make(map[*int]cacheListener), - } -} - -type cacheListener func(directoryPackageInfo) - -// ScanAndListen calls listener on all the items in the cache, and on anything -// newly added. The returned stop function waits for all in-flight callbacks to -// finish and blocks new ones. -func (d *DirInfoCache) ScanAndListen(ctx context.Context, listener cacheListener) func() { - ctx, cancel := context.WithCancel(ctx) - - // Flushing out all the callbacks is tricky without knowing how many there - // are going to be. Setting an arbitrary limit makes it much easier. - const maxInFlight = 10 - sema := make(chan struct{}, maxInFlight) - for range maxInFlight { - sema <- struct{}{} - } - - cookie := new(int) // A unique ID we can use for the listener. - - // We can't hold mu while calling the listener. - d.mu.Lock() - var keys []string - for key := range d.dirs { - keys = append(keys, key) - } - d.listeners[cookie] = func(info directoryPackageInfo) { - select { - case <-ctx.Done(): - return - case <-sema: - } - listener(info) - sema <- struct{}{} - } - d.mu.Unlock() - - stop := func() { - cancel() - d.mu.Lock() - delete(d.listeners, cookie) - d.mu.Unlock() - for range maxInFlight { - <-sema - } - } - - // Process the pre-existing keys. - for _, k := range keys { - select { - case <-ctx.Done(): - return stop - default: - } - if v, ok := d.Load(k); ok { - listener(v) - } - } - - return stop -} - -// Store stores the package info for dir. -func (d *DirInfoCache) Store(dir string, info directoryPackageInfo) { - d.mu.Lock() - // TODO(rfindley, golang/go#59216): should we overwrite an existing entry? - // That seems incorrect as the cache should be idempotent. - _, old := d.dirs[dir] - d.dirs[dir] = &info - var listeners []cacheListener - for _, l := range d.listeners { - listeners = append(listeners, l) - } - d.mu.Unlock() - - if !old { - for _, l := range listeners { - l(info) - } - } -} - -// Load returns a copy of the directoryPackageInfo for absolute directory dir. -func (d *DirInfoCache) Load(dir string) (directoryPackageInfo, bool) { - d.mu.Lock() - defer d.mu.Unlock() - info, ok := d.dirs[dir] - if !ok { - return directoryPackageInfo{}, false - } - return *info, true -} - -// Keys returns the keys currently present in d. -func (d *DirInfoCache) Keys() (keys []string) { - d.mu.Lock() - defer d.mu.Unlock() - for key := range d.dirs { - keys = append(keys, key) - } - return keys -} - -func (d *DirInfoCache) CachePackageName(info directoryPackageInfo) (string, error) { - if loaded, err := info.reachedStatus(nameLoaded); loaded { - return info.packageName, err - } - if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil { - return "", fmt.Errorf("cannot read package name, scan error: %v", err) - } - info.packageName, info.err = packageDirToName(info.dir) - info.status = nameLoaded - d.Store(info.dir, info) - return info.packageName, info.err -} - -func (d *DirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []stdlib.Symbol, error) { - if reached, _ := info.reachedStatus(exportsLoaded); reached { - return info.packageName, info.exports, info.err - } - if reached, err := info.reachedStatus(nameLoaded); reached && err != nil { - return "", nil, err - } - info.packageName, info.exports, info.err = loadExportsFromFiles(ctx, env, info.dir, false) - if info.err == context.Canceled || info.err == context.DeadlineExceeded { - return info.packageName, info.exports, info.err - } - // The cache structure wants things to proceed linearly. We can skip a - // step here, but only if we succeed. - if info.status == nameLoaded || info.err == nil { - info.status = exportsLoaded - } else { - info.status = nameLoaded - } - d.Store(info.dir, info) - return info.packageName, info.exports, info.err -} - -// ScanModuleCache walks the given directory, which must be a GOMODCACHE value, -// for directory package information, storing the results in cache. -func ScanModuleCache(dir string, cache *DirInfoCache, logf func(string, ...any)) { - // Note(rfindley): it's hard to see, but this function attempts to implement - // just the side effects on cache of calling PrimeCache with a ProcessEnv - // that has the given dir as its GOMODCACHE. - // - // Teasing out the control flow, we see that we can avoid any handling of - // vendor/ and can infer module info entirely from the path, simplifying the - // logic here. - - root := gopathwalk.Root{ - Path: filepath.Clean(dir), - Type: gopathwalk.RootModuleCache, - } - - directoryInfo := func(root gopathwalk.Root, dir string) directoryPackageInfo { - // This is a copy of ModuleResolver.scanDirForPackage, trimmed down to - // logic that applies to a module cache directory. - - subdir := "" - if dir != root.Path { - subdir = dir[len(root.Path)+len("/"):] - } - - matches := modCacheRegexp.FindStringSubmatch(subdir) - if len(matches) == 0 { - return directoryPackageInfo{ - status: directoryScanned, - err: fmt.Errorf("invalid module cache path: %v", subdir), - } - } - modPath, err := module.UnescapePath(filepath.ToSlash(matches[1])) - if err != nil { - if logf != nil { - logf("decoding module cache path %q: %v", subdir, err) - } - return directoryPackageInfo{ - status: directoryScanned, - err: fmt.Errorf("decoding module cache path %q: %v", subdir, err), - } - } - importPath := path.Join(modPath, filepath.ToSlash(matches[3])) - index := strings.Index(dir, matches[1]+"@"+matches[2]) - modDir := filepath.Join(dir[:index], matches[1]+"@"+matches[2]) - modName := readModName(filepath.Join(modDir, "go.mod")) - return directoryPackageInfo{ - status: directoryScanned, - dir: dir, - rootType: root.Type, - nonCanonicalImportPath: importPath, - moduleDir: modDir, - moduleName: modName, - } - } - - add := func(root gopathwalk.Root, dir string) { - info := directoryInfo(root, dir) - cache.Store(info.dir, info) - } - - skip := func(_ gopathwalk.Root, dir string) bool { - // Skip directories that have already been scanned. - // - // Note that gopathwalk only adds "package" directories, which must contain - // a .go file, and all such package directories in the module cache are - // immutable. So if we can load a dir, it can be skipped. - info, ok := cache.Load(dir) - if !ok { - return false - } - packageScanned, _ := info.reachedStatus(directoryScanned) - return packageScanned - } - - gopathwalk.WalkSkip([]gopathwalk.Root{root}, add, skip, gopathwalk.Options{Logf: logf, ModulesEnabled: true}) -} diff --git a/vendor/golang.org/x/tools/internal/imports/sortimports.go b/vendor/golang.org/x/tools/internal/imports/sortimports.go deleted file mode 100644 index f390be90..00000000 --- a/vendor/golang.org/x/tools/internal/imports/sortimports.go +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Hacked up copy of go/ast/import.go -// Modified to use a single token.File in preference to a FileSet. - -package imports - -import ( - "go/ast" - "go/token" - "log" - "reflect" - "slices" - "sort" - "strconv" -) - -// sortImports sorts runs of consecutive import lines in import blocks in f. -// It also removes duplicate imports when it is possible to do so without data loss. -// -// It may mutate the token.File and the ast.File. -func sortImports(localPrefix string, tokFile *token.File, f *ast.File) { - for i, d := range f.Decls { - d, ok := d.(*ast.GenDecl) - if !ok || d.Tok != token.IMPORT { - // Not an import declaration, so we're done. - // Imports are always first. - break - } - - if len(d.Specs) == 0 { - // Empty import block, remove it. - f.Decls = slices.Delete(f.Decls, i, i+1) - } - - if !d.Lparen.IsValid() { - // Not a block: sorted by default. - continue - } - - // Identify and sort runs of specs on successive lines. - i := 0 - specs := d.Specs[:0] - for j, s := range d.Specs { - if j > i && tokFile.Line(s.Pos()) > 1+tokFile.Line(d.Specs[j-1].End()) { - // j begins a new run. End this one. - specs = append(specs, sortSpecs(localPrefix, tokFile, f, d.Specs[i:j])...) - i = j - } - } - specs = append(specs, sortSpecs(localPrefix, tokFile, f, d.Specs[i:])...) - d.Specs = specs - - // Deduping can leave a blank line before the rparen; clean that up. - // Ignore line directives. - if len(d.Specs) > 0 { - lastSpec := d.Specs[len(d.Specs)-1] - lastLine := tokFile.PositionFor(lastSpec.Pos(), false).Line - if rParenLine := tokFile.PositionFor(d.Rparen, false).Line; rParenLine > lastLine+1 { - tokFile.MergeLine(rParenLine - 1) // has side effects! - } - } - } -} - -// mergeImports merges all the import declarations into the first one. -// Taken from golang.org/x/tools/go/ast/astutil. -// This does not adjust line numbers properly -func mergeImports(f *ast.File) { - if len(f.Decls) <= 1 { - return - } - - // Merge all the import declarations into the first one. - var first *ast.GenDecl - for i := 0; i < len(f.Decls); i++ { - decl := f.Decls[i] - gen, ok := decl.(*ast.GenDecl) - if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") { - continue - } - if first == nil { - first = gen - continue // Don't touch the first one. - } - // We now know there is more than one package in this import - // declaration. Ensure that it ends up parenthesized. - first.Lparen = first.Pos() - // Move the imports of the other import declaration to the first one. - for _, spec := range gen.Specs { - updateBasicLitPos(spec.(*ast.ImportSpec).Path, first.Pos()) - first.Specs = append(first.Specs, spec) - } - f.Decls = slices.Delete(f.Decls, i, i+1) - i-- - } -} - -// declImports reports whether gen contains an import of path. -// Taken from golang.org/x/tools/go/ast/astutil. -func declImports(gen *ast.GenDecl, path string) bool { - if gen.Tok != token.IMPORT { - return false - } - for _, spec := range gen.Specs { - impspec := spec.(*ast.ImportSpec) - if importPath(impspec) == path { - return true - } - } - return false -} - -func importPath(s ast.Spec) string { - t, err := strconv.Unquote(s.(*ast.ImportSpec).Path.Value) - if err == nil { - return t - } - return "" -} - -func importName(s ast.Spec) string { - n := s.(*ast.ImportSpec).Name - if n == nil { - return "" - } - return n.Name -} - -func importComment(s ast.Spec) string { - c := s.(*ast.ImportSpec).Comment - if c == nil { - return "" - } - return c.Text() -} - -// collapse indicates whether prev may be removed, leaving only next. -func collapse(prev, next ast.Spec) bool { - if importPath(next) != importPath(prev) || importName(next) != importName(prev) { - return false - } - return prev.(*ast.ImportSpec).Comment == nil -} - -type posSpan struct { - Start token.Pos - End token.Pos -} - -// sortSpecs sorts the import specs within each import decl. -// It may mutate the token.File. -func sortSpecs(localPrefix string, tokFile *token.File, f *ast.File, specs []ast.Spec) []ast.Spec { - // Can't short-circuit here even if specs are already sorted, - // since they might yet need deduplication. - // A lone import, however, may be safely ignored. - if len(specs) <= 1 { - return specs - } - - // Record positions for specs. - pos := make([]posSpan, len(specs)) - for i, s := range specs { - pos[i] = posSpan{s.Pos(), s.End()} - } - - // Identify comments in this range. - // Any comment from pos[0].Start to the final line counts. - lastLine := tokFile.Line(pos[len(pos)-1].End) - cstart := len(f.Comments) - cend := len(f.Comments) - for i, g := range f.Comments { - if g.Pos() < pos[0].Start { - continue - } - if i < cstart { - cstart = i - } - if tokFile.Line(g.End()) > lastLine { - cend = i - break - } - } - comments := f.Comments[cstart:cend] - - // Assign each comment to the import spec preceding it. - importComment := map[*ast.ImportSpec][]*ast.CommentGroup{} - specIndex := 0 - for _, g := range comments { - for specIndex+1 < len(specs) && pos[specIndex+1].Start <= g.Pos() { - specIndex++ - } - s := specs[specIndex].(*ast.ImportSpec) - importComment[s] = append(importComment[s], g) - } - - // Sort the import specs by import path. - // Remove duplicates, when possible without data loss. - // Reassign the import paths to have the same position sequence. - // Reassign each comment to abut the end of its spec. - // Sort the comments by new position. - sort.Sort(byImportSpec{localPrefix, specs}) - - // Dedup. Thanks to our sorting, we can just consider - // adjacent pairs of imports. - deduped := specs[:0] - for i, s := range specs { - if i == len(specs)-1 || !collapse(s, specs[i+1]) { - deduped = append(deduped, s) - } else { - p := s.Pos() - tokFile.MergeLine(tokFile.Line(p)) // has side effects! - } - } - specs = deduped - - // Fix up comment positions - for i, s := range specs { - s := s.(*ast.ImportSpec) - if s.Name != nil { - s.Name.NamePos = pos[i].Start - } - updateBasicLitPos(s.Path, pos[i].Start) - s.EndPos = pos[i].End - nextSpecPos := pos[i].End - - for _, g := range importComment[s] { - for _, c := range g.List { - c.Slash = pos[i].End - nextSpecPos = c.End() - } - } - if i < len(specs)-1 { - pos[i+1].Start = nextSpecPos - pos[i+1].End = nextSpecPos - } - } - - sort.Sort(byCommentPos(comments)) - - // Fixup comments can insert blank lines, because import specs are on different lines. - // We remove those blank lines here by merging import spec to the first import spec line. - firstSpecLine := tokFile.Line(specs[0].Pos()) - for _, s := range specs[1:] { - p := s.Pos() - line := tokFile.Line(p) - for previousLine := line - 1; previousLine >= firstSpecLine; { - // MergeLine can panic. Avoid the panic at the cost of not removing the blank line - // golang/go#50329 - if previousLine > 0 && previousLine < tokFile.LineCount() { - tokFile.MergeLine(previousLine) // has side effects! - previousLine-- - } else { - // try to gather some data to diagnose how this could happen - req := "Please report what the imports section of your go file looked like." - log.Printf("panic avoided: first:%d line:%d previous:%d max:%d. %s", - firstSpecLine, line, previousLine, tokFile.LineCount(), req) - } - } - } - return specs -} - -type byImportSpec struct { - localPrefix string - specs []ast.Spec // slice of *ast.ImportSpec -} - -func (x byImportSpec) Len() int { return len(x.specs) } -func (x byImportSpec) Swap(i, j int) { x.specs[i], x.specs[j] = x.specs[j], x.specs[i] } -func (x byImportSpec) Less(i, j int) bool { - ipath := importPath(x.specs[i]) - jpath := importPath(x.specs[j]) - - igroup := importGroup(x.localPrefix, ipath) - jgroup := importGroup(x.localPrefix, jpath) - if igroup != jgroup { - return igroup < jgroup - } - - if ipath != jpath { - return ipath < jpath - } - iname := importName(x.specs[i]) - jname := importName(x.specs[j]) - - if iname != jname { - return iname < jname - } - return importComment(x.specs[i]) < importComment(x.specs[j]) -} - -type byCommentPos []*ast.CommentGroup - -func (x byCommentPos) Len() int { return len(x) } -func (x byCommentPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] } -func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() } - -// updateBasicLitPos updates lit.Pos, -// ensuring that lit.End (if set) is displaced by the same amount. -// (See https://go.dev/issue/76395.) -func updateBasicLitPos(lit *ast.BasicLit, pos token.Pos) { - len := lit.End() - lit.Pos() - lit.ValuePos = pos - // TODO(adonovan): after go1.26, simplify to: - // lit.ValueEnd = pos + len - v := reflect.ValueOf(lit).Elem().FieldByName("ValueEnd") - if v.IsValid() && v.Int() != 0 { - v.SetInt(int64(pos + len)) - } -} diff --git a/vendor/golang.org/x/tools/internal/imports/source.go b/vendor/golang.org/x/tools/internal/imports/source.go deleted file mode 100644 index cbe4f3c5..00000000 --- a/vendor/golang.org/x/tools/internal/imports/source.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2024 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 imports - -import "context" - -// These types document the APIs below. -// -// TODO(rfindley): consider making these defined types rather than aliases. -type ( - ImportPath = string - PackageName = string - Symbol = string - - // References is set of References found in a Go file. The first map key is the - // left hand side of a selector expression, the second key is the right hand - // side, and the value should always be true. - References = map[PackageName]map[Symbol]bool -) - -// A Result satisfies a missing import. -// -// The Import field describes the missing import spec, and the Package field -// summarizes the package exports. -type Result struct { - Import *ImportInfo - Package *PackageInfo -} - -// An ImportInfo represents a single import statement. -type ImportInfo struct { - ImportPath string // import path, e.g. "crypto/rand". - Name string // import name, e.g. "crand", or "" if none. -} - -// A PackageInfo represents what's known about a package. -type PackageInfo struct { - Name string // package name in the package declaration, if known - Exports map[string]bool // set of names of known package level sortSymbols -} - -// A Source provides imports to satisfy unresolved references in the file being -// fixed. -type Source interface { - // LoadPackageNames queries PackageName information for the requested import - // paths, when operating from the provided srcDir. - // - // TODO(rfindley): try to refactor to remove this operation. - LoadPackageNames(ctx context.Context, srcDir string, paths []ImportPath) (map[ImportPath]PackageName, error) - - // ResolveReferences asks the Source for the best package name to satisfy - // each of the missing references, in the context of fixing the given - // filename. - // - // Returns a map from package name to a [Result] for that package name that - // provides the required symbols. Keys may be omitted in the map if no - // candidates satisfy all missing references for that package name. It is up - // to each data source to select the best result for each entry in the - // missing map. - ResolveReferences(ctx context.Context, filename string, missing References) ([]*Result, error) -} diff --git a/vendor/golang.org/x/tools/internal/imports/source_env.go b/vendor/golang.org/x/tools/internal/imports/source_env.go deleted file mode 100644 index ec996c3c..00000000 --- a/vendor/golang.org/x/tools/internal/imports/source_env.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2024 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 imports - -import ( - "context" - "path/filepath" - "strings" - "sync" - - "golang.org/x/sync/errgroup" - "golang.org/x/tools/internal/gopathwalk" -) - -// ProcessEnvSource implements the [Source] interface using the legacy -// [ProcessEnv] abstraction. -type ProcessEnvSource struct { - env *ProcessEnv - srcDir string - filename string - pkgName string -} - -// NewProcessEnvSource returns a [ProcessEnvSource] wrapping the given -// env, to be used for fixing imports in the file with name filename in package -// named pkgName. -func NewProcessEnvSource(env *ProcessEnv, filename, pkgName string) (*ProcessEnvSource, error) { - abs, err := filepath.Abs(filename) - if err != nil { - return nil, err - } - srcDir := filepath.Dir(abs) - return &ProcessEnvSource{ - env: env, - srcDir: srcDir, - filename: filename, - pkgName: pkgName, - }, nil -} - -func (s *ProcessEnvSource) LoadPackageNames(ctx context.Context, srcDir string, unknown []string) (map[string]string, error) { - r, err := s.env.GetResolver() - if err != nil { - return nil, err - } - return r.loadPackageNames(unknown, srcDir) -} - -func (s *ProcessEnvSource) ResolveReferences(ctx context.Context, filename string, refs map[string]map[string]bool) ([]*Result, error) { - var mu sync.Mutex - found := make(map[string][]pkgDistance) - callback := &scanCallback{ - rootFound: func(gopathwalk.Root) bool { - return true // We want everything. - }, - dirFound: func(pkg *pkg) bool { - return pkgIsCandidate(filename, refs, pkg) - }, - packageNameLoaded: func(pkg *pkg) bool { - if _, want := refs[pkg.packageName]; !want { - return false - } - if pkg.dir == s.srcDir && s.pkgName == pkg.packageName { - // The candidate is in the same directory and has the - // same package name. Don't try to import ourselves. - return false - } - if !CanUse(filename, pkg.dir) { - return false - } - mu.Lock() - defer mu.Unlock() - found[pkg.packageName] = append(found[pkg.packageName], pkgDistance{pkg, distance(s.srcDir, pkg.dir)}) - return false // We'll do our own loading after we sort. - }, - } - resolver, err := s.env.GetResolver() - if err != nil { - return nil, err - } - if err := resolver.scan(ctx, callback); err != nil { - return nil, err - } - - g, ctx := errgroup.WithContext(ctx) - - searcher := symbolSearcher{ - logf: s.env.logf, - srcDir: s.srcDir, - xtest: strings.HasSuffix(s.pkgName, "_test"), - loadExports: resolver.loadExports, - } - - var resultMu sync.Mutex - results := make(map[string]*Result, len(refs)) - for pkgName, symbols := range refs { - g.Go(func() error { - found, err := searcher.search(ctx, found[pkgName], pkgName, symbols) - if err != nil { - return err - } - if found == nil { - return nil // No matching package. - } - - imp := &ImportInfo{ - ImportPath: found.importPathShort, - } - pkg := &PackageInfo{ - Name: pkgName, - Exports: symbols, - } - resultMu.Lock() - results[pkgName] = &Result{Import: imp, Package: pkg} - resultMu.Unlock() - return nil - }) - } - if err := g.Wait(); err != nil { - return nil, err - } - var ans []*Result - for _, x := range results { - ans = append(ans, x) - } - return ans, nil -} diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go deleted file mode 100644 index 929b470b..00000000 --- a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package packagesinternal exposes internal-only fields from go/packages. -package packagesinternal - -import "fmt" - -var GetDepsErrors = func(p any) []*PackageError { return nil } - -type PackageError struct { - ImportStack []string // shortest path from package named on command line to this one - Pos string // position of error (if present, file:line:col) - Err string // the error itself -} - -func (err PackageError) String() string { - return fmt.Sprintf("%s: %s (import stack: %s)", err.Pos, err.Err, err.ImportStack) -} - -var TypecheckCgo int -var DepsErrors int // must be set as a LoadMode to call GetDepsErrors diff --git a/vendor/golang.org/x/tools/internal/pkgbits/codes.go b/vendor/golang.org/x/tools/internal/pkgbits/codes.go deleted file mode 100644 index f0cabde9..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/codes.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -// A Code is an enum value that can be encoded into bitstreams. -// -// Code types are preferable for enum types, because they allow -// Decoder to detect desyncs. -type Code interface { - // Marker returns the SyncMarker for the Code's dynamic type. - Marker() SyncMarker - - // Value returns the Code's ordinal value. - Value() int -} - -// A CodeVal distinguishes among go/constant.Value encodings. -type CodeVal int - -func (c CodeVal) Marker() SyncMarker { return SyncVal } -func (c CodeVal) Value() int { return int(c) } - -// Note: These values are public and cannot be changed without -// updating the go/types importers. - -const ( - ValBool CodeVal = iota - ValString - ValInt64 - ValBigInt - ValBigRat - ValBigFloat -) - -// A CodeType distinguishes among go/types.Type encodings. -type CodeType int - -func (c CodeType) Marker() SyncMarker { return SyncType } -func (c CodeType) Value() int { return int(c) } - -// Note: These values are public and cannot be changed without -// updating the go/types importers. - -const ( - TypeBasic CodeType = iota - TypeNamed - TypePointer - TypeSlice - TypeArray - TypeChan - TypeMap - TypeSignature - TypeStruct - TypeInterface - TypeUnion - TypeTypeParam -) - -// A CodeObj distinguishes among go/types.Object encodings. -type CodeObj int - -func (c CodeObj) Marker() SyncMarker { return SyncCodeObj } -func (c CodeObj) Value() int { return int(c) } - -// Note: These values are public and cannot be changed without -// updating the go/types importers. - -const ( - ObjAlias CodeObj = iota - ObjConst - ObjType - ObjFunc - ObjVar - ObjStub -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go deleted file mode 100644 index c0aba26c..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go +++ /dev/null @@ -1,519 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -import ( - "encoding/binary" - "errors" - "fmt" - "go/constant" - "go/token" - "io" - "math/big" - "os" - "runtime" - "strings" -) - -// A PkgDecoder provides methods for decoding a package's Unified IR -// export data. -type PkgDecoder struct { - // version is the file format version. - version Version - - // sync indicates whether the file uses sync markers. - sync bool - - // pkgPath is the package path for the package to be decoded. - // - // TODO(mdempsky): Remove; unneeded since CL 391014. - pkgPath string - - // elemData is the full data payload of the encoded package. - // Elements are densely and contiguously packed together. - // - // The last 8 bytes of elemData are the package fingerprint. - elemData string - - // elemEnds stores the byte-offset end positions of element - // bitstreams within elemData. - // - // For example, element I's bitstream data starts at elemEnds[I-1] - // (or 0, if I==0) and ends at elemEnds[I]. - // - // Note: elemEnds is indexed by absolute indices, not - // section-relative indices. - elemEnds []uint32 - - // elemEndsEnds stores the index-offset end positions of relocation - // sections within elemEnds. - // - // For example, section K's end positions start at elemEndsEnds[K-1] - // (or 0, if K==0) and end at elemEndsEnds[K]. - elemEndsEnds [numRelocs]uint32 - - scratchRelocEnt []RelocEnt -} - -// PkgPath returns the package path for the package -// -// TODO(mdempsky): Remove; unneeded since CL 391014. -func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath } - -// SyncMarkers reports whether pr uses sync markers. -func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync } - -// NewPkgDecoder returns a PkgDecoder initialized to read the Unified -// IR export data from input. pkgPath is the package path for the -// compilation unit that produced the export data. -func NewPkgDecoder(pkgPath, input string) PkgDecoder { - pr := PkgDecoder{ - pkgPath: pkgPath, - } - - // TODO(mdempsky): Implement direct indexing of input string to - // avoid copying the position information. - - r := strings.NewReader(input) - - var ver uint32 - assert(binary.Read(r, binary.LittleEndian, &ver) == nil) - pr.version = Version(ver) - - if pr.version >= numVersions { - panic(fmt.Errorf("cannot decode %q, export data version %d is greater than maximum supported version %d", pkgPath, pr.version, numVersions-1)) - } - - if pr.version.Has(Flags) { - var flags uint32 - assert(binary.Read(r, binary.LittleEndian, &flags) == nil) - pr.sync = flags&flagSyncMarkers != 0 - } - - assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil) - - pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1]) - assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil) - - pos, err := r.Seek(0, io.SeekCurrent) - assert(err == nil) - - pr.elemData = input[pos:] - - const fingerprintSize = 8 - assert(len(pr.elemData)-fingerprintSize == int(pr.elemEnds[len(pr.elemEnds)-1])) - - return pr -} - -// NumElems returns the number of elements in section k. -func (pr *PkgDecoder) NumElems(k RelocKind) int { - count := int(pr.elemEndsEnds[k]) - if k > 0 { - count -= int(pr.elemEndsEnds[k-1]) - } - return count -} - -// TotalElems returns the total number of elements across all sections. -func (pr *PkgDecoder) TotalElems() int { - return len(pr.elemEnds) -} - -// Fingerprint returns the package fingerprint. -func (pr *PkgDecoder) Fingerprint() [8]byte { - var fp [8]byte - copy(fp[:], pr.elemData[len(pr.elemData)-8:]) - return fp -} - -// AbsIdx returns the absolute index for the given (section, index) -// pair. -func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int { - absIdx := int(idx) - if k > 0 { - absIdx += int(pr.elemEndsEnds[k-1]) - } - if absIdx >= int(pr.elemEndsEnds[k]) { - panicf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds) - } - return absIdx -} - -// DataIdx returns the raw element bitstream for the given (section, -// index) pair. -func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string { - absIdx := pr.AbsIdx(k, idx) - - var start uint32 - if absIdx > 0 { - start = pr.elemEnds[absIdx-1] - } - end := pr.elemEnds[absIdx] - - return pr.elemData[start:end] -} - -// StringIdx returns the string value for the given string index. -func (pr *PkgDecoder) StringIdx(idx Index) string { - return pr.DataIdx(RelocString, idx) -} - -// NewDecoder returns a Decoder for the given (section, index) pair, -// and decodes the given SyncMarker from the element bitstream. -func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { - r := pr.NewDecoderRaw(k, idx) - r.Sync(marker) - return r -} - -// TempDecoder returns a Decoder for the given (section, index) pair, -// and decodes the given SyncMarker from the element bitstream. -// If possible the Decoder should be RetireDecoder'd when it is no longer -// needed, this will avoid heap allocations. -func (pr *PkgDecoder) TempDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { - r := pr.TempDecoderRaw(k, idx) - r.Sync(marker) - return r -} - -func (pr *PkgDecoder) RetireDecoder(d *Decoder) { - pr.scratchRelocEnt = d.Relocs - d.Relocs = nil -} - -// NewDecoderRaw returns a Decoder for the given (section, index) pair. -// -// Most callers should use NewDecoder instead. -func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder { - r := Decoder{ - common: pr, - k: k, - Idx: idx, - } - - r.Data.Reset(pr.DataIdx(k, idx)) - r.Sync(SyncRelocs) - r.Relocs = make([]RelocEnt, r.Len()) - for i := range r.Relocs { - r.Sync(SyncReloc) - r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} - } - - return r -} - -func (pr *PkgDecoder) TempDecoderRaw(k RelocKind, idx Index) Decoder { - r := Decoder{ - common: pr, - k: k, - Idx: idx, - } - - r.Data.Reset(pr.DataIdx(k, idx)) - r.Sync(SyncRelocs) - l := r.Len() - if cap(pr.scratchRelocEnt) >= l { - r.Relocs = pr.scratchRelocEnt[:l] - pr.scratchRelocEnt = nil - } else { - r.Relocs = make([]RelocEnt, l) - } - for i := range r.Relocs { - r.Sync(SyncReloc) - r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} - } - - return r -} - -// A Decoder provides methods for decoding an individual element's -// bitstream data. -type Decoder struct { - common *PkgDecoder - - Relocs []RelocEnt - Data strings.Reader - - k RelocKind - Idx Index -} - -func (r *Decoder) checkErr(err error) { - if err != nil { - panicf("unexpected decoding error: %w", err) - } -} - -func (r *Decoder) rawUvarint() uint64 { - x, err := readUvarint(&r.Data) - r.checkErr(err) - return x -} - -// readUvarint is a type-specialized copy of encoding/binary.ReadUvarint. -// This avoids the interface conversion and thus has better escape properties, -// which flows up the stack. -func readUvarint(r *strings.Reader) (uint64, error) { - var x uint64 - var s uint - for i := range binary.MaxVarintLen64 { - b, err := r.ReadByte() - if err != nil { - if i > 0 && err == io.EOF { - err = io.ErrUnexpectedEOF - } - return x, err - } - if b < 0x80 { - if i == binary.MaxVarintLen64-1 && b > 1 { - return x, overflow - } - return x | uint64(b)<> 1) - if ux&1 != 0 { - x = ^x - } - return x -} - -func (r *Decoder) rawReloc(k RelocKind, idx int) Index { - e := r.Relocs[idx] - assert(e.Kind == k) - return e.Idx -} - -// Sync decodes a sync marker from the element bitstream and asserts -// that it matches the expected marker. -// -// If r.common.sync is false, then Sync is a no-op. -func (r *Decoder) Sync(mWant SyncMarker) { - if !r.common.sync { - return - } - - pos, _ := r.Data.Seek(0, io.SeekCurrent) - mHave := SyncMarker(r.rawUvarint()) - writerPCs := make([]int, r.rawUvarint()) - for i := range writerPCs { - writerPCs[i] = int(r.rawUvarint()) - } - - if mHave == mWant { - return - } - - // There's some tension here between printing: - // - // (1) full file paths that tools can recognize (e.g., so emacs - // hyperlinks the "file:line" text for easy navigation), or - // - // (2) short file paths that are easier for humans to read (e.g., by - // omitting redundant or irrelevant details, so it's easier to - // focus on the useful bits that remain). - // - // The current formatting favors the former, as it seems more - // helpful in practice. But perhaps the formatting could be improved - // to better address both concerns. For example, use relative file - // paths if they would be shorter, or rewrite file paths to contain - // "$GOROOT" (like objabi.AbsFile does) if tools can be taught how - // to reliably expand that again. - - fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", r.common.pkgPath, r.k, r.Idx, pos) - - fmt.Printf("\nfound %v, written at:\n", mHave) - if len(writerPCs) == 0 { - fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", r.common.pkgPath) - } - for _, pc := range writerPCs { - fmt.Printf("\t%s\n", r.common.StringIdx(r.rawReloc(RelocString, pc))) - } - - fmt.Printf("\nexpected %v, reading at:\n", mWant) - var readerPCs [32]uintptr // TODO(mdempsky): Dynamically size? - n := runtime.Callers(2, readerPCs[:]) - for _, pc := range fmtFrames(readerPCs[:n]...) { - fmt.Printf("\t%s\n", pc) - } - - // We already printed a stack trace for the reader, so now we can - // simply exit. Printing a second one with panic or base.Fatalf - // would just be noise. - os.Exit(1) -} - -// Bool decodes and returns a bool value from the element bitstream. -func (r *Decoder) Bool() bool { - r.Sync(SyncBool) - x, err := r.Data.ReadByte() - r.checkErr(err) - assert(x < 2) - return x != 0 -} - -// Int64 decodes and returns an int64 value from the element bitstream. -func (r *Decoder) Int64() int64 { - r.Sync(SyncInt64) - return r.rawVarint() -} - -// Uint64 decodes and returns a uint64 value from the element bitstream. -func (r *Decoder) Uint64() uint64 { - r.Sync(SyncUint64) - return r.rawUvarint() -} - -// Len decodes and returns a non-negative int value from the element bitstream. -func (r *Decoder) Len() int { x := r.Uint64(); v := int(x); assert(uint64(v) == x); return v } - -// Int decodes and returns an int value from the element bitstream. -func (r *Decoder) Int() int { x := r.Int64(); v := int(x); assert(int64(v) == x); return v } - -// Uint decodes and returns a uint value from the element bitstream. -func (r *Decoder) Uint() uint { x := r.Uint64(); v := uint(x); assert(uint64(v) == x); return v } - -// Code decodes a Code value from the element bitstream and returns -// its ordinal value. It's the caller's responsibility to convert the -// result to an appropriate Code type. -// -// TODO(mdempsky): Ideally this method would have signature "Code[T -// Code] T" instead, but we don't allow generic methods and the -// compiler can't depend on generics yet anyway. -func (r *Decoder) Code(mark SyncMarker) int { - r.Sync(mark) - return r.Len() -} - -// Reloc decodes a relocation of expected section k from the element -// bitstream and returns an index to the referenced element. -func (r *Decoder) Reloc(k RelocKind) Index { - r.Sync(SyncUseReloc) - return r.rawReloc(k, r.Len()) -} - -// String decodes and returns a string value from the element -// bitstream. -func (r *Decoder) String() string { - r.Sync(SyncString) - return r.common.StringIdx(r.Reloc(RelocString)) -} - -// Strings decodes and returns a variable-length slice of strings from -// the element bitstream. -func (r *Decoder) Strings() []string { - res := make([]string, r.Len()) - for i := range res { - res[i] = r.String() - } - return res -} - -// Value decodes and returns a constant.Value from the element -// bitstream. -func (r *Decoder) Value() constant.Value { - r.Sync(SyncValue) - isComplex := r.Bool() - val := r.scalar() - if isComplex { - val = constant.BinaryOp(val, token.ADD, constant.MakeImag(r.scalar())) - } - return val -} - -func (r *Decoder) scalar() constant.Value { - switch tag := CodeVal(r.Code(SyncVal)); tag { - default: - panic(fmt.Errorf("unexpected scalar tag: %v", tag)) - - case ValBool: - return constant.MakeBool(r.Bool()) - case ValString: - return constant.MakeString(r.String()) - case ValInt64: - return constant.MakeInt64(r.Int64()) - case ValBigInt: - return constant.Make(r.bigInt()) - case ValBigRat: - num := r.bigInt() - denom := r.bigInt() - return constant.Make(new(big.Rat).SetFrac(num, denom)) - case ValBigFloat: - return constant.Make(r.bigFloat()) - } -} - -func (r *Decoder) bigInt() *big.Int { - v := new(big.Int).SetBytes([]byte(r.String())) - if r.Bool() { - v.Neg(v) - } - return v -} - -func (r *Decoder) bigFloat() *big.Float { - v := new(big.Float).SetPrec(512) - assert(v.UnmarshalText([]byte(r.String())) == nil) - return v -} - -// @@@ Helpers - -// TODO(mdempsky): These should probably be removed. I think they're a -// smell that the export data format is not yet quite right. - -// PeekPkgPath returns the package path for the specified package -// index. -func (pr *PkgDecoder) PeekPkgPath(idx Index) string { - var path string - { - r := pr.TempDecoder(RelocPkg, idx, SyncPkgDef) - path = r.String() - pr.RetireDecoder(&r) - } - if path == "" { - path = pr.pkgPath - } - return path -} - -// PeekObj returns the package path, object name, and CodeObj for the -// specified object index. -func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) { - var ridx Index - var name string - var rcode int - { - r := pr.TempDecoder(RelocName, idx, SyncObject1) - r.Sync(SyncSym) - r.Sync(SyncPkg) - ridx = r.Reloc(RelocPkg) - name = r.String() - rcode = r.Code(SyncCodeObj) - pr.RetireDecoder(&r) - } - - path := pr.PeekPkgPath(ridx) - assert(name != "") - - tag := CodeObj(rcode) - - return path, name, tag -} - -// Version reports the version of the bitstream. -func (w *Decoder) Version() Version { return w.common.version } diff --git a/vendor/golang.org/x/tools/internal/pkgbits/doc.go b/vendor/golang.org/x/tools/internal/pkgbits/doc.go deleted file mode 100644 index c8a2796b..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/doc.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package pkgbits implements low-level coding abstractions for -// Unified IR's export data format. -// -// At a low-level, a package is a collection of bitstream elements. -// Each element has a "kind" and a dense, non-negative index. -// Elements can be randomly accessed given their kind and index. -// -// Individual elements are sequences of variable-length values (e.g., -// integers, booleans, strings, go/constant values, cross-references -// to other elements). Package pkgbits provides APIs for encoding and -// decoding these low-level values, but the details of mapping -// higher-level Go constructs into elements is left to higher-level -// abstractions. -// -// Elements may cross-reference each other with "relocations." For -// example, an element representing a pointer type has a relocation -// referring to the element type. -// -// Go constructs may be composed as a constellation of multiple -// elements. For example, a declared function may have one element to -// describe the object (e.g., its name, type, position), and a -// separate element to describe its function body. This allows readers -// some flexibility in efficiently seeking or re-reading data (e.g., -// inlining requires re-reading the function body for each inlined -// call, without needing to re-read the object-level details). -// -// This is a copy of internal/pkgbits in the Go implementation. -package pkgbits diff --git a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go deleted file mode 100644 index c17a1239..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go +++ /dev/null @@ -1,392 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -import ( - "bytes" - "crypto/md5" - "encoding/binary" - "go/constant" - "io" - "math/big" - "runtime" - "strings" -) - -// A PkgEncoder provides methods for encoding a package's Unified IR -// export data. -type PkgEncoder struct { - // version of the bitstream. - version Version - - // elems holds the bitstream for previously encoded elements. - elems [numRelocs][]string - - // stringsIdx maps previously encoded strings to their index within - // the RelocString section, to allow deduplication. That is, - // elems[RelocString][stringsIdx[s]] == s (if present). - stringsIdx map[string]Index - - // syncFrames is the number of frames to write at each sync - // marker. A negative value means sync markers are omitted. - syncFrames int -} - -// SyncMarkers reports whether pw uses sync markers. -func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 } - -// NewPkgEncoder returns an initialized PkgEncoder. -// -// syncFrames is the number of caller frames that should be serialized -// at Sync points. Serializing additional frames results in larger -// export data files, but can help diagnosing desync errors in -// higher-level Unified IR reader/writer code. If syncFrames is -// negative, then sync markers are omitted entirely. -func NewPkgEncoder(version Version, syncFrames int) PkgEncoder { - return PkgEncoder{ - version: version, - stringsIdx: make(map[string]Index), - syncFrames: syncFrames, - } -} - -// DumpTo writes the package's encoded data to out0 and returns the -// package fingerprint. -func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) { - h := md5.New() - out := io.MultiWriter(out0, h) - - writeUint32 := func(x uint32) { - assert(binary.Write(out, binary.LittleEndian, x) == nil) - } - - writeUint32(uint32(pw.version)) - - if pw.version.Has(Flags) { - var flags uint32 - if pw.SyncMarkers() { - flags |= flagSyncMarkers - } - writeUint32(flags) - } - - // Write elemEndsEnds. - var sum uint32 - for _, elems := range &pw.elems { - sum += uint32(len(elems)) - writeUint32(sum) - } - - // Write elemEnds. - sum = 0 - for _, elems := range &pw.elems { - for _, elem := range elems { - sum += uint32(len(elem)) - writeUint32(sum) - } - } - - // Write elemData. - for _, elems := range &pw.elems { - for _, elem := range elems { - _, err := io.WriteString(out, elem) - assert(err == nil) - } - } - - // Write fingerprint. - copy(fingerprint[:], h.Sum(nil)) - _, err := out0.Write(fingerprint[:]) - assert(err == nil) - - return -} - -// StringIdx adds a string value to the strings section, if not -// already present, and returns its index. -func (pw *PkgEncoder) StringIdx(s string) Index { - if idx, ok := pw.stringsIdx[s]; ok { - assert(pw.elems[RelocString][idx] == s) - return idx - } - - idx := Index(len(pw.elems[RelocString])) - pw.elems[RelocString] = append(pw.elems[RelocString], s) - pw.stringsIdx[s] = idx - return idx -} - -// NewEncoder returns an Encoder for a new element within the given -// section, and encodes the given SyncMarker as the start of the -// element bitstream. -func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder { - e := pw.NewEncoderRaw(k) - e.Sync(marker) - return e -} - -// NewEncoderRaw returns an Encoder for a new element within the given -// section. -// -// Most callers should use NewEncoder instead. -func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder { - idx := Index(len(pw.elems[k])) - pw.elems[k] = append(pw.elems[k], "") // placeholder - - return Encoder{ - p: pw, - k: k, - Idx: idx, - } -} - -// An Encoder provides methods for encoding an individual element's -// bitstream data. -type Encoder struct { - p *PkgEncoder - - Relocs []RelocEnt - RelocMap map[RelocEnt]uint32 - Data bytes.Buffer // accumulated element bitstream data - - encodingRelocHeader bool - - k RelocKind - Idx Index // index within relocation section -} - -// Flush finalizes the element's bitstream and returns its Index. -func (w *Encoder) Flush() Index { - var sb strings.Builder - - // Backup the data so we write the relocations at the front. - var tmp bytes.Buffer - io.Copy(&tmp, &w.Data) - - // TODO(mdempsky): Consider writing these out separately so they're - // easier to strip, along with function bodies, so that we can prune - // down to just the data that's relevant to go/types. - if w.encodingRelocHeader { - panic("encodingRelocHeader already true; recursive flush?") - } - w.encodingRelocHeader = true - w.Sync(SyncRelocs) - w.Len(len(w.Relocs)) - for _, rEnt := range w.Relocs { - w.Sync(SyncReloc) - w.Len(int(rEnt.Kind)) - w.Len(int(rEnt.Idx)) - } - - io.Copy(&sb, &w.Data) - io.Copy(&sb, &tmp) - w.p.elems[w.k][w.Idx] = sb.String() - - return w.Idx -} - -func (w *Encoder) checkErr(err error) { - if err != nil { - panicf("unexpected encoding error: %v", err) - } -} - -func (w *Encoder) rawUvarint(x uint64) { - var buf [binary.MaxVarintLen64]byte - n := binary.PutUvarint(buf[:], x) - _, err := w.Data.Write(buf[:n]) - w.checkErr(err) -} - -func (w *Encoder) rawVarint(x int64) { - // Zig-zag encode. - ux := uint64(x) << 1 - if x < 0 { - ux = ^ux - } - - w.rawUvarint(ux) -} - -func (w *Encoder) rawReloc(r RelocKind, idx Index) int { - e := RelocEnt{r, idx} - if w.RelocMap != nil { - if i, ok := w.RelocMap[e]; ok { - return int(i) - } - } else { - w.RelocMap = make(map[RelocEnt]uint32) - } - - i := len(w.Relocs) - w.RelocMap[e] = uint32(i) - w.Relocs = append(w.Relocs, e) - return i -} - -func (w *Encoder) Sync(m SyncMarker) { - if !w.p.SyncMarkers() { - return - } - - // Writing out stack frame string references requires working - // relocations, but writing out the relocations themselves involves - // sync markers. To prevent infinite recursion, we simply trim the - // stack frame for sync markers within the relocation header. - var frames []string - if !w.encodingRelocHeader && w.p.syncFrames > 0 { - pcs := make([]uintptr, w.p.syncFrames) - n := runtime.Callers(2, pcs) - frames = fmtFrames(pcs[:n]...) - } - - // TODO(mdempsky): Save space by writing out stack frames as a - // linked list so we can share common stack frames. - w.rawUvarint(uint64(m)) - w.rawUvarint(uint64(len(frames))) - for _, frame := range frames { - w.rawUvarint(uint64(w.rawReloc(RelocString, w.p.StringIdx(frame)))) - } -} - -// Bool encodes and writes a bool value into the element bitstream, -// and then returns the bool value. -// -// For simple, 2-alternative encodings, the idiomatic way to call Bool -// is something like: -// -// if w.Bool(x != 0) { -// // alternative #1 -// } else { -// // alternative #2 -// } -// -// For multi-alternative encodings, use Code instead. -func (w *Encoder) Bool(b bool) bool { - w.Sync(SyncBool) - var x byte - if b { - x = 1 - } - err := w.Data.WriteByte(x) - w.checkErr(err) - return b -} - -// Int64 encodes and writes an int64 value into the element bitstream. -func (w *Encoder) Int64(x int64) { - w.Sync(SyncInt64) - w.rawVarint(x) -} - -// Uint64 encodes and writes a uint64 value into the element bitstream. -func (w *Encoder) Uint64(x uint64) { - w.Sync(SyncUint64) - w.rawUvarint(x) -} - -// Len encodes and writes a non-negative int value into the element bitstream. -func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) } - -// Int encodes and writes an int value into the element bitstream. -func (w *Encoder) Int(x int) { w.Int64(int64(x)) } - -// Uint encodes and writes a uint value into the element bitstream. -func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) } - -// Reloc encodes and writes a relocation for the given (section, -// index) pair into the element bitstream. -// -// Note: Only the index is formally written into the element -// bitstream, so bitstream decoders must know from context which -// section an encoded relocation refers to. -func (w *Encoder) Reloc(r RelocKind, idx Index) { - w.Sync(SyncUseReloc) - w.Len(w.rawReloc(r, idx)) -} - -// Code encodes and writes a Code value into the element bitstream. -func (w *Encoder) Code(c Code) { - w.Sync(c.Marker()) - w.Len(c.Value()) -} - -// String encodes and writes a string value into the element -// bitstream. -// -// Internally, strings are deduplicated by adding them to the strings -// section (if not already present), and then writing a relocation -// into the element bitstream. -func (w *Encoder) String(s string) { - w.StringRef(w.p.StringIdx(s)) -} - -// StringRef writes a reference to the given index, which must be a -// previously encoded string value. -func (w *Encoder) StringRef(idx Index) { - w.Sync(SyncString) - w.Reloc(RelocString, idx) -} - -// Strings encodes and writes a variable-length slice of strings into -// the element bitstream. -func (w *Encoder) Strings(ss []string) { - w.Len(len(ss)) - for _, s := range ss { - w.String(s) - } -} - -// Value encodes and writes a constant.Value into the element -// bitstream. -func (w *Encoder) Value(val constant.Value) { - w.Sync(SyncValue) - if w.Bool(val.Kind() == constant.Complex) { - w.scalar(constant.Real(val)) - w.scalar(constant.Imag(val)) - } else { - w.scalar(val) - } -} - -func (w *Encoder) scalar(val constant.Value) { - switch v := constant.Val(val).(type) { - default: - panicf("unhandled %v (%v)", val, val.Kind()) - case bool: - w.Code(ValBool) - w.Bool(v) - case string: - w.Code(ValString) - w.String(v) - case int64: - w.Code(ValInt64) - w.Int64(v) - case *big.Int: - w.Code(ValBigInt) - w.bigInt(v) - case *big.Rat: - w.Code(ValBigRat) - w.bigInt(v.Num()) - w.bigInt(v.Denom()) - case *big.Float: - w.Code(ValBigFloat) - w.bigFloat(v) - } -} - -func (w *Encoder) bigInt(v *big.Int) { - b := v.Bytes() - w.String(string(b)) // TODO: More efficient encoding. - w.Bool(v.Sign() < 0) -} - -func (w *Encoder) bigFloat(v *big.Float) { - b := v.Append(nil, 'p', -1) - w.String(string(b)) // TODO: More efficient encoding. -} - -// Version reports the version of the bitstream. -func (w *Encoder) Version() Version { return w.p.version } diff --git a/vendor/golang.org/x/tools/internal/pkgbits/flags.go b/vendor/golang.org/x/tools/internal/pkgbits/flags.go deleted file mode 100644 index 65422274..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/flags.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -const ( - flagSyncMarkers = 1 << iota // file format contains sync markers -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/reloc.go b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go deleted file mode 100644 index fcdfb97c..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/reloc.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -// A RelocKind indicates a particular section within a unified IR export. -type RelocKind int32 - -// An Index represents a bitstream element index within a particular -// section. -type Index int32 - -// A relocEnt (relocation entry) is an entry in an element's local -// reference table. -// -// TODO(mdempsky): Rename this too. -type RelocEnt struct { - Kind RelocKind - Idx Index -} - -// Reserved indices within the meta relocation section. -const ( - PublicRootIdx Index = 0 - PrivateRootIdx Index = 1 -) - -const ( - RelocString RelocKind = iota - RelocMeta - RelocPosBase - RelocPkg - RelocName - RelocType - RelocObj - RelocObjExt - RelocObjDict - RelocBody - - numRelocs = iota -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/support.go b/vendor/golang.org/x/tools/internal/pkgbits/support.go deleted file mode 100644 index 50534a29..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/support.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -import "fmt" - -func assert(b bool) { - if !b { - panic("assertion failed") - } -} - -func panicf(format string, args ...any) { - panic(fmt.Errorf(format, args...)) -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/sync.go b/vendor/golang.org/x/tools/internal/pkgbits/sync.go deleted file mode 100644 index 1520b73a..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/sync.go +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkgbits - -import ( - "fmt" - "runtime" - "strings" -) - -// fmtFrames formats a backtrace for reporting reader/writer desyncs. -func fmtFrames(pcs ...uintptr) []string { - res := make([]string, 0, len(pcs)) - walkFrames(pcs, func(file string, line int, name string, offset uintptr) { - // Trim package from function name. It's just redundant noise. - name = strings.TrimPrefix(name, "cmd/compile/internal/noder.") - - res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset)) - }) - return res -} - -type frameVisitor func(file string, line int, name string, offset uintptr) - -// walkFrames calls visit for each call frame represented by pcs. -// -// pcs should be a slice of PCs, as returned by runtime.Callers. -func walkFrames(pcs []uintptr, visit frameVisitor) { - if len(pcs) == 0 { - return - } - - frames := runtime.CallersFrames(pcs) - for { - frame, more := frames.Next() - visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry) - if !more { - return - } - } -} - -// SyncMarker is an enum type that represents markers that may be -// written to export data to ensure the reader and writer stay -// synchronized. -type SyncMarker int - -//go:generate stringer -type=SyncMarker -trimprefix=Sync - -const ( - _ SyncMarker = iota - - // Public markers (known to go/types importers). - - // Low-level coding markers. - SyncEOF - SyncBool - SyncInt64 - SyncUint64 - SyncString - SyncValue - SyncVal - SyncRelocs - SyncReloc - SyncUseReloc - - // Higher-level object and type markers. - SyncPublic - SyncPos - SyncPosBase - SyncObject - SyncObject1 - SyncPkg - SyncPkgDef - SyncMethod - SyncType - SyncTypeIdx - SyncTypeParamNames - SyncSignature - SyncParams - SyncParam - SyncCodeObj - SyncSym - SyncLocalIdent - SyncSelector - - // Private markers (only known to cmd/compile). - SyncPrivate - - SyncFuncExt - SyncVarExt - SyncTypeExt - SyncPragma - - SyncExprList - SyncExprs - SyncExpr - SyncExprType - SyncAssign - SyncOp - SyncFuncLit - SyncCompLit - - SyncDecl - SyncFuncBody - SyncOpenScope - SyncCloseScope - SyncCloseAnotherScope - SyncDeclNames - SyncDeclName - - SyncStmts - SyncBlockStmt - SyncIfStmt - SyncForStmt - SyncSwitchStmt - SyncRangeStmt - SyncCaseClause - SyncCommClause - SyncSelectStmt - SyncDecls - SyncLabeledStmt - SyncUseObjLocal - SyncAddLocal - SyncLinkname - SyncStmt1 - SyncStmtsEnd - SyncLabel - SyncOptLabel - - SyncMultiExpr - SyncRType - SyncConvRTTI -) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go deleted file mode 100644 index 582ad56d..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go +++ /dev/null @@ -1,92 +0,0 @@ -// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT. - -package pkgbits - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[SyncEOF-1] - _ = x[SyncBool-2] - _ = x[SyncInt64-3] - _ = x[SyncUint64-4] - _ = x[SyncString-5] - _ = x[SyncValue-6] - _ = x[SyncVal-7] - _ = x[SyncRelocs-8] - _ = x[SyncReloc-9] - _ = x[SyncUseReloc-10] - _ = x[SyncPublic-11] - _ = x[SyncPos-12] - _ = x[SyncPosBase-13] - _ = x[SyncObject-14] - _ = x[SyncObject1-15] - _ = x[SyncPkg-16] - _ = x[SyncPkgDef-17] - _ = x[SyncMethod-18] - _ = x[SyncType-19] - _ = x[SyncTypeIdx-20] - _ = x[SyncTypeParamNames-21] - _ = x[SyncSignature-22] - _ = x[SyncParams-23] - _ = x[SyncParam-24] - _ = x[SyncCodeObj-25] - _ = x[SyncSym-26] - _ = x[SyncLocalIdent-27] - _ = x[SyncSelector-28] - _ = x[SyncPrivate-29] - _ = x[SyncFuncExt-30] - _ = x[SyncVarExt-31] - _ = x[SyncTypeExt-32] - _ = x[SyncPragma-33] - _ = x[SyncExprList-34] - _ = x[SyncExprs-35] - _ = x[SyncExpr-36] - _ = x[SyncExprType-37] - _ = x[SyncAssign-38] - _ = x[SyncOp-39] - _ = x[SyncFuncLit-40] - _ = x[SyncCompLit-41] - _ = x[SyncDecl-42] - _ = x[SyncFuncBody-43] - _ = x[SyncOpenScope-44] - _ = x[SyncCloseScope-45] - _ = x[SyncCloseAnotherScope-46] - _ = x[SyncDeclNames-47] - _ = x[SyncDeclName-48] - _ = x[SyncStmts-49] - _ = x[SyncBlockStmt-50] - _ = x[SyncIfStmt-51] - _ = x[SyncForStmt-52] - _ = x[SyncSwitchStmt-53] - _ = x[SyncRangeStmt-54] - _ = x[SyncCaseClause-55] - _ = x[SyncCommClause-56] - _ = x[SyncSelectStmt-57] - _ = x[SyncDecls-58] - _ = x[SyncLabeledStmt-59] - _ = x[SyncUseObjLocal-60] - _ = x[SyncAddLocal-61] - _ = x[SyncLinkname-62] - _ = x[SyncStmt1-63] - _ = x[SyncStmtsEnd-64] - _ = x[SyncLabel-65] - _ = x[SyncOptLabel-66] - _ = x[SyncMultiExpr-67] - _ = x[SyncRType-68] - _ = x[SyncConvRTTI-69] -} - -const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabelMultiExprRTypeConvRTTI" - -var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458, 467, 472, 480} - -func (i SyncMarker) String() string { - i -= 1 - if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) { - return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")" - } - return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]] -} diff --git a/vendor/golang.org/x/tools/internal/pkgbits/version.go b/vendor/golang.org/x/tools/internal/pkgbits/version.go deleted file mode 100644 index 0db96527..00000000 --- a/vendor/golang.org/x/tools/internal/pkgbits/version.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2024 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 pkgbits - -// Version indicates a version of a unified IR bitstream. -// Each Version indicates the addition, removal, or change of -// new data in the bitstream. -// -// These are serialized to disk and the interpretation remains fixed. -type Version uint32 - -const ( - // V0: initial prototype. - // - // All data that is not assigned a Field is in version V0 - // and has not been deprecated. - V0 Version = iota - - // V1: adds the Flags uint32 word - V1 - - // V2: removes unused legacy fields and supports type parameters for aliases. - // - remove the legacy "has init" bool from the public root - // - remove obj's "derived func instance" bool - // - add a TypeParamNames field to ObjAlias - // - remove derived info "needed" bool - V2 - - // V3: introduces a more compact format for composite literal element lists - // - negative lengths indicate that (some) elements may have keys - // - positive lengths indicate that no element has a key - // - a negative struct field index indicates an embedded field - V3 - - // V4: encodes generic methods as standalone function objects - V4 - - numVersions = iota -) - -// Field denotes a unit of data in the serialized unified IR bitstream. -// It is conceptually a like field in a structure. -// -// We only really need Fields when the data may or may not be present -// in a stream based on the Version of the bitstream. -// -// Unlike much of pkgbits, Fields are not serialized and -// can change values as needed. -type Field int - -const ( - // Flags in a uint32 in the header of a bitstream - // that is used to indicate whether optional features are enabled. - Flags Field = iota - - // Deprecated: HasInit was a bool indicating whether a package - // has any init functions. - HasInit - - // Deprecated: DerivedFuncInstance was a bool indicating - // whether an object was a function instance. - DerivedFuncInstance - - // ObjAlias has a list of TypeParamNames. - AliasTypeParamNames - - // Deprecated: DerivedInfoNeeded was a bool indicating - // whether a type was a derived type. - DerivedInfoNeeded - - // Composite literals use a more compact format for element lists. - CompactCompLiterals - - // Generic methods may appear as standalone function objects. - GenericMethods - - numFields = iota -) - -// introduced is the version a field was added. -var introduced = [numFields]Version{ - Flags: V1, - AliasTypeParamNames: V2, - CompactCompLiterals: V3, - GenericMethods: V4, -} - -// removed is the version a field was removed in or 0 for fields -// that have not yet been deprecated. -// (So removed[f]-1 is the last version it is included in.) -var removed = [numFields]Version{ - HasInit: V2, - DerivedFuncInstance: V2, - DerivedInfoNeeded: V2, -} - -// Has reports whether field f is present in a bitstream at version v. -func (v Version) Has(f Field) bool { - return introduced[f] <= v && (v < removed[f] || removed[f] == V0) -} diff --git a/vendor/golang.org/x/tools/internal/stdlib/deps.go b/vendor/golang.org/x/tools/internal/stdlib/deps.go deleted file mode 100644 index dacfc1df..00000000 --- a/vendor/golang.org/x/tools/internal/stdlib/deps.go +++ /dev/null @@ -1,527 +0,0 @@ -// Copyright 2025 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. - -// Code generated by generate.go. DO NOT EDIT. - -package stdlib - -type pkginfo struct { - name string - deps string // list of indices of dependencies, as varint-encoded deltas -} - -var deps = [...]pkginfo{ - {"archive/tar", "\x03q\x03F=\x01\n\x01$\x01\x01\x02\x05\b\x02\x01\x02\x02\r"}, - {"archive/zip", "\x02\x04g\a\x03\x13\x021=\x01+\x05\x01\x0f\x03\x02\x0f\x04"}, - {"bufio", "\x03q\x86\x01D\x15"}, - {"bytes", "t+[\x03\fH\x02\x02"}, - {"cmp", ""}, - {"compress/bzip2", "\x02\x02\xf6\x01A"}, - {"compress/flate", "\x02r\x03\x83\x01\f\x033\x01\x03"}, - {"compress/gzip", "\x02\x04g\a\x03\x15nU"}, - {"compress/lzw", "\x02r\x03\x83\x01"}, - {"compress/zlib", "\x02\x04g\a\x03\x13\x01o"}, - {"container/heap", "\xbc\x02"}, - {"container/list", ""}, - {"container/ring", ""}, - {"context", "t\\p\x01\x0e"}, - {"crypto", "\x8a\x01pC"}, - {"crypto/aes", "\x10\v\t\x99\x02"}, - {"crypto/cipher", "\x03!\x01\x01 \x12\x1c,Z"}, - {"crypto/des", "\x10\x16 .,\x9d\x01\x03"}, - {"crypto/dsa", "F\x03+\x86\x01\r"}, - {"crypto/ecdh", "\x03\v\r\x10\x04\x17\x03\x0f\x1c\x86\x01"}, - {"crypto/ecdsa", "\x0e\x05\x03\x05\x01\x10\b\v\x06\x01\x03\x0e\x01\x1c\x86\x01\r\x05L\x01"}, - {"crypto/ed25519", "\x0e\x1f\x12\a\x03\b\a\x1cI=C"}, - {"crypto/elliptic", "4@\x86\x01\r9"}, - {"crypto/fips140", "#\x05\x95\x01\x98\x01"}, - {"crypto/hkdf", "0\x15\x01.\x16"}, - {"crypto/hmac", "\x1b\x16\x14\x01\x122"}, - {"crypto/hpke", "\x03\v\x02\x03\x04\x01\f\x01\x05\x1f\x05\a\x01\x01\x1d\x03\x13\x16\x9b\x01\x1c"}, - {"crypto/internal/boring", "\x0e\x02\x0el"}, - {"crypto/internal/boring/bbig", "\x1b\xec\x01N"}, - {"crypto/internal/boring/bcache", "\xc1\x02\x14"}, - {"crypto/internal/boring/sig", ""}, - {"crypto/internal/constanttime", ""}, - {"crypto/internal/cryptotest", "\x03\r\v\b%\x10\x19\x06\x13\x12 \x04\x06\t\x19\x01\x11\x11\x1b\x01\a\x05\b\x03\x05\f"}, - {"crypto/internal/entropy", "K"}, - {"crypto/internal/entropy/v1.0.0", "D0\x95\x018\x14"}, - {"crypto/internal/fips140", "C1\xbf\x01\v\x17"}, - {"crypto/internal/fips140/aes", "\x03 \x03\x02\x14\x05\x01\x01\x05,\x95\x014"}, - {"crypto/internal/fips140/aes/gcm", "#\x01\x02\x02\x02\x12\x05\x01\x06,\x92\x01"}, - {"crypto/internal/fips140/alias", "\xd5\x02"}, - {"crypto/internal/fips140/bigmod", "(\x19\x01\x06,\x95\x01"}, - {"crypto/internal/fips140/check", "#\x0e\a\t\x02\xb7\x01["}, - {"crypto/internal/fips140/check/checktest", "(\x8b\x02\""}, - {"crypto/internal/fips140/drbg", "\x03\x1f\x01\x01\x04\x14\x05\n)\x86\x01\x0f7\x01"}, - {"crypto/internal/fips140/ecdh", "\x03 \x05\x02\n\r3\x86\x01\x0f7"}, - {"crypto/internal/fips140/ecdsa", "\x03 \x04\x01\x02\a\x03\x06:\x16pF"}, - {"crypto/internal/fips140/ed25519", "\x03 \x05\x02\x04\f:\xc9\x01\x03"}, - {"crypto/internal/fips140/edwards25519", "\x1f\t\a\x123\x95\x017"}, - {"crypto/internal/fips140/edwards25519/field", "(\x14\x053\x95\x01"}, - {"crypto/internal/fips140/hkdf", "\x03 \x05\t\a<\x16"}, - {"crypto/internal/fips140/hmac", "\x03 \x15\x01\x01:\x16"}, - {"crypto/internal/fips140/mldsa", "\x03\x1c\x04\x05\x02\x0e\x01\x03\x053\x95\x017"}, - {"crypto/internal/fips140/mlkem", "\x03 \x05\x02\x0f\x03\x053\xcc\x01"}, - {"crypto/internal/fips140/nistec", "\x1f\t\r\f3\x95\x01*\r\x15"}, - {"crypto/internal/fips140/nistec/fiat", "(\x148\x95\x01"}, - {"crypto/internal/fips140/pbkdf2", "\x03 \x05\t\a<\x16"}, - {"crypto/internal/fips140/rsa", "\x03\x1c\x04\x04\x01\x02\x0e\x01\x01\x028\x16pF"}, - {"crypto/internal/fips140/sha256", "\x03 \x1e\x01\x06,\x16\x7f"}, - {"crypto/internal/fips140/sha3", "\x03 \x19\x05\x012\x95\x01L"}, - {"crypto/internal/fips140/sha512", "\x03 \x1e\x01\x06,\x16\x7f"}, - {"crypto/internal/fips140/ssh", "(b"}, - {"crypto/internal/fips140/subtle", "\x1f\a\x1b\xc8\x01"}, - {"crypto/internal/fips140/tls12", "\x03 \x05\t\a\x02:\x16"}, - {"crypto/internal/fips140/tls13", "\x03 \x05\b\b\t3\x16"}, - {"crypto/internal/fips140cache", "\xb3\x02\r'"}, - {"crypto/internal/fips140deps", ""}, - {"crypto/internal/fips140deps/byteorder", "\xa0\x01"}, - {"crypto/internal/fips140deps/cpu", "\xb5\x01\a"}, - {"crypto/internal/fips140deps/godebug", "\xbd\x01"}, - {"crypto/internal/fips140deps/time", "\xcf\x02"}, - {"crypto/internal/fips140hash", "9\x1d4\xcb\x01"}, - {"crypto/internal/fips140only", "\x17\x13\x0e\x01\x01Pp"}, - {"crypto/internal/fips140test", ""}, - {"crypto/internal/impl", "\xbe\x02"}, - {"crypto/internal/rand", "\x1b\x0f s=["}, - {"crypto/internal/randutil", "\xfa\x01\x12"}, - {"crypto/internal/sysrand", "tq! \r\r\x01\x01\r\x06"}, - {"crypto/internal/sysrand/internal/seccomp", "t"}, - {"crypto/md5", "\x0e8.\x16\x16i"}, - {"crypto/mlkem", "\x0e%"}, - {"crypto/mlkem/mlkemtest", "3\x13\b&"}, - {"crypto/pbkdf2", "6\x0f\x01.\x16"}, - {"crypto/rand", "\x1b\x0f\x1c\x03+\x86\x01\rN"}, - {"crypto/rc4", "& .\xc9\x01"}, - {"crypto/rsa", "\x0e\r\x01\v\x10\x0e\x01\x03\b\a\x1c\x03\x133=\f\x01"}, - {"crypto/sha1", "\x0e\r+\x02,\x16\x16\x15T"}, - {"crypto/sha256", "\x0e\r\x1dR"}, - {"crypto/sha3", "\x0e+Q\xcb\x01"}, - {"crypto/sha512", "\x0e\r\x1fP"}, - {"crypto/subtle", "\x1f\x1d\x9f\x01z"}, - {"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x02\x01\x01\x01\t\x01\x18\x01\x0f\x01\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x13\x16\x15\b=\x16\x16\r\b\x01\x01\x01\x02\x01\x0e\x06\x02\x01\x0f"}, - {"crypto/tls/internal/fips140tls", "\x17\xaa\x02"}, - {"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x017\x06\x01\x01\x02\x05\x0e\x06\x02\x02\x03F\x03:\x01\x02\b\x01\x01\x02\a\x10\x05\x01\x06\a\b\x02\x01\x02\x0f\x02\x01\x01\x02\x03\x01"}, - {"crypto/x509/pkix", "j\x06\a\x90\x01H"}, - {"database/sql", "\x03\nQ\x16\x03\x83\x01\v\a\"\x05\b\x02\x03\x01\x0e\x02\x02\x02"}, - {"database/sql/driver", "\rg\x03\xb7\x01\x0f\x12"}, - {"debug/buildinfo", "\x03^\x02\x01\x01\b\a\x03g\x1a\x02\x01+\x0f "}, - {"debug/dwarf", "\x03j\a\x03\x83\x011\x11\x01\x01"}, - {"debug/elf", "\x03\x06W\r\a\x03g\x1b\x01\f \x17\x01\x17"}, - {"debug/gosym", "\x03j\n$\xa1\x01\x01\x01\x02"}, - {"debug/macho", "\x03\x06W\r\ng\x1c,\x17\x01"}, - {"debug/pe", "\x03\x06W\r\a\x03g\x1c,\x17\x01\x17"}, - {"debug/plan9obj", "m\a\x03g\x1c,"}, - {"embed", "t+B\x19\x01T"}, - {"embed/internal/embedtest", ""}, - {"encoding", ""}, - {"encoding/ascii85", "\xfa\x01C"}, - {"encoding/asn1", "\x03q\x03g(\x01'\r\x02\x01\x11\x03\x01"}, - {"encoding/base32", "\xfa\x01A\x02"}, - {"encoding/base64", "\xa0\x01ZA\x02"}, - {"encoding/binary", "t\x86\x01\f(\r\x05"}, - {"encoding/csv", "\x02\x01q\x03\x83\x01D\x13\x02"}, - {"encoding/gob", "\x02f\x05\a\x03g\x1c\v\x01\x03\x1d\b\x12\x01\x10\x02"}, - {"encoding/hex", "t\x03\x83\x01A\x03"}, - {"encoding/json", "\x03\x01d\x04\b\x03\x83\x01\f(\r\x02\x01\x02\x11\x01\x01\x02"}, - {"encoding/pem", "\x03i\b\x86\x01A\x03"}, - {"encoding/xml", "\x02\x01e\f\x03\x83\x014\x05\n\x01\x02\x11\x02"}, - {"errors", "\xd0\x01\x85\x01"}, - {"expvar", "qLA\b\v\x15\r\b\x02\x03\x01\x12"}, - {"flag", "h\f\x03\x83\x01,\b\x05\b\x02\x01\x11"}, - {"fmt", "tF'\x19\f \b\r\x02\x03\x13"}, - {"go/ast", "\x03\x01s\x0f\x01s\x03)\b\r\x02\x01\x13\x02"}, - {"go/build", "\x02\x01q\x03\x01\x02\x02\b\x02\x01\x17\x1f\x04\x02\b\x1c\x13\x01+\x01\x04\x01\a\b\x02\x01\x13\x02\x02"}, - {"go/build/constraint", "t\xc9\x01\x01\x13\x02"}, - {"go/constant", "w\x10\x7f\x01\x024\x01\x02\x13"}, - {"go/doc", "\x04s\x01\x05\n=61\x10\x02\x01\x13\x02"}, - {"go/doc/comment", "\x03t\xc4\x01\x01\x01\x01\x13\x02"}, - {"go/format", "\x03t\x01\f\x01\x02sD"}, - {"go/importer", "y\a\x01\x02\x04\x01r9"}, - {"go/internal/gccgoimporter", "\x02\x01^\x13\x03\x04\f\x01p\x02,\x01\x05\x11\x01\r\b"}, - {"go/internal/gcimporter", "\x02u\x10\x010\x05\r0,\x15\x03\x02"}, - {"go/internal/scannerhooks", "\x87\x01"}, - {"go/internal/srcimporter", "w\x01\x01\v\x03\x01r,\x01\x05\x12\x02\x15"}, - {"go/parser", "\x03q\x03\x01\x02\b\x04\x01s\x01+\x06\x12"}, - {"go/printer", "w\x01\x02\x03\ns\f \x15\x02\x01\x02\f\x05\x02"}, - {"go/scanner", "\x03t\v\x05s2\x10\x01\x14\x02"}, - {"go/token", "\x04s\x86\x01>\x02\x03\x01\x10\x02"}, - {"go/types", "\x03\x01\x06j\x03\x01\x03\t\x03\x024\x063\x04\x03\t \x06\a\b\x01\x01\x01\x02\x01\x10\x02\x02"}, - {"go/version", "\xc2\x01|"}, - {"hash", "\xfa\x01"}, - {"hash/adler32", "t\x16\x16"}, - {"hash/crc32", "t\x16\x16\x15\x8b\x01\x01\x14"}, - {"hash/crc64", "t\x16\x16\xa0\x01"}, - {"hash/fnv", "t\x16\x16i"}, - {"hash/maphash", "\x8a\x01\x11<~"}, - {"html", "\xbe\x02\x02\x13"}, - {"html/template", "\x03n\x06\x19-=\x01\n!\x05\x01\x02\x03\f\x01\x02\r\x01\x03\x02"}, - {"image", "\x02r\x1fg\x0f4\x03\x01"}, - {"image/color", ""}, - {"image/color/palette", "\x93\x01"}, - {"image/draw", "\x92\x01\x01\x04"}, - {"image/gif", "\x02\x01\x05l\x03\x1b\x01\x01\x01\vZ\x0f"}, - {"image/internal/imageutil", "\x92\x01"}, - {"image/jpeg", "\x02r\x1e\x01\x04c"}, - {"image/png", "\x02\ad\n\x13\x02\x06\x01gC"}, - {"index/suffixarray", "\x03j\a\x86\x01\f+\n\x01"}, - {"internal/abi", "\xbc\x01\x99\x01"}, - {"internal/asan", "\xd5\x02"}, - {"internal/bisect", "\xb3\x02\r\x01"}, - {"internal/buildcfg", "wHg\x06\x02\x05\n\x01"}, - {"internal/bytealg", "\xb5\x01\xa0\x01"}, - {"internal/byteorder", ""}, - {"internal/cfg", ""}, - {"internal/cgrouptest", "w[T\x06\x0f\x02\x01\x04\x01"}, - {"internal/chacha8rand", "\xa0\x01\x15\a\x99\x01"}, - {"internal/copyright", ""}, - {"internal/coverage", ""}, - {"internal/coverage/calloc", ""}, - {"internal/coverage/cfile", "q\x06\x17\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01\"\x02',\x06\a\n\x01\x03\x0e\x06"}, - {"internal/coverage/cformat", "\x04s.\x04Q\v6\x01\x02\x0e"}, - {"internal/coverage/cmerge", "w.a"}, - {"internal/coverage/decodecounter", "m\n.\v\x02H,\x17\x18"}, - {"internal/coverage/decodemeta", "\x02k\n\x17\x17\v\x02H,"}, - {"internal/coverage/encodecounter", "\x02k\n.\f\x01\x02F\v!\x15"}, - {"internal/coverage/encodemeta", "\x02\x01j\n\x13\x04\x17\r\x02F,/"}, - {"internal/coverage/pods", "\x04s.\x81\x01\x06\x05\n\x02\x01"}, - {"internal/coverage/rtcov", "\xd5\x02"}, - {"internal/coverage/slicereader", "m\n\x83\x01["}, - {"internal/coverage/slicewriter", "w\x83\x01"}, - {"internal/coverage/stringtab", "w9\x04F"}, - {"internal/coverage/test", ""}, - {"internal/coverage/uleb128", ""}, - {"internal/cpu", "\xd5\x02"}, - {"internal/dag", "\x04s\xc4\x01\x03"}, - {"internal/diff", "\x03t\xc5\x01\x02"}, - {"internal/exportdata", "\x02\x01q\x03\x02e\x1c,\x01\x05\x11\x01\x02"}, - {"internal/filepathlite", "t+B\x1a@"}, - {"internal/fmtsort", "\x04\xaa\x02\r"}, - {"internal/fuzz", "\x03\nH\x18\x04\x03\x03\x01\f\x036=\f\x03\x1d\x01\x05\x02\x05\n\x01\x02\x01\x01\r\x04\x02"}, - {"internal/goarch", ""}, - {"internal/godebug", "\x9d\x01!\x82\x01\x01\x14"}, - {"internal/godebugs", ""}, - {"internal/goexperiment", ""}, - {"internal/goos", ""}, - {"internal/goroot", "\xa6\x02\x01\x05\x12\x02"}, - {"internal/gover", "\x04"}, - {"internal/goversion", ""}, - {"internal/lazyregexp", "\xa6\x02\v\r\x02"}, - {"internal/lazytemplate", "\xfa\x01,\x18\x02\r"}, - {"internal/msan", "\xd5\x02"}, - {"internal/nettrace", ""}, - {"internal/obscuretestdata", "l\x8e\x01,"}, - {"internal/oserror", "t"}, - {"internal/pkgbits", "\x03R\x18\a\x03\x04\fs\r\x1f\r\n\x01"}, - {"internal/platform", ""}, - {"internal/poll", "tl\x05\x159\r\x01\x01\r\x06"}, - {"internal/profile", "\x03\x04m\x03\x83\x017\n\x01\x01\x01\x11"}, - {"internal/profilerecord", ""}, - {"internal/race", "\x9b\x01\xba\x01"}, - {"internal/reflectlite", "\x9b\x01!;<\""}, - {"internal/runtime/atomic", "\xbc\x01\x99\x01"}, - {"internal/runtime/cgroup", "\x9f\x01=\x04u"}, - {"internal/runtime/exithook", "\xd1\x01\x84\x01"}, - {"internal/runtime/gc", "\xbc\x01"}, - {"internal/runtime/gc/internal/gen", "\nc\n\x18k\x04\v\x1d\b\x10\x02"}, - {"internal/runtime/gc/scan", "\xb5\x01\a\x18\az"}, - {"internal/runtime/maps", "\x9b\x01\x01 \n\t\t\x03z"}, - {"internal/runtime/math", "\xbc\x01"}, - {"internal/runtime/pprof/label", ""}, - {"internal/runtime/startlinetest", ""}, - {"internal/runtime/sys", "\xbc\x01\x04"}, - {"internal/runtime/syscall/linux", "\xbc\x01\x99\x01"}, - {"internal/runtime/wasitest", ""}, - {"internal/saferio", "\xfa\x01["}, - {"internal/singleflight", "\xc0\x02"}, - {"internal/strconv", "\x89\x02L"}, - {"internal/stringslite", "\x9f\x01\xb6\x01"}, - {"internal/sync", "\x9b\x01!\x13r\x14"}, - {"internal/synctest", "\x9b\x01\xba\x01"}, - {"internal/syscall/execenv", "\xc2\x02"}, - {"internal/syscall/unix", "\xb3\x02\x0e\x01\x13"}, - {"internal/sysinfo", "\x02\x01\xb2\x01E,\x18\x02"}, - {"internal/syslist", ""}, - {"internal/testenv", "\x03\ng\x02\x01*\x1b\x0f0+\x01\x05\a\n\x01\x02\x02\x01\f"}, - {"internal/testhash", "\x03\x87\x01p\x118\f"}, - {"internal/testlog", "\xc0\x02\x01\x14"}, - {"internal/testpty", "t\x03\xaf\x01"}, - {"internal/trace", "\x02\x01\x01\x06c\a\x03w\x03\x03\x06\x03\t+\n\x01\x01\x01\x11\x06"}, - {"internal/trace/internal/testgen", "\x03j\nu\x03\x02\x03\x011\v\r\x11"}, - {"internal/trace/internal/tracev1", "\x03\x01i\a\x03}\x06\f5\x01"}, - {"internal/trace/raw", "\x02k\nz\x03\x06C\x01\x13"}, - {"internal/trace/testtrace", "\x02\x01q\x03q\x04\x03\x05\x01\x05,\v\x02\b\x02\x01\x05"}, - {"internal/trace/tracev2", ""}, - {"internal/trace/traceviewer", "\x02d\v\x06\x1a<\x1f\a\a\x04\b\v\x15\x01\x05\a\n\x01\x02\x0f"}, - {"internal/trace/traceviewer/format", ""}, - {"internal/trace/version", "wz\t"}, - {"internal/txtar", "\x03t\xaf\x01\x18"}, - {"internal/types/errors", "\xbd\x02"}, - {"internal/unsafeheader", "\xd5\x02"}, - {"internal/xcoff", "`\r\a\x03g\x1c,\x17\x01"}, - {"internal/zstd", "m\a\x03\x83\x01\x0f"}, - {"io", "t\xcc\x01"}, - {"io/fs", "t+*11\x10\x14\x04"}, - {"io/ioutil", "\xfa\x01\x01+\x15\x03"}, - {"iter", "\xcf\x01d\""}, - {"log", "w\x83\x01\x05'\r\r\x01\x0e"}, - {"log/internal", ""}, - {"log/slog", "\x03\n[\t\x03\x03\x83\x01\x04\x01\x02\x02\x03(\x05\b\x02\x01\x02\x01\x0e\x02\x02\x02"}, - {"log/slog/internal", ""}, - {"log/slog/internal/benchmarks", "\rg\x03\x83\x01\x06\x03:\x12"}, - {"log/slog/internal/buffer", "\xc0\x02"}, - {"log/syslog", "t\x03\x87\x01\x12\x16\x18\x02\x0f"}, - {"maps", "\xfd\x01X"}, - {"math", "\xb5\x01TL"}, - {"math/big", "\x03q\x03)\x15E\f\x03\x020\x02\x01\x02\x15"}, - {"math/big/internal/asmgen", "\x03\x01s\x92\x012\x03"}, - {"math/bits", "\xd5\x02"}, - {"math/cmplx", "\x86\x02\x03"}, - {"math/rand", "\xbd\x01I:\x01\x14"}, - {"math/rand/v2", "t,\x03c\x03L"}, - {"mime", "\x02\x01i\b\x03\x83\x01\v!\x15\x03\x02\x11\x02"}, - {"mime/multipart", "\x02\x01N#\x03F=\v\x01\a\x02\x15\x02\x06\x0f\x02\x01\x17"}, - {"mime/quotedprintable", "\x02\x01t\x83\x01"}, - {"net", "\x04\tg+\x1e\n\x05\x13\x01\x01\x04\x15\x01%\x06\r\b\x05\x01\x01\r\x06\a"}, - {"net/http", "\x02\x01\x03\x01\x04\x02D\b\x13\x01\a\x03F=\x01\x03\a\x01\x03\x02\x02\x01\x02\x06\x02\x01\x01\n\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\x0e\x02\x02\x02\b\x01\x01\x01"}, - {"net/http/cgi", "\x02W\x1b\x03\x83\x01\x04\a\v\x01\x13\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x11\x0e"}, - {"net/http/cookiejar", "\x04p\x03\x99\x01\x01\b\a\x05\x16\x03\x02\x0f\x04"}, - {"net/http/fcgi", "\x02\x01\n`\a\x03\x83\x01\x16\x01\x01\x14\x18\x02\x0f"}, - {"net/http/httptest", "\x02\x01\nL\x02\x1b\x01\x83\x01\x04\x12\x01\n\t\x02\x17\x01\x02\x0f\x0e"}, - {"net/http/httptrace", "\rLnI\x14\n!"}, - {"net/http/httputil", "\x02\x01\ng\x03\x83\x01\x04\x0f\x03\x01\x05\x02\x01\v\x01\x19\x02\x01\x0e\x0e"}, - {"net/http/internal", "\x02\x01q\x03\x83\x01"}, - {"net/http/internal/ascii", "\xbe\x02\x13"}, - {"net/http/internal/httpcommon", "\rg\x03\x9f\x01\x0e\x01\x17\x01\x01\x02\x1d\x02"}, - {"net/http/internal/testcert", "\xbe\x02"}, - {"net/http/pprof", "\x02\x01\nj\x19-\x02\x0e-\x04\x13\x14\x01\r\x04\x03\x01\x02\x01\x11"}, - {"net/internal/cgotest", ""}, - {"net/internal/socktest", "w\xc9\x01\x02"}, - {"net/mail", "\x02r\x03\x83\x01\x04\x0f\x03\x14\x1a\x02\x0f\x04"}, - {"net/netip", "\x04p+\x01f\x034\x17"}, - {"net/rpc", "\x02m\x05\x03\x10\ni\x04\x12\x01\x1d\r\x03\x02"}, - {"net/rpc/jsonrpc", "q\x03\x03\x83\x01\x16\x11\x1f"}, - {"net/smtp", "\x194\f\x13\b\x03\x83\x01\x16\x14\x1a"}, - {"net/textproto", "\x02\x01q\x03\x83\x01\f\n-\x01\x02\x15"}, - {"net/url", "t\x03Fc\v\x10\x02\x01\x17"}, - {"os", "t+\x01\x19\x03\x10\x14\x01\x03\x01\x05\x10\x018\b\x05\x01\x01\r\x06"}, - {"os/exec", "\x03\ngI'\x01\x15\x01+\x06\a\n\x01\x03\x01\r"}, - {"os/exec/internal/fdtest", "\xc2\x02"}, - {"os/signal", "\r\x99\x02\x15\x05\x02"}, - {"os/user", "\x02\x01q\x03\x83\x01,\r\n\x01\x02"}, - {"path", "t+\xb4\x01"}, - {"path/filepath", "t+\x1aB+\r\b\x03\x04\x11"}, - {"plugin", "t"}, - {"reflect", "t'\x04\x1d\x13\b\x04\x05\x17\x06\t-\n\x03\x11\x02\x02"}, - {"reflect/internal/example1", ""}, - {"reflect/internal/example2", ""}, - {"regexp", "\x03\xf7\x018\t\x02\x01\x02\x11\x02"}, - {"regexp/syntax", "\xbb\x02\x01\x01\x01\x02\x11\x02"}, - {"runtime", "\x9b\x01\x04\x01\x03\f\x06\a\x02\x01\x01\x0e\x03\x01\x01\x01\x02\x01\x01\x01\x02\x01\x04\x01\x10\x18L"}, - {"runtime/coverage", "\xa7\x01S"}, - {"runtime/debug", "wUZ\r\b\x02\x01\x11\x06"}, - {"runtime/metrics", "\xbe\x01H-\""}, - {"runtime/pprof", "\x02\x01\x01\x03\x06`\a\x03$$\x0f\v!\f \r\b\x01\x01\x01\x02\x02\n\x03\x06"}, - {"runtime/race", "\xb9\x02"}, - {"runtime/race/internal/amd64v1", ""}, - {"runtime/trace", "\rg\x03z\t9\b\x05\x01\x0e\x06"}, - {"slices", "\x04\xf9\x01\fL"}, - {"sort", "\xd0\x0192"}, - {"strconv", "t+A\x01r"}, - {"strings", "t'\x04B\x19\x03\f7\x11\x02\x02"}, - {"structs", ""}, - {"sync", "\xcf\x01\x13\x01P\x0e\x14"}, - {"sync/atomic", "\xd5\x02"}, - {"syscall", "t(\x03\x01\x1c\n\x03\x06\r\x04S\b\x05\x01\x14"}, - {"testing", "\x03\ng\x02\x01X\x17\x14\f\x05\x1b\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\x0e\x02\x04"}, - {"testing/cryptotest", "QOZ\x124\x03\x12"}, - {"testing/fstest", "t\x03\x83\x01\x01\n&\x10\x03\t\b"}, - {"testing/internal/testdeps", "\x02\v\xae\x01/\x10,\x03\x05\x03\x06\a\x02\x0f"}, - {"testing/iotest", "\x03q\x03\x83\x01\x04"}, - {"testing/quick", "v\x01\x8f\x01\x05#\x10\x11"}, - {"testing/slogtest", "\rg\x03\x89\x01.\x05\x10\f"}, - {"testing/synctest", "\xe3\x01`\x12"}, - {"text/scanner", "\x03t\x83\x01,+\x02"}, - {"text/tabwriter", "w\x83\x01Y"}, - {"text/template", "t\x03C@\x01\n \x01\x05\x01\x02\x05\v\x02\x0e\x03\x02"}, - {"text/template/parse", "\x03t\xbc\x01\n\x01\x13\x02"}, - {"time", "t+\x1e$(*\r\x02\x13"}, - {"time/tzdata", "t\xce\x01\x13"}, - {"unicode", ""}, - {"unicode/utf16", ""}, - {"unicode/utf8", ""}, - {"unique", "\x9b\x01!%\x01Q\r\x01\x14\x12"}, - {"unsafe", ""}, - {"vendor/golang.org/x/crypto/chacha20", "\x10]\a\x95\x01*'"}, - {"vendor/golang.org/x/crypto/chacha20poly1305", "\x10\aV\a\xe2\x01\x04\x01\a"}, - {"vendor/golang.org/x/crypto/cryptobyte", "j\n\x03\x90\x01'!\n"}, - {"vendor/golang.org/x/crypto/cryptobyte/asn1", ""}, - {"vendor/golang.org/x/crypto/internal/alias", "\xd5\x02"}, - {"vendor/golang.org/x/crypto/internal/poly1305", "X\x15\x9c\x01"}, - {"vendor/golang.org/x/net/dns/dnsmessage", "t\xc7\x01"}, - {"vendor/golang.org/x/net/http/httpguts", "\x90\x02\x14\x1a\x15\r"}, - {"vendor/golang.org/x/net/http/httpproxy", "t\x03\x99\x01\x10\x05\x01\x18\x15\r"}, - {"vendor/golang.org/x/net/http2/hpack", "\x03q\x03\x83\x01F"}, - {"vendor/golang.org/x/net/idna", "w\x8f\x018\x15\x10\x02\x01"}, - {"vendor/golang.org/x/net/nettest", "\x03j\a\x03\x83\x01\x11\x05\x16\x01\f\n\x01\x02\x02\x01\f"}, - {"vendor/golang.org/x/sys/cpu", "\xa6\x02\r\n\x01\x17"}, - {"vendor/golang.org/x/text/secure/bidirule", "t\xdf\x01\x11\x01"}, - {"vendor/golang.org/x/text/transform", "\x03q\x86\x01Y"}, - {"vendor/golang.org/x/text/unicode/bidi", "\x03\bl\x87\x01>\x17"}, - {"vendor/golang.org/x/text/unicode/norm", "m\n\x83\x01F\x13\x11"}, - {"weak", "\x9b\x01\x98\x01\""}, -} - -// bootstrap is the list of bootstrap packages extracted from cmd/dist. -var bootstrap = map[string]bool{ - "cmp": true, - "cmd/asm": true, - "cmd/asm/internal/arch": true, - "cmd/asm/internal/asm": true, - "cmd/asm/internal/flags": true, - "cmd/asm/internal/lex": true, - "cmd/cgo": true, - "cmd/compile": true, - "cmd/compile/internal/abi": true, - "cmd/compile/internal/abt": true, - "cmd/compile/internal/amd64": true, - "cmd/compile/internal/arm": true, - "cmd/compile/internal/arm64": true, - "cmd/compile/internal/base": true, - "cmd/compile/internal/bitvec": true, - "cmd/compile/internal/bloop": true, - "cmd/compile/internal/compare": true, - "cmd/compile/internal/coverage": true, - "cmd/compile/internal/deadlocals": true, - "cmd/compile/internal/devirtualize": true, - "cmd/compile/internal/dwarfgen": true, - "cmd/compile/internal/escape": true, - "cmd/compile/internal/gc": true, - "cmd/compile/internal/importer": true, - "cmd/compile/internal/inline": true, - "cmd/compile/internal/inline/inlheur": true, - "cmd/compile/internal/inline/interleaved": true, - "cmd/compile/internal/ir": true, - "cmd/compile/internal/liveness": true, - "cmd/compile/internal/logopt": true, - "cmd/compile/internal/loong64": true, - "cmd/compile/internal/loopvar": true, - "cmd/compile/internal/mips": true, - "cmd/compile/internal/mips64": true, - "cmd/compile/internal/noder": true, - "cmd/compile/internal/objw": true, - "cmd/compile/internal/pgoir": true, - "cmd/compile/internal/pkginit": true, - "cmd/compile/internal/ppc64": true, - "cmd/compile/internal/rangefunc": true, - "cmd/compile/internal/reflectdata": true, - "cmd/compile/internal/riscv64": true, - "cmd/compile/internal/rttype": true, - "cmd/compile/internal/s390x": true, - "cmd/compile/internal/slice": true, - "cmd/compile/internal/ssa": true, - "cmd/compile/internal/ssagen": true, - "cmd/compile/internal/staticdata": true, - "cmd/compile/internal/staticinit": true, - "cmd/compile/internal/syntax": true, - "cmd/compile/internal/test": true, - "cmd/compile/internal/typebits": true, - "cmd/compile/internal/typecheck": true, - "cmd/compile/internal/types": true, - "cmd/compile/internal/types2": true, - "cmd/compile/internal/walk": true, - "cmd/compile/internal/wasm": true, - "cmd/compile/internal/x86": true, - "cmd/internal/archive": true, - "cmd/internal/bio": true, - "cmd/internal/codesign": true, - "cmd/internal/dwarf": true, - "cmd/internal/edit": true, - "cmd/internal/gcprog": true, - "cmd/internal/goobj": true, - "cmd/internal/hash": true, - "cmd/internal/macho": true, - "cmd/internal/obj": true, - "cmd/internal/obj/arm": true, - "cmd/internal/obj/arm64": true, - "cmd/internal/obj/loong64": true, - "cmd/internal/obj/mips": true, - "cmd/internal/obj/ppc64": true, - "cmd/internal/obj/riscv": true, - "cmd/internal/obj/s390x": true, - "cmd/internal/obj/wasm": true, - "cmd/internal/obj/x86": true, - "cmd/internal/objabi": true, - "cmd/internal/par": true, - "cmd/internal/pgo": true, - "cmd/internal/pkgpath": true, - "cmd/internal/quoted": true, - "cmd/internal/src": true, - "cmd/internal/sys": true, - "cmd/internal/telemetry": true, - "cmd/internal/telemetry/counter": true, - "cmd/link": true, - "cmd/link/internal/amd64": true, - "cmd/link/internal/arm": true, - "cmd/link/internal/arm64": true, - "cmd/link/internal/benchmark": true, - "cmd/link/internal/dwtest": true, - "cmd/link/internal/ld": true, - "cmd/link/internal/loadelf": true, - "cmd/link/internal/loader": true, - "cmd/link/internal/loadmacho": true, - "cmd/link/internal/loadpe": true, - "cmd/link/internal/loadxcoff": true, - "cmd/link/internal/loong64": true, - "cmd/link/internal/mips": true, - "cmd/link/internal/mips64": true, - "cmd/link/internal/ppc64": true, - "cmd/link/internal/riscv64": true, - "cmd/link/internal/s390x": true, - "cmd/link/internal/sym": true, - "cmd/link/internal/wasm": true, - "cmd/link/internal/x86": true, - "compress/flate": true, - "compress/zlib": true, - "container/heap": true, - "debug/dwarf": true, - "debug/elf": true, - "debug/macho": true, - "debug/pe": true, - "go/build/constraint": true, - "go/constant": true, - "go/version": true, - "internal/abi": true, - "internal/coverage": true, - "cmd/internal/cov/covcmd": true, - "internal/bisect": true, - "internal/buildcfg": true, - "internal/exportdata": true, - "internal/goarch": true, - "internal/godebugs": true, - "internal/goexperiment": true, - "internal/goroot": true, - "internal/gover": true, - "internal/goversion": true, - "internal/lazyregexp": true, - "internal/pkgbits": true, - "internal/platform": true, - "internal/profile": true, - "internal/race": true, - "internal/runtime/gc": true, - "internal/saferio": true, - "internal/syscall/unix": true, - "internal/types/errors": true, - "internal/unsafeheader": true, - "internal/xcoff": true, - "internal/zstd": true, - "math/bits": true, - "sort": true, -} - -// BootstrapVersion is the minor version of Go used during toolchain -// bootstrapping. Packages for which [IsBootstrapPackage] must not use -// features of Go newer than this version. -const BootstrapVersion = Version(24) // go1.24.6 diff --git a/vendor/golang.org/x/tools/internal/stdlib/import.go b/vendor/golang.org/x/tools/internal/stdlib/import.go deleted file mode 100644 index 8ecc672b..00000000 --- a/vendor/golang.org/x/tools/internal/stdlib/import.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2025 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 stdlib - -// This file provides the API for the import graph of the standard library. -// -// Be aware that the compiler-generated code for every package -// implicitly depends on package "runtime" and a handful of others -// (see runtimePkgs in GOROOT/src/cmd/internal/objabi/pkgspecial.go). - -import ( - "encoding/binary" - "iter" - "slices" - "strings" -) - -// Imports returns the sequence of packages directly imported by the -// named standard packages, in name order. -// The imports of an unknown package are the empty set. -// -// The graph is built into the application and may differ from the -// graph in the Go source tree being analyzed by the application. -func Imports(pkgs ...string) iter.Seq[string] { - return func(yield func(string) bool) { - for _, pkg := range pkgs { - if i, ok := find(pkg); ok { - var depIndex uint64 - for data := []byte(deps[i].deps); len(data) > 0; { - delta, n := binary.Uvarint(data) - depIndex += delta - if !yield(deps[depIndex].name) { - return - } - data = data[n:] - } - } - } - } -} - -// Dependencies returns the set of all dependencies of the named -// standard packages, including the initial package, -// in a deterministic topological order. -// The dependencies of an unknown package are the empty set. -// -// The graph is built into the application and may differ from the -// graph in the Go source tree being analyzed by the application. -func Dependencies(pkgs ...string) iter.Seq[string] { - return func(yield func(string) bool) { - for _, pkg := range pkgs { - if i, ok := find(pkg); ok { - var seen [1 + len(deps)/8]byte // bit set of seen packages - var visit func(i int) bool - visit = func(i int) bool { - bit := byte(1) << (i % 8) - if seen[i/8]&bit == 0 { - seen[i/8] |= bit - var depIndex uint64 - for data := []byte(deps[i].deps); len(data) > 0; { - delta, n := binary.Uvarint(data) - depIndex += delta - if !visit(int(depIndex)) { - return false - } - data = data[n:] - } - if !yield(deps[i].name) { - return false - } - } - return true - } - if !visit(i) { - return - } - } - } - } -} - -// find returns the index of pkg in the deps table. -func find(pkg string) (int, bool) { - return slices.BinarySearchFunc(deps[:], pkg, func(p pkginfo, n string) int { - return strings.Compare(p.name, n) - }) -} - -// IsBootstrapPackage reports whether pkg is one of the low-level -// packages in the Go distribution that must compile with the older -// language version specified by [BootstrapVersion] during toolchain -// bootstrapping; see golang.org/s/go15bootstrap. -func IsBootstrapPackage(pkg string) bool { - return bootstrap[pkg] -} diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go deleted file mode 100644 index 33e4f505..00000000 --- a/vendor/golang.org/x/tools/internal/stdlib/manifest.go +++ /dev/null @@ -1,18328 +0,0 @@ -// Copyright 2025 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. - -// Code generated by generate.go. DO NOT EDIT. - -package stdlib - -var PackageSymbols = map[string][]Symbol{ - "archive/tar": { - {"(*Header).FileInfo", Method, 1, ""}, - {"(*Reader).Next", Method, 0, ""}, - {"(*Reader).Read", Method, 0, ""}, - {"(*Writer).AddFS", Method, 22, ""}, - {"(*Writer).Close", Method, 0, ""}, - {"(*Writer).Flush", Method, 0, ""}, - {"(*Writer).Write", Method, 0, ""}, - {"(*Writer).WriteHeader", Method, 0, ""}, - {"(FileInfoNames).Gname", Method, 23, ""}, - {"(FileInfoNames).IsDir", Method, 23, ""}, - {"(FileInfoNames).ModTime", Method, 23, ""}, - {"(FileInfoNames).Mode", Method, 23, ""}, - {"(FileInfoNames).Name", Method, 23, ""}, - {"(FileInfoNames).Size", Method, 23, ""}, - {"(FileInfoNames).Sys", Method, 23, ""}, - {"(FileInfoNames).Uname", Method, 23, ""}, - {"(Format).String", Method, 10, ""}, - {"ErrFieldTooLong", Var, 0, ""}, - {"ErrHeader", Var, 0, ""}, - {"ErrInsecurePath", Var, 20, ""}, - {"ErrWriteAfterClose", Var, 0, ""}, - {"ErrWriteTooLong", Var, 0, ""}, - {"FileInfoHeader", Func, 1, "func(fi fs.FileInfo, link string) (*Header, error)"}, - {"FileInfoNames", Type, 23, ""}, - {"Format", Type, 10, ""}, - {"FormatGNU", Const, 10, ""}, - {"FormatPAX", Const, 10, ""}, - {"FormatUSTAR", Const, 10, ""}, - {"FormatUnknown", Const, 10, ""}, - {"Header", Type, 0, ""}, - {"Header.AccessTime", Field, 0, ""}, - {"Header.ChangeTime", Field, 0, ""}, - {"Header.Devmajor", Field, 0, ""}, - {"Header.Devminor", Field, 0, ""}, - {"Header.Format", Field, 10, ""}, - {"Header.Gid", Field, 0, ""}, - {"Header.Gname", Field, 0, ""}, - {"Header.Linkname", Field, 0, ""}, - {"Header.ModTime", Field, 0, ""}, - {"Header.Mode", Field, 0, ""}, - {"Header.Name", Field, 0, ""}, - {"Header.PAXRecords", Field, 10, ""}, - {"Header.Size", Field, 0, ""}, - {"Header.Typeflag", Field, 0, ""}, - {"Header.Uid", Field, 0, ""}, - {"Header.Uname", Field, 0, ""}, - {"Header.Xattrs", Field, 3, ""}, - {"NewReader", Func, 0, "func(r io.Reader) *Reader"}, - {"NewWriter", Func, 0, "func(w io.Writer) *Writer"}, - {"Reader", Type, 0, ""}, - {"TypeBlock", Const, 0, ""}, - {"TypeChar", Const, 0, ""}, - {"TypeCont", Const, 0, ""}, - {"TypeDir", Const, 0, ""}, - {"TypeFifo", Const, 0, ""}, - {"TypeGNULongLink", Const, 1, ""}, - {"TypeGNULongName", Const, 1, ""}, - {"TypeGNUSparse", Const, 3, ""}, - {"TypeLink", Const, 0, ""}, - {"TypeReg", Const, 0, ""}, - {"TypeRegA", Const, 0, ""}, - {"TypeSymlink", Const, 0, ""}, - {"TypeXGlobalHeader", Const, 0, ""}, - {"TypeXHeader", Const, 0, ""}, - {"Writer", Type, 0, ""}, - }, - "archive/zip": { - {"(*File).DataOffset", Method, 2, ""}, - {"(*File).FileInfo", Method, 0, ""}, - {"(*File).ModTime", Method, 0, ""}, - {"(*File).Mode", Method, 0, ""}, - {"(*File).Open", Method, 0, ""}, - {"(*File).OpenRaw", Method, 17, ""}, - {"(*File).SetModTime", Method, 0, ""}, - {"(*File).SetMode", Method, 0, ""}, - {"(*FileHeader).FileInfo", Method, 0, ""}, - {"(*FileHeader).ModTime", Method, 0, ""}, - {"(*FileHeader).Mode", Method, 0, ""}, - {"(*FileHeader).SetModTime", Method, 0, ""}, - {"(*FileHeader).SetMode", Method, 0, ""}, - {"(*ReadCloser).Close", Method, 0, ""}, - {"(*ReadCloser).Open", Method, 16, ""}, - {"(*ReadCloser).RegisterDecompressor", Method, 6, ""}, - {"(*Reader).Open", Method, 16, ""}, - {"(*Reader).RegisterDecompressor", Method, 6, ""}, - {"(*Writer).AddFS", Method, 22, ""}, - {"(*Writer).Close", Method, 0, ""}, - {"(*Writer).Copy", Method, 17, ""}, - {"(*Writer).Create", Method, 0, ""}, - {"(*Writer).CreateHeader", Method, 0, ""}, - {"(*Writer).CreateRaw", Method, 17, ""}, - {"(*Writer).Flush", Method, 4, ""}, - {"(*Writer).RegisterCompressor", Method, 6, ""}, - {"(*Writer).SetComment", Method, 10, ""}, - {"(*Writer).SetOffset", Method, 5, ""}, - {"Compressor", Type, 2, ""}, - {"Decompressor", Type, 2, ""}, - {"Deflate", Const, 0, ""}, - {"ErrAlgorithm", Var, 0, ""}, - {"ErrChecksum", Var, 0, ""}, - {"ErrFormat", Var, 0, ""}, - {"ErrInsecurePath", Var, 20, ""}, - {"File", Type, 0, ""}, - {"File.FileHeader", Field, 0, ""}, - {"FileHeader", Type, 0, ""}, - {"FileHeader.CRC32", Field, 0, ""}, - {"FileHeader.Comment", Field, 0, ""}, - {"FileHeader.CompressedSize", Field, 0, ""}, - {"FileHeader.CompressedSize64", Field, 1, ""}, - {"FileHeader.CreatorVersion", Field, 0, ""}, - {"FileHeader.ExternalAttrs", Field, 0, ""}, - {"FileHeader.Extra", Field, 0, ""}, - {"FileHeader.Flags", Field, 0, ""}, - {"FileHeader.Method", Field, 0, ""}, - {"FileHeader.Modified", Field, 10, ""}, - {"FileHeader.ModifiedDate", Field, 0, ""}, - {"FileHeader.ModifiedTime", Field, 0, ""}, - {"FileHeader.Name", Field, 0, ""}, - {"FileHeader.NonUTF8", Field, 10, ""}, - {"FileHeader.ReaderVersion", Field, 0, ""}, - {"FileHeader.UncompressedSize", Field, 0, ""}, - {"FileHeader.UncompressedSize64", Field, 1, ""}, - {"FileInfoHeader", Func, 0, "func(fi fs.FileInfo) (*FileHeader, error)"}, - {"NewReader", Func, 0, "func(r io.ReaderAt, size int64) (*Reader, error)"}, - {"NewWriter", Func, 0, "func(w io.Writer) *Writer"}, - {"OpenReader", Func, 0, "func(name string) (*ReadCloser, error)"}, - {"ReadCloser", Type, 0, ""}, - {"ReadCloser.Reader", Field, 0, ""}, - {"Reader", Type, 0, ""}, - {"Reader.Comment", Field, 0, ""}, - {"Reader.File", Field, 0, ""}, - {"RegisterCompressor", Func, 2, "func(method uint16, comp Compressor)"}, - {"RegisterDecompressor", Func, 2, "func(method uint16, dcomp Decompressor)"}, - {"Store", Const, 0, ""}, - {"Writer", Type, 0, ""}, - }, - "bufio": { - {"(*Reader).Buffered", Method, 0, ""}, - {"(*Reader).Discard", Method, 5, ""}, - {"(*Reader).Peek", Method, 0, ""}, - {"(*Reader).Read", Method, 0, ""}, - {"(*Reader).ReadByte", Method, 0, ""}, - {"(*Reader).ReadBytes", Method, 0, ""}, - {"(*Reader).ReadLine", Method, 0, ""}, - {"(*Reader).ReadRune", Method, 0, ""}, - {"(*Reader).ReadSlice", Method, 0, ""}, - {"(*Reader).ReadString", Method, 0, ""}, - {"(*Reader).Reset", Method, 2, ""}, - {"(*Reader).Size", Method, 10, ""}, - {"(*Reader).UnreadByte", Method, 0, ""}, - {"(*Reader).UnreadRune", Method, 0, ""}, - {"(*Reader).WriteTo", Method, 1, ""}, - {"(*Scanner).Buffer", Method, 6, ""}, - {"(*Scanner).Bytes", Method, 1, ""}, - {"(*Scanner).Err", Method, 1, ""}, - {"(*Scanner).Scan", Method, 1, ""}, - {"(*Scanner).Split", Method, 1, ""}, - {"(*Scanner).Text", Method, 1, ""}, - {"(*Writer).Available", Method, 0, ""}, - {"(*Writer).AvailableBuffer", Method, 18, ""}, - {"(*Writer).Buffered", Method, 0, ""}, - {"(*Writer).Flush", Method, 0, ""}, - {"(*Writer).ReadFrom", Method, 1, ""}, - {"(*Writer).Reset", Method, 2, ""}, - {"(*Writer).Size", Method, 10, ""}, - {"(*Writer).Write", Method, 0, ""}, - {"(*Writer).WriteByte", Method, 0, ""}, - {"(*Writer).WriteRune", Method, 0, ""}, - {"(*Writer).WriteString", Method, 0, ""}, - {"(ReadWriter).Available", Method, 0, ""}, - {"(ReadWriter).AvailableBuffer", Method, 18, ""}, - {"(ReadWriter).Discard", Method, 5, ""}, - {"(ReadWriter).Flush", Method, 0, ""}, - {"(ReadWriter).Peek", Method, 0, ""}, - {"(ReadWriter).Read", Method, 0, ""}, - {"(ReadWriter).ReadByte", Method, 0, ""}, - {"(ReadWriter).ReadBytes", Method, 0, ""}, - {"(ReadWriter).ReadFrom", Method, 1, ""}, - {"(ReadWriter).ReadLine", Method, 0, ""}, - {"(ReadWriter).ReadRune", Method, 0, ""}, - {"(ReadWriter).ReadSlice", Method, 0, ""}, - {"(ReadWriter).ReadString", Method, 0, ""}, - {"(ReadWriter).UnreadByte", Method, 0, ""}, - {"(ReadWriter).UnreadRune", Method, 0, ""}, - {"(ReadWriter).Write", Method, 0, ""}, - {"(ReadWriter).WriteByte", Method, 0, ""}, - {"(ReadWriter).WriteRune", Method, 0, ""}, - {"(ReadWriter).WriteString", Method, 0, ""}, - {"(ReadWriter).WriteTo", Method, 1, ""}, - {"ErrAdvanceTooFar", Var, 1, ""}, - {"ErrBadReadCount", Var, 15, ""}, - {"ErrBufferFull", Var, 0, ""}, - {"ErrFinalToken", Var, 6, ""}, - {"ErrInvalidUnreadByte", Var, 0, ""}, - {"ErrInvalidUnreadRune", Var, 0, ""}, - {"ErrNegativeAdvance", Var, 1, ""}, - {"ErrNegativeCount", Var, 0, ""}, - {"ErrTooLong", Var, 1, ""}, - {"MaxScanTokenSize", Const, 1, ""}, - {"NewReadWriter", Func, 0, "func(r *Reader, w *Writer) *ReadWriter"}, - {"NewReader", Func, 0, "func(rd io.Reader) *Reader"}, - {"NewReaderSize", Func, 0, "func(rd io.Reader, size int) *Reader"}, - {"NewScanner", Func, 1, "func(r io.Reader) *Scanner"}, - {"NewWriter", Func, 0, "func(w io.Writer) *Writer"}, - {"NewWriterSize", Func, 0, "func(w io.Writer, size int) *Writer"}, - {"ReadWriter", Type, 0, ""}, - {"ReadWriter.Reader", Field, 0, ""}, - {"ReadWriter.Writer", Field, 0, ""}, - {"Reader", Type, 0, ""}, - {"ScanBytes", Func, 1, "func(data []byte, atEOF bool) (advance int, token []byte, err error)"}, - {"ScanLines", Func, 1, "func(data []byte, atEOF bool) (advance int, token []byte, err error)"}, - {"ScanRunes", Func, 1, "func(data []byte, atEOF bool) (advance int, token []byte, err error)"}, - {"ScanWords", Func, 1, "func(data []byte, atEOF bool) (advance int, token []byte, err error)"}, - {"Scanner", Type, 1, ""}, - {"SplitFunc", Type, 1, ""}, - {"Writer", Type, 0, ""}, - }, - "bytes": { - {"(*Buffer).Available", Method, 21, ""}, - {"(*Buffer).AvailableBuffer", Method, 21, ""}, - {"(*Buffer).Bytes", Method, 0, ""}, - {"(*Buffer).Cap", Method, 5, ""}, - {"(*Buffer).Grow", Method, 1, ""}, - {"(*Buffer).Len", Method, 0, ""}, - {"(*Buffer).Next", Method, 0, ""}, - {"(*Buffer).Peek", Method, 26, ""}, - {"(*Buffer).Read", Method, 0, ""}, - {"(*Buffer).ReadByte", Method, 0, ""}, - {"(*Buffer).ReadBytes", Method, 0, ""}, - {"(*Buffer).ReadFrom", Method, 0, ""}, - {"(*Buffer).ReadRune", Method, 0, ""}, - {"(*Buffer).ReadString", Method, 0, ""}, - {"(*Buffer).Reset", Method, 0, ""}, - {"(*Buffer).String", Method, 0, ""}, - {"(*Buffer).Truncate", Method, 0, ""}, - {"(*Buffer).UnreadByte", Method, 0, ""}, - {"(*Buffer).UnreadRune", Method, 0, ""}, - {"(*Buffer).Write", Method, 0, ""}, - {"(*Buffer).WriteByte", Method, 0, ""}, - {"(*Buffer).WriteRune", Method, 0, ""}, - {"(*Buffer).WriteString", Method, 0, ""}, - {"(*Buffer).WriteTo", Method, 0, ""}, - {"(*Reader).Len", Method, 0, ""}, - {"(*Reader).Read", Method, 0, ""}, - {"(*Reader).ReadAt", Method, 0, ""}, - {"(*Reader).ReadByte", Method, 0, ""}, - {"(*Reader).ReadRune", Method, 0, ""}, - {"(*Reader).Reset", Method, 7, ""}, - {"(*Reader).Seek", Method, 0, ""}, - {"(*Reader).Size", Method, 5, ""}, - {"(*Reader).UnreadByte", Method, 0, ""}, - {"(*Reader).UnreadRune", Method, 0, ""}, - {"(*Reader).WriteTo", Method, 1, ""}, - {"Buffer", Type, 0, ""}, - {"Clone", Func, 20, "func(b []byte) []byte"}, - {"Compare", Func, 0, "func(a []byte, b []byte) int"}, - {"Contains", Func, 0, "func(b []byte, subslice []byte) bool"}, - {"ContainsAny", Func, 7, "func(b []byte, chars string) bool"}, - {"ContainsFunc", Func, 21, "func(b []byte, f func(rune) bool) bool"}, - {"ContainsRune", Func, 7, "func(b []byte, r rune) bool"}, - {"Count", Func, 0, "func(s []byte, sep []byte) int"}, - {"Cut", Func, 18, "func(s []byte, sep []byte) (before []byte, after []byte, found bool)"}, - {"CutPrefix", Func, 20, "func(s []byte, prefix []byte) (after []byte, found bool)"}, - {"CutSuffix", Func, 20, "func(s []byte, suffix []byte) (before []byte, found bool)"}, - {"Equal", Func, 0, "func(a []byte, b []byte) bool"}, - {"EqualFold", Func, 0, "func(s []byte, t []byte) bool"}, - {"ErrTooLarge", Var, 0, ""}, - {"Fields", Func, 0, "func(s []byte) [][]byte"}, - {"FieldsFunc", Func, 0, "func(s []byte, f func(rune) bool) [][]byte"}, - {"FieldsFuncSeq", Func, 24, "func(s []byte, f func(rune) bool) iter.Seq[[]byte]"}, - {"FieldsSeq", Func, 24, "func(s []byte) iter.Seq[[]byte]"}, - {"HasPrefix", Func, 0, "func(s []byte, prefix []byte) bool"}, - {"HasSuffix", Func, 0, "func(s []byte, suffix []byte) bool"}, - {"Index", Func, 0, "func(s []byte, sep []byte) int"}, - {"IndexAny", Func, 0, "func(s []byte, chars string) int"}, - {"IndexByte", Func, 0, "func(b []byte, c byte) int"}, - {"IndexFunc", Func, 0, "func(s []byte, f func(r rune) bool) int"}, - {"IndexRune", Func, 0, "func(s []byte, r rune) int"}, - {"Join", Func, 0, "func(s [][]byte, sep []byte) []byte"}, - {"LastIndex", Func, 0, "func(s []byte, sep []byte) int"}, - {"LastIndexAny", Func, 0, "func(s []byte, chars string) int"}, - {"LastIndexByte", Func, 5, "func(s []byte, c byte) int"}, - {"LastIndexFunc", Func, 0, "func(s []byte, f func(r rune) bool) int"}, - {"Lines", Func, 24, "func(s []byte) iter.Seq[[]byte]"}, - {"Map", Func, 0, "func(mapping func(r rune) rune, s []byte) []byte"}, - {"MinRead", Const, 0, ""}, - {"NewBuffer", Func, 0, "func(buf []byte) *Buffer"}, - {"NewBufferString", Func, 0, "func(s string) *Buffer"}, - {"NewReader", Func, 0, "func(b []byte) *Reader"}, - {"Reader", Type, 0, ""}, - {"Repeat", Func, 0, "func(b []byte, count int) []byte"}, - {"Replace", Func, 0, "func(s []byte, old []byte, new []byte, n int) []byte"}, - {"ReplaceAll", Func, 12, "func(s []byte, old []byte, new []byte) []byte"}, - {"Runes", Func, 0, "func(s []byte) []rune"}, - {"Split", Func, 0, "func(s []byte, sep []byte) [][]byte"}, - {"SplitAfter", Func, 0, "func(s []byte, sep []byte) [][]byte"}, - {"SplitAfterN", Func, 0, "func(s []byte, sep []byte, n int) [][]byte"}, - {"SplitAfterSeq", Func, 24, "func(s []byte, sep []byte) iter.Seq[[]byte]"}, - {"SplitN", Func, 0, "func(s []byte, sep []byte, n int) [][]byte"}, - {"SplitSeq", Func, 24, "func(s []byte, sep []byte) iter.Seq[[]byte]"}, - {"Title", Func, 0, "func(s []byte) []byte"}, - {"ToLower", Func, 0, "func(s []byte) []byte"}, - {"ToLowerSpecial", Func, 0, "func(c unicode.SpecialCase, s []byte) []byte"}, - {"ToTitle", Func, 0, "func(s []byte) []byte"}, - {"ToTitleSpecial", Func, 0, "func(c unicode.SpecialCase, s []byte) []byte"}, - {"ToUpper", Func, 0, "func(s []byte) []byte"}, - {"ToUpperSpecial", Func, 0, "func(c unicode.SpecialCase, s []byte) []byte"}, - {"ToValidUTF8", Func, 13, "func(s []byte, replacement []byte) []byte"}, - {"Trim", Func, 0, "func(s []byte, cutset string) []byte"}, - {"TrimFunc", Func, 0, "func(s []byte, f func(r rune) bool) []byte"}, - {"TrimLeft", Func, 0, "func(s []byte, cutset string) []byte"}, - {"TrimLeftFunc", Func, 0, "func(s []byte, f func(r rune) bool) []byte"}, - {"TrimPrefix", Func, 1, "func(s []byte, prefix []byte) []byte"}, - {"TrimRight", Func, 0, "func(s []byte, cutset string) []byte"}, - {"TrimRightFunc", Func, 0, "func(s []byte, f func(r rune) bool) []byte"}, - {"TrimSpace", Func, 0, "func(s []byte) []byte"}, - {"TrimSuffix", Func, 1, "func(s []byte, suffix []byte) []byte"}, - }, - "cmp": { - {"Compare", Func, 21, "func[T Ordered](x T, y T) int"}, - {"Less", Func, 21, "func[T Ordered](x T, y T) bool"}, - {"Or", Func, 22, "func[T comparable](vals ...T) T"}, - {"Ordered", Type, 21, ""}, - }, - "compress/bzip2": { - {"(StructuralError).Error", Method, 0, ""}, - {"NewReader", Func, 0, "func(r io.Reader) io.Reader"}, - {"StructuralError", Type, 0, ""}, - }, - "compress/flate": { - {"(*ReadError).Error", Method, 0, ""}, - {"(*WriteError).Error", Method, 0, ""}, - {"(*Writer).Close", Method, 0, ""}, - {"(*Writer).Flush", Method, 0, ""}, - {"(*Writer).Reset", Method, 2, ""}, - {"(*Writer).Write", Method, 0, ""}, - {"(CorruptInputError).Error", Method, 0, ""}, - {"(InternalError).Error", Method, 0, ""}, - {"(Reader).Read", Method, 0, ""}, - {"(Reader).ReadByte", Method, 0, ""}, - {"(Resetter).Reset", Method, 4, ""}, - {"BestCompression", Const, 0, ""}, - {"BestSpeed", Const, 0, ""}, - {"CorruptInputError", Type, 0, ""}, - {"DefaultCompression", Const, 0, ""}, - {"HuffmanOnly", Const, 7, ""}, - {"InternalError", Type, 0, ""}, - {"NewReader", Func, 0, "func(r io.Reader) io.ReadCloser"}, - {"NewReaderDict", Func, 0, "func(r io.Reader, dict []byte) io.ReadCloser"}, - {"NewWriter", Func, 0, "func(w io.Writer, level int) (*Writer, error)"}, - {"NewWriterDict", Func, 0, "func(w io.Writer, level int, dict []byte) (*Writer, error)"}, - {"NoCompression", Const, 0, ""}, - {"ReadError", Type, 0, ""}, - {"ReadError.Err", Field, 0, ""}, - {"ReadError.Offset", Field, 0, ""}, - {"Reader", Type, 0, ""}, - {"Resetter", Type, 4, ""}, - {"WriteError", Type, 0, ""}, - {"WriteError.Err", Field, 0, ""}, - {"WriteError.Offset", Field, 0, ""}, - {"Writer", Type, 0, ""}, - }, - "compress/gzip": { - {"(*Reader).Close", Method, 0, ""}, - {"(*Reader).Multistream", Method, 4, ""}, - {"(*Reader).Read", Method, 0, ""}, - {"(*Reader).Reset", Method, 3, ""}, - {"(*Writer).Close", Method, 0, ""}, - {"(*Writer).Flush", Method, 1, ""}, - {"(*Writer).Reset", Method, 2, ""}, - {"(*Writer).Write", Method, 0, ""}, - {"BestCompression", Const, 0, ""}, - {"BestSpeed", Const, 0, ""}, - {"DefaultCompression", Const, 0, ""}, - {"ErrChecksum", Var, 0, ""}, - {"ErrHeader", Var, 0, ""}, - {"Header", Type, 0, ""}, - {"Header.Comment", Field, 0, ""}, - {"Header.Extra", Field, 0, ""}, - {"Header.ModTime", Field, 0, ""}, - {"Header.Name", Field, 0, ""}, - {"Header.OS", Field, 0, ""}, - {"HuffmanOnly", Const, 8, ""}, - {"NewReader", Func, 0, "func(r io.Reader) (*Reader, error)"}, - {"NewWriter", Func, 0, "func(w io.Writer) *Writer"}, - {"NewWriterLevel", Func, 0, "func(w io.Writer, level int) (*Writer, error)"}, - {"NoCompression", Const, 0, ""}, - {"Reader", Type, 0, ""}, - {"Reader.Header", Field, 0, ""}, - {"Writer", Type, 0, ""}, - {"Writer.Header", Field, 0, ""}, - }, - "compress/lzw": { - {"(*Reader).Close", Method, 17, ""}, - {"(*Reader).Read", Method, 17, ""}, - {"(*Reader).Reset", Method, 17, ""}, - {"(*Writer).Close", Method, 17, ""}, - {"(*Writer).Reset", Method, 17, ""}, - {"(*Writer).Write", Method, 17, ""}, - {"LSB", Const, 0, ""}, - {"MSB", Const, 0, ""}, - {"NewReader", Func, 0, "func(r io.Reader, order Order, litWidth int) io.ReadCloser"}, - {"NewWriter", Func, 0, "func(w io.Writer, order Order, litWidth int) io.WriteCloser"}, - {"Order", Type, 0, ""}, - {"Reader", Type, 17, ""}, - {"Writer", Type, 17, ""}, - }, - "compress/zlib": { - {"(*Writer).Close", Method, 0, ""}, - {"(*Writer).Flush", Method, 0, ""}, - {"(*Writer).Reset", Method, 2, ""}, - {"(*Writer).Write", Method, 0, ""}, - {"(Resetter).Reset", Method, 4, ""}, - {"BestCompression", Const, 0, ""}, - {"BestSpeed", Const, 0, ""}, - {"DefaultCompression", Const, 0, ""}, - {"ErrChecksum", Var, 0, ""}, - {"ErrDictionary", Var, 0, ""}, - {"ErrHeader", Var, 0, ""}, - {"HuffmanOnly", Const, 8, ""}, - {"NewReader", Func, 0, "func(r io.Reader) (io.ReadCloser, error)"}, - {"NewReaderDict", Func, 0, "func(r io.Reader, dict []byte) (io.ReadCloser, error)"}, - {"NewWriter", Func, 0, "func(w io.Writer) *Writer"}, - {"NewWriterLevel", Func, 0, "func(w io.Writer, level int) (*Writer, error)"}, - {"NewWriterLevelDict", Func, 0, "func(w io.Writer, level int, dict []byte) (*Writer, error)"}, - {"NoCompression", Const, 0, ""}, - {"Resetter", Type, 4, ""}, - {"Writer", Type, 0, ""}, - }, - "container/heap": { - {"(Interface).Len", Method, 0, ""}, - {"(Interface).Less", Method, 0, ""}, - {"(Interface).Pop", Method, 0, ""}, - {"(Interface).Push", Method, 0, ""}, - {"(Interface).Swap", Method, 0, ""}, - {"Fix", Func, 2, "func(h Interface, i int)"}, - {"Init", Func, 0, "func(h Interface)"}, - {"Interface", Type, 0, ""}, - {"Pop", Func, 0, "func(h Interface) any"}, - {"Push", Func, 0, "func(h Interface, x any)"}, - {"Remove", Func, 0, "func(h Interface, i int) any"}, - }, - "container/list": { - {"(*Element).Next", Method, 0, ""}, - {"(*Element).Prev", Method, 0, ""}, - {"(*List).Back", Method, 0, ""}, - {"(*List).Front", Method, 0, ""}, - {"(*List).Init", Method, 0, ""}, - {"(*List).InsertAfter", Method, 0, ""}, - {"(*List).InsertBefore", Method, 0, ""}, - {"(*List).Len", Method, 0, ""}, - {"(*List).MoveAfter", Method, 2, ""}, - {"(*List).MoveBefore", Method, 2, ""}, - {"(*List).MoveToBack", Method, 0, ""}, - {"(*List).MoveToFront", Method, 0, ""}, - {"(*List).PushBack", Method, 0, ""}, - {"(*List).PushBackList", Method, 0, ""}, - {"(*List).PushFront", Method, 0, ""}, - {"(*List).PushFrontList", Method, 0, ""}, - {"(*List).Remove", Method, 0, ""}, - {"Element", Type, 0, ""}, - {"Element.Value", Field, 0, ""}, - {"List", Type, 0, ""}, - {"New", Func, 0, "func() *List"}, - }, - "container/ring": { - {"(*Ring).Do", Method, 0, ""}, - {"(*Ring).Len", Method, 0, ""}, - {"(*Ring).Link", Method, 0, ""}, - {"(*Ring).Move", Method, 0, ""}, - {"(*Ring).Next", Method, 0, ""}, - {"(*Ring).Prev", Method, 0, ""}, - {"(*Ring).Unlink", Method, 0, ""}, - {"New", Func, 0, "func(n int) *Ring"}, - {"Ring", Type, 0, ""}, - {"Ring.Value", Field, 0, ""}, - }, - "context": { - {"(Context).Deadline", Method, 7, ""}, - {"(Context).Done", Method, 7, ""}, - {"(Context).Err", Method, 7, ""}, - {"(Context).Value", Method, 7, ""}, - {"AfterFunc", Func, 21, "func(ctx Context, f func()) (stop func() bool)"}, - {"Background", Func, 7, "func() Context"}, - {"CancelCauseFunc", Type, 20, ""}, - {"CancelFunc", Type, 7, ""}, - {"Canceled", Var, 7, ""}, - {"Cause", Func, 20, "func(c Context) error"}, - {"Context", Type, 7, ""}, - {"DeadlineExceeded", Var, 7, ""}, - {"TODO", Func, 7, "func() Context"}, - {"WithCancel", Func, 7, "func(parent Context) (ctx Context, cancel CancelFunc)"}, - {"WithCancelCause", Func, 20, "func(parent Context) (ctx Context, cancel CancelCauseFunc)"}, - {"WithDeadline", Func, 7, "func(parent Context, d time.Time) (Context, CancelFunc)"}, - {"WithDeadlineCause", Func, 21, "func(parent Context, d time.Time, cause error) (Context, CancelFunc)"}, - {"WithTimeout", Func, 7, "func(parent Context, timeout time.Duration) (Context, CancelFunc)"}, - {"WithTimeoutCause", Func, 21, "func(parent Context, timeout time.Duration, cause error) (Context, CancelFunc)"}, - {"WithValue", Func, 7, "func(parent Context, key any, val any) Context"}, - {"WithoutCancel", Func, 21, "func(parent Context) Context"}, - }, - "crypto": { - {"(Decapsulator).Decapsulate", Method, 26, ""}, - {"(Decapsulator).Encapsulator", Method, 26, ""}, - {"(Decrypter).Decrypt", Method, 5, ""}, - {"(Decrypter).Public", Method, 5, ""}, - {"(Encapsulator).Bytes", Method, 26, ""}, - {"(Encapsulator).Encapsulate", Method, 26, ""}, - {"(Hash).Available", Method, 0, ""}, - {"(Hash).HashFunc", Method, 4, ""}, - {"(Hash).New", Method, 0, ""}, - {"(Hash).Size", Method, 0, ""}, - {"(Hash).String", Method, 15, ""}, - {"(MessageSigner).Public", Method, 25, ""}, - {"(MessageSigner).Sign", Method, 25, ""}, - {"(MessageSigner).SignMessage", Method, 25, ""}, - {"(Signer).Public", Method, 4, ""}, - {"(Signer).Sign", Method, 4, ""}, - {"(SignerOpts).HashFunc", Method, 4, ""}, - {"BLAKE2b_256", Const, 9, ""}, - {"BLAKE2b_384", Const, 9, ""}, - {"BLAKE2b_512", Const, 9, ""}, - {"BLAKE2s_256", Const, 9, ""}, - {"Decapsulator", Type, 26, ""}, - {"Decrypter", Type, 5, ""}, - {"DecrypterOpts", Type, 5, ""}, - {"Encapsulator", Type, 26, ""}, - {"Hash", Type, 0, ""}, - {"MD4", Const, 0, ""}, - {"MD5", Const, 0, ""}, - {"MD5SHA1", Const, 0, ""}, - {"MessageSigner", Type, 25, ""}, - {"PrivateKey", Type, 0, ""}, - {"PublicKey", Type, 2, ""}, - {"RIPEMD160", Const, 0, ""}, - {"RegisterHash", Func, 0, "func(h Hash, f func() hash.Hash)"}, - {"SHA1", Const, 0, ""}, - {"SHA224", Const, 0, ""}, - {"SHA256", Const, 0, ""}, - {"SHA384", Const, 0, ""}, - {"SHA3_224", Const, 4, ""}, - {"SHA3_256", Const, 4, ""}, - {"SHA3_384", Const, 4, ""}, - {"SHA3_512", Const, 4, ""}, - {"SHA512", Const, 0, ""}, - {"SHA512_224", Const, 5, ""}, - {"SHA512_256", Const, 5, ""}, - {"SignMessage", Func, 25, "func(signer Signer, rand io.Reader, msg []byte, opts SignerOpts) (signature []byte, err error)"}, - {"Signer", Type, 4, ""}, - {"SignerOpts", Type, 4, ""}, - }, - "crypto/aes": { - {"(KeySizeError).Error", Method, 0, ""}, - {"BlockSize", Const, 0, ""}, - {"KeySizeError", Type, 0, ""}, - {"NewCipher", Func, 0, "func(key []byte) (cipher.Block, error)"}, - }, - "crypto/cipher": { - {"(AEAD).NonceSize", Method, 2, ""}, - {"(AEAD).Open", Method, 2, ""}, - {"(AEAD).Overhead", Method, 2, ""}, - {"(AEAD).Seal", Method, 2, ""}, - {"(Block).BlockSize", Method, 0, ""}, - {"(Block).Decrypt", Method, 0, ""}, - {"(Block).Encrypt", Method, 0, ""}, - {"(BlockMode).BlockSize", Method, 0, ""}, - {"(BlockMode).CryptBlocks", Method, 0, ""}, - {"(Stream).XORKeyStream", Method, 0, ""}, - {"(StreamReader).Read", Method, 0, ""}, - {"(StreamWriter).Close", Method, 0, ""}, - {"(StreamWriter).Write", Method, 0, ""}, - {"AEAD", Type, 2, ""}, - {"Block", Type, 0, ""}, - {"BlockMode", Type, 0, ""}, - {"NewCBCDecrypter", Func, 0, "func(b Block, iv []byte) BlockMode"}, - {"NewCBCEncrypter", Func, 0, "func(b Block, iv []byte) BlockMode"}, - {"NewCFBDecrypter", Func, 0, "func(block Block, iv []byte) Stream"}, - {"NewCFBEncrypter", Func, 0, "func(block Block, iv []byte) Stream"}, - {"NewCTR", Func, 0, "func(block Block, iv []byte) Stream"}, - {"NewGCM", Func, 2, "func(cipher Block) (AEAD, error)"}, - {"NewGCMWithNonceSize", Func, 5, "func(cipher Block, size int) (AEAD, error)"}, - {"NewGCMWithRandomNonce", Func, 24, "func(cipher Block) (AEAD, error)"}, - {"NewGCMWithTagSize", Func, 11, "func(cipher Block, tagSize int) (AEAD, error)"}, - {"NewOFB", Func, 0, "func(b Block, iv []byte) Stream"}, - {"Stream", Type, 0, ""}, - {"StreamReader", Type, 0, ""}, - {"StreamReader.R", Field, 0, ""}, - {"StreamReader.S", Field, 0, ""}, - {"StreamWriter", Type, 0, ""}, - {"StreamWriter.Err", Field, 0, ""}, - {"StreamWriter.S", Field, 0, ""}, - {"StreamWriter.W", Field, 0, ""}, - }, - "crypto/des": { - {"(KeySizeError).Error", Method, 0, ""}, - {"BlockSize", Const, 0, ""}, - {"KeySizeError", Type, 0, ""}, - {"NewCipher", Func, 0, "func(key []byte) (cipher.Block, error)"}, - {"NewTripleDESCipher", Func, 0, "func(key []byte) (cipher.Block, error)"}, - }, - "crypto/dsa": { - {"ErrInvalidPublicKey", Var, 0, ""}, - {"GenerateKey", Func, 0, "func(priv *PrivateKey, rand io.Reader) error"}, - {"GenerateParameters", Func, 0, "func(params *Parameters, rand io.Reader, sizes ParameterSizes) error"}, - {"L1024N160", Const, 0, ""}, - {"L2048N224", Const, 0, ""}, - {"L2048N256", Const, 0, ""}, - {"L3072N256", Const, 0, ""}, - {"ParameterSizes", Type, 0, ""}, - {"Parameters", Type, 0, ""}, - {"Parameters.G", Field, 0, ""}, - {"Parameters.P", Field, 0, ""}, - {"Parameters.Q", Field, 0, ""}, - {"PrivateKey", Type, 0, ""}, - {"PrivateKey.PublicKey", Field, 0, ""}, - {"PrivateKey.X", Field, 0, ""}, - {"PublicKey", Type, 0, ""}, - {"PublicKey.Parameters", Field, 0, ""}, - {"PublicKey.Y", Field, 0, ""}, - {"Sign", Func, 0, "func(random io.Reader, priv *PrivateKey, hash []byte) (r *big.Int, s *big.Int, err error)"}, - {"Verify", Func, 0, "func(pub *PublicKey, hash []byte, r *big.Int, s *big.Int) bool"}, - }, - "crypto/ecdh": { - {"(*PrivateKey).Bytes", Method, 20, ""}, - {"(*PrivateKey).Curve", Method, 20, ""}, - {"(*PrivateKey).ECDH", Method, 20, ""}, - {"(*PrivateKey).Equal", Method, 20, ""}, - {"(*PrivateKey).Public", Method, 20, ""}, - {"(*PrivateKey).PublicKey", Method, 20, ""}, - {"(*PublicKey).Bytes", Method, 20, ""}, - {"(*PublicKey).Curve", Method, 20, ""}, - {"(*PublicKey).Equal", Method, 20, ""}, - {"(Curve).GenerateKey", Method, 20, ""}, - {"(Curve).NewPrivateKey", Method, 20, ""}, - {"(Curve).NewPublicKey", Method, 20, ""}, - {"(KeyExchanger).Curve", Method, 26, ""}, - {"(KeyExchanger).ECDH", Method, 26, ""}, - {"(KeyExchanger).PublicKey", Method, 26, ""}, - {"KeyExchanger", Type, 26, ""}, - {"P256", Func, 20, "func() Curve"}, - {"P384", Func, 20, "func() Curve"}, - {"P521", Func, 20, "func() Curve"}, - {"PrivateKey", Type, 20, ""}, - {"PublicKey", Type, 20, ""}, - {"X25519", Func, 20, "func() Curve"}, - }, - "crypto/ecdsa": { - {"(*PrivateKey).Bytes", Method, 25, ""}, - {"(*PrivateKey).ECDH", Method, 20, ""}, - {"(*PrivateKey).Equal", Method, 15, ""}, - {"(*PrivateKey).Public", Method, 4, ""}, - {"(*PrivateKey).Sign", Method, 4, ""}, - {"(*PublicKey).Bytes", Method, 25, ""}, - {"(*PublicKey).ECDH", Method, 20, ""}, - {"(*PublicKey).Equal", Method, 15, ""}, - {"(PrivateKey).Add", Method, 0, ""}, - {"(PrivateKey).Double", Method, 0, ""}, - {"(PrivateKey).IsOnCurve", Method, 0, ""}, - {"(PrivateKey).Params", Method, 0, ""}, - {"(PrivateKey).ScalarBaseMult", Method, 0, ""}, - {"(PrivateKey).ScalarMult", Method, 0, ""}, - {"(PublicKey).Add", Method, 0, ""}, - {"(PublicKey).Double", Method, 0, ""}, - {"(PublicKey).IsOnCurve", Method, 0, ""}, - {"(PublicKey).Params", Method, 0, ""}, - {"(PublicKey).ScalarBaseMult", Method, 0, ""}, - {"(PublicKey).ScalarMult", Method, 0, ""}, - {"GenerateKey", Func, 0, "func(c elliptic.Curve, r io.Reader) (*PrivateKey, error)"}, - {"ParseRawPrivateKey", Func, 25, "func(curve elliptic.Curve, data []byte) (*PrivateKey, error)"}, - {"ParseUncompressedPublicKey", Func, 25, "func(curve elliptic.Curve, data []byte) (*PublicKey, error)"}, - {"PrivateKey", Type, 0, ""}, - {"PrivateKey.D", Field, 0, ""}, - {"PrivateKey.PublicKey", Field, 0, ""}, - {"PublicKey", Type, 0, ""}, - {"PublicKey.Curve", Field, 0, ""}, - {"PublicKey.X", Field, 0, ""}, - {"PublicKey.Y", Field, 0, ""}, - {"Sign", Func, 0, "func(rand io.Reader, priv *PrivateKey, hash []byte) (r *big.Int, s *big.Int, err error)"}, - {"SignASN1", Func, 15, "func(r io.Reader, priv *PrivateKey, hash []byte) ([]byte, error)"}, - {"Verify", Func, 0, "func(pub *PublicKey, hash []byte, r *big.Int, s *big.Int) bool"}, - {"VerifyASN1", Func, 15, "func(pub *PublicKey, hash []byte, sig []byte) bool"}, - }, - "crypto/ed25519": { - {"(*Options).HashFunc", Method, 20, ""}, - {"(PrivateKey).Equal", Method, 15, ""}, - {"(PrivateKey).Public", Method, 13, ""}, - {"(PrivateKey).Seed", Method, 13, ""}, - {"(PrivateKey).Sign", Method, 13, ""}, - {"(PublicKey).Equal", Method, 15, ""}, - {"GenerateKey", Func, 13, "func(random io.Reader) (PublicKey, PrivateKey, error)"}, - {"NewKeyFromSeed", Func, 13, "func(seed []byte) PrivateKey"}, - {"Options", Type, 20, ""}, - {"Options.Context", Field, 20, ""}, - {"Options.Hash", Field, 20, ""}, - {"PrivateKey", Type, 13, ""}, - {"PrivateKeySize", Const, 13, ""}, - {"PublicKey", Type, 13, ""}, - {"PublicKeySize", Const, 13, ""}, - {"SeedSize", Const, 13, ""}, - {"Sign", Func, 13, "func(privateKey PrivateKey, message []byte) []byte"}, - {"SignatureSize", Const, 13, ""}, - {"Verify", Func, 13, "func(publicKey PublicKey, message []byte, sig []byte) bool"}, - {"VerifyWithOptions", Func, 20, "func(publicKey PublicKey, message []byte, sig []byte, opts *Options) error"}, - }, - "crypto/elliptic": { - {"(*CurveParams).Add", Method, 0, ""}, - {"(*CurveParams).Double", Method, 0, ""}, - {"(*CurveParams).IsOnCurve", Method, 0, ""}, - {"(*CurveParams).Params", Method, 0, ""}, - {"(*CurveParams).ScalarBaseMult", Method, 0, ""}, - {"(*CurveParams).ScalarMult", Method, 0, ""}, - {"(Curve).Add", Method, 0, ""}, - {"(Curve).Double", Method, 0, ""}, - {"(Curve).IsOnCurve", Method, 0, ""}, - {"(Curve).Params", Method, 0, ""}, - {"(Curve).ScalarBaseMult", Method, 0, ""}, - {"(Curve).ScalarMult", Method, 0, ""}, - {"Curve", Type, 0, ""}, - {"CurveParams", Type, 0, ""}, - {"CurveParams.B", Field, 0, ""}, - {"CurveParams.BitSize", Field, 0, ""}, - {"CurveParams.Gx", Field, 0, ""}, - {"CurveParams.Gy", Field, 0, ""}, - {"CurveParams.N", Field, 0, ""}, - {"CurveParams.Name", Field, 5, ""}, - {"CurveParams.P", Field, 0, ""}, - {"GenerateKey", Func, 0, "func(curve Curve, rand io.Reader) (priv []byte, x *big.Int, y *big.Int, err error)"}, - {"Marshal", Func, 0, "func(curve Curve, x *big.Int, y *big.Int) []byte"}, - {"MarshalCompressed", Func, 15, "func(curve Curve, x *big.Int, y *big.Int) []byte"}, - {"P224", Func, 0, "func() Curve"}, - {"P256", Func, 0, "func() Curve"}, - {"P384", Func, 0, "func() Curve"}, - {"P521", Func, 0, "func() Curve"}, - {"Unmarshal", Func, 0, "func(curve Curve, data []byte) (x *big.Int, y *big.Int)"}, - {"UnmarshalCompressed", Func, 15, "func(curve Curve, data []byte) (x *big.Int, y *big.Int)"}, - }, - "crypto/fips140": { - {"Enabled", Func, 24, "func() bool"}, - {"Enforced", Func, 26, "func() bool"}, - {"Version", Func, 26, "func() string"}, - {"WithoutEnforcement", Func, 26, "func(f func())"}, - }, - "crypto/hkdf": { - {"Expand", Func, 24, "func[H hash.Hash](h func() H, pseudorandomKey []byte, info string, keyLength int) ([]byte, error)"}, - {"Extract", Func, 24, "func[H hash.Hash](h func() H, secret []byte, salt []byte) ([]byte, error)"}, - {"Key", Func, 24, "func[Hash hash.Hash](h func() Hash, secret []byte, salt []byte, info string, keyLength int) ([]byte, error)"}, - }, - "crypto/hmac": { - {"Equal", Func, 1, "func(mac1 []byte, mac2 []byte) bool"}, - {"New", Func, 0, "func(h func() hash.Hash, key []byte) hash.Hash"}, - }, - "crypto/hpke": { - {"(*Recipient).Export", Method, 26, ""}, - {"(*Recipient).Open", Method, 26, ""}, - {"(*Sender).Export", Method, 26, ""}, - {"(*Sender).Seal", Method, 26, ""}, - {"(AEAD).ID", Method, 26, ""}, - {"(KDF).ID", Method, 26, ""}, - {"(KEM).DeriveKeyPair", Method, 26, ""}, - {"(KEM).GenerateKey", Method, 26, ""}, - {"(KEM).ID", Method, 26, ""}, - {"(KEM).NewPrivateKey", Method, 26, ""}, - {"(KEM).NewPublicKey", Method, 26, ""}, - {"(PrivateKey).Bytes", Method, 26, ""}, - {"(PrivateKey).KEM", Method, 26, ""}, - {"(PrivateKey).PublicKey", Method, 26, ""}, - {"(PublicKey).Bytes", Method, 26, ""}, - {"(PublicKey).KEM", Method, 26, ""}, - {"AES128GCM", Func, 26, "func() AEAD"}, - {"AES256GCM", Func, 26, "func() AEAD"}, - {"ChaCha20Poly1305", Func, 26, "func() AEAD"}, - {"DHKEM", Func, 26, "func(curve ecdh.Curve) KEM"}, - {"ExportOnly", Func, 26, "func() AEAD"}, - {"HKDFSHA256", Func, 26, "func() KDF"}, - {"HKDFSHA384", Func, 26, "func() KDF"}, - {"HKDFSHA512", Func, 26, "func() KDF"}, - {"MLKEM1024", Func, 26, "func() KEM"}, - {"MLKEM1024P384", Func, 26, "func() KEM"}, - {"MLKEM768", Func, 26, "func() KEM"}, - {"MLKEM768P256", Func, 26, "func() KEM"}, - {"MLKEM768X25519", Func, 26, "func() KEM"}, - {"NewAEAD", Func, 26, "func(id uint16) (AEAD, error)"}, - {"NewDHKEMPrivateKey", Func, 26, "func(priv ecdh.KeyExchanger) (PrivateKey, error)"}, - {"NewDHKEMPublicKey", Func, 26, "func(pub *ecdh.PublicKey) (PublicKey, error)"}, - {"NewHybridPrivateKey", Func, 26, "func(pq crypto.Decapsulator, t ecdh.KeyExchanger) (PrivateKey, error)"}, - {"NewHybridPublicKey", Func, 26, "func(pq crypto.Encapsulator, t *ecdh.PublicKey) (PublicKey, error)"}, - {"NewKDF", Func, 26, "func(id uint16) (KDF, error)"}, - {"NewKEM", Func, 26, "func(id uint16) (KEM, error)"}, - {"NewMLKEMPrivateKey", Func, 26, "func(priv crypto.Decapsulator) (PrivateKey, error)"}, - {"NewMLKEMPublicKey", Func, 26, "func(pub crypto.Encapsulator) (PublicKey, error)"}, - {"NewRecipient", Func, 26, "func(enc []byte, k PrivateKey, kdf KDF, aead AEAD, info []byte) (*Recipient, error)"}, - {"NewSender", Func, 26, "func(pk PublicKey, kdf KDF, aead AEAD, info []byte) (enc []byte, s *Sender, err error)"}, - {"Open", Func, 26, "func(k PrivateKey, kdf KDF, aead AEAD, info []byte, ciphertext []byte) ([]byte, error)"}, - {"Recipient", Type, 26, ""}, - {"SHAKE128", Func, 26, "func() KDF"}, - {"SHAKE256", Func, 26, "func() KDF"}, - {"Seal", Func, 26, "func(pk PublicKey, kdf KDF, aead AEAD, info []byte, plaintext []byte) ([]byte, error)"}, - {"Sender", Type, 26, ""}, - }, - "crypto/md5": { - {"BlockSize", Const, 0, ""}, - {"New", Func, 0, "func() hash.Hash"}, - {"Size", Const, 0, ""}, - {"Sum", Func, 2, "func(data []byte) [16]byte"}, - }, - "crypto/mlkem": { - {"(*DecapsulationKey1024).Bytes", Method, 24, ""}, - {"(*DecapsulationKey1024).Decapsulate", Method, 24, ""}, - {"(*DecapsulationKey1024).EncapsulationKey", Method, 24, ""}, - {"(*DecapsulationKey1024).Encapsulator", Method, 26, ""}, - {"(*DecapsulationKey768).Bytes", Method, 24, ""}, - {"(*DecapsulationKey768).Decapsulate", Method, 24, ""}, - {"(*DecapsulationKey768).EncapsulationKey", Method, 24, ""}, - {"(*DecapsulationKey768).Encapsulator", Method, 26, ""}, - {"(*EncapsulationKey1024).Bytes", Method, 24, ""}, - {"(*EncapsulationKey1024).Encapsulate", Method, 24, ""}, - {"(*EncapsulationKey768).Bytes", Method, 24, ""}, - {"(*EncapsulationKey768).Encapsulate", Method, 24, ""}, - {"CiphertextSize1024", Const, 24, ""}, - {"CiphertextSize768", Const, 24, ""}, - {"DecapsulationKey1024", Type, 24, ""}, - {"DecapsulationKey768", Type, 24, ""}, - {"EncapsulationKey1024", Type, 24, ""}, - {"EncapsulationKey768", Type, 24, ""}, - {"EncapsulationKeySize1024", Const, 24, ""}, - {"EncapsulationKeySize768", Const, 24, ""}, - {"GenerateKey1024", Func, 24, "func() (*DecapsulationKey1024, error)"}, - {"GenerateKey768", Func, 24, "func() (*DecapsulationKey768, error)"}, - {"NewDecapsulationKey1024", Func, 24, "func(seed []byte) (*DecapsulationKey1024, error)"}, - {"NewDecapsulationKey768", Func, 24, "func(seed []byte) (*DecapsulationKey768, error)"}, - {"NewEncapsulationKey1024", Func, 24, "func(encapsulationKey []byte) (*EncapsulationKey1024, error)"}, - {"NewEncapsulationKey768", Func, 24, "func(encapsulationKey []byte) (*EncapsulationKey768, error)"}, - {"SeedSize", Const, 24, ""}, - {"SharedKeySize", Const, 24, ""}, - }, - "crypto/mlkem/mlkemtest": { - {"Encapsulate1024", Func, 26, "func(ek *mlkem.EncapsulationKey1024, random []byte) (sharedKey []byte, ciphertext []byte, err error)"}, - {"Encapsulate768", Func, 26, "func(ek *mlkem.EncapsulationKey768, random []byte) (sharedKey []byte, ciphertext []byte, err error)"}, - }, - "crypto/pbkdf2": { - {"Key", Func, 24, "func[Hash hash.Hash](h func() Hash, password string, salt []byte, iter int, keyLength int) ([]byte, error)"}, - }, - "crypto/rand": { - {"Int", Func, 0, "func(rand io.Reader, max *big.Int) (n *big.Int, err error)"}, - {"Prime", Func, 0, "func(r io.Reader, bits int) (*big.Int, error)"}, - {"Read", Func, 0, "func(b []byte) (n int, err error)"}, - {"Reader", Var, 0, ""}, - {"Text", Func, 24, "func() string"}, - }, - "crypto/rc4": { - {"(*Cipher).Reset", Method, 0, ""}, - {"(*Cipher).XORKeyStream", Method, 0, ""}, - {"(KeySizeError).Error", Method, 0, ""}, - {"Cipher", Type, 0, ""}, - {"KeySizeError", Type, 0, ""}, - {"NewCipher", Func, 0, "func(key []byte) (*Cipher, error)"}, - }, - "crypto/rsa": { - {"(*PSSOptions).HashFunc", Method, 4, ""}, - {"(*PrivateKey).Decrypt", Method, 5, ""}, - {"(*PrivateKey).Equal", Method, 15, ""}, - {"(*PrivateKey).Precompute", Method, 0, ""}, - {"(*PrivateKey).Public", Method, 4, ""}, - {"(*PrivateKey).Sign", Method, 4, ""}, - {"(*PrivateKey).Size", Method, 11, ""}, - {"(*PrivateKey).Validate", Method, 0, ""}, - {"(*PublicKey).Equal", Method, 15, ""}, - {"(*PublicKey).Size", Method, 11, ""}, - {"CRTValue", Type, 0, ""}, - {"CRTValue.Coeff", Field, 0, ""}, - {"CRTValue.Exp", Field, 0, ""}, - {"CRTValue.R", Field, 0, ""}, - {"DecryptOAEP", Func, 0, "func(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error)"}, - {"DecryptPKCS1v15", Func, 0, "func(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error)"}, - {"DecryptPKCS1v15SessionKey", Func, 0, "func(random io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error"}, - {"EncryptOAEP", Func, 0, "func(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error)"}, - {"EncryptOAEPWithOptions", Func, 26, "func(random io.Reader, pub *PublicKey, msg []byte, opts *OAEPOptions) ([]byte, error)"}, - {"EncryptPKCS1v15", Func, 0, "func(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error)"}, - {"ErrDecryption", Var, 0, ""}, - {"ErrMessageTooLong", Var, 0, ""}, - {"ErrVerification", Var, 0, ""}, - {"GenerateKey", Func, 0, "func(random io.Reader, bits int) (*PrivateKey, error)"}, - {"GenerateMultiPrimeKey", Func, 0, "func(random io.Reader, nprimes int, bits int) (*PrivateKey, error)"}, - {"OAEPOptions", Type, 5, ""}, - {"OAEPOptions.Hash", Field, 5, ""}, - {"OAEPOptions.Label", Field, 5, ""}, - {"OAEPOptions.MGFHash", Field, 20, ""}, - {"PKCS1v15DecryptOptions", Type, 5, ""}, - {"PKCS1v15DecryptOptions.SessionKeyLen", Field, 5, ""}, - {"PSSOptions", Type, 2, ""}, - {"PSSOptions.Hash", Field, 4, ""}, - {"PSSOptions.SaltLength", Field, 2, ""}, - {"PSSSaltLengthAuto", Const, 2, ""}, - {"PSSSaltLengthEqualsHash", Const, 2, ""}, - {"PrecomputedValues", Type, 0, ""}, - {"PrecomputedValues.CRTValues", Field, 0, ""}, - {"PrecomputedValues.Dp", Field, 0, ""}, - {"PrecomputedValues.Dq", Field, 0, ""}, - {"PrecomputedValues.Qinv", Field, 0, ""}, - {"PrivateKey", Type, 0, ""}, - {"PrivateKey.D", Field, 0, ""}, - {"PrivateKey.Precomputed", Field, 0, ""}, - {"PrivateKey.Primes", Field, 0, ""}, - {"PrivateKey.PublicKey", Field, 0, ""}, - {"PublicKey", Type, 0, ""}, - {"PublicKey.E", Field, 0, ""}, - {"PublicKey.N", Field, 0, ""}, - {"SignPKCS1v15", Func, 0, "func(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error)"}, - {"SignPSS", Func, 2, "func(random io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error)"}, - {"VerifyPKCS1v15", Func, 0, "func(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error"}, - {"VerifyPSS", Func, 2, "func(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error"}, - }, - "crypto/sha1": { - {"BlockSize", Const, 0, ""}, - {"New", Func, 0, "func() hash.Hash"}, - {"Size", Const, 0, ""}, - {"Sum", Func, 2, "func(data []byte) [20]byte"}, - }, - "crypto/sha256": { - {"BlockSize", Const, 0, ""}, - {"New", Func, 0, "func() hash.Hash"}, - {"New224", Func, 0, "func() hash.Hash"}, - {"Size", Const, 0, ""}, - {"Size224", Const, 0, ""}, - {"Sum224", Func, 2, "func(data []byte) [28]byte"}, - {"Sum256", Func, 2, "func(data []byte) [32]byte"}, - }, - "crypto/sha3": { - {"(*SHA3).AppendBinary", Method, 24, ""}, - {"(*SHA3).BlockSize", Method, 24, ""}, - {"(*SHA3).Clone", Method, 25, ""}, - {"(*SHA3).MarshalBinary", Method, 24, ""}, - {"(*SHA3).Reset", Method, 24, ""}, - {"(*SHA3).Size", Method, 24, ""}, - {"(*SHA3).Sum", Method, 24, ""}, - {"(*SHA3).UnmarshalBinary", Method, 24, ""}, - {"(*SHA3).Write", Method, 24, ""}, - {"(*SHAKE).AppendBinary", Method, 24, ""}, - {"(*SHAKE).BlockSize", Method, 24, ""}, - {"(*SHAKE).MarshalBinary", Method, 24, ""}, - {"(*SHAKE).Read", Method, 24, ""}, - {"(*SHAKE).Reset", Method, 24, ""}, - {"(*SHAKE).UnmarshalBinary", Method, 24, ""}, - {"(*SHAKE).Write", Method, 24, ""}, - {"New224", Func, 24, "func() *SHA3"}, - {"New256", Func, 24, "func() *SHA3"}, - {"New384", Func, 24, "func() *SHA3"}, - {"New512", Func, 24, "func() *SHA3"}, - {"NewCSHAKE128", Func, 24, "func(N []byte, S []byte) *SHAKE"}, - {"NewCSHAKE256", Func, 24, "func(N []byte, S []byte) *SHAKE"}, - {"NewSHAKE128", Func, 24, "func() *SHAKE"}, - {"NewSHAKE256", Func, 24, "func() *SHAKE"}, - {"SHA3", Type, 24, ""}, - {"SHAKE", Type, 24, ""}, - {"Sum224", Func, 24, "func(data []byte) [28]byte"}, - {"Sum256", Func, 24, "func(data []byte) [32]byte"}, - {"Sum384", Func, 24, "func(data []byte) [48]byte"}, - {"Sum512", Func, 24, "func(data []byte) [64]byte"}, - {"SumSHAKE128", Func, 24, "func(data []byte, length int) []byte"}, - {"SumSHAKE256", Func, 24, "func(data []byte, length int) []byte"}, - }, - "crypto/sha512": { - {"BlockSize", Const, 0, ""}, - {"New", Func, 0, "func() hash.Hash"}, - {"New384", Func, 0, "func() hash.Hash"}, - {"New512_224", Func, 5, "func() hash.Hash"}, - {"New512_256", Func, 5, "func() hash.Hash"}, - {"Size", Const, 0, ""}, - {"Size224", Const, 5, ""}, - {"Size256", Const, 5, ""}, - {"Size384", Const, 0, ""}, - {"Sum384", Func, 2, "func(data []byte) [48]byte"}, - {"Sum512", Func, 2, "func(data []byte) [64]byte"}, - {"Sum512_224", Func, 5, "func(data []byte) [28]byte"}, - {"Sum512_256", Func, 5, "func(data []byte) [32]byte"}, - }, - "crypto/subtle": { - {"ConstantTimeByteEq", Func, 0, "func(x uint8, y uint8) int"}, - {"ConstantTimeCompare", Func, 0, "func(x []byte, y []byte) int"}, - {"ConstantTimeCopy", Func, 0, "func(v int, x []byte, y []byte)"}, - {"ConstantTimeEq", Func, 0, "func(x int32, y int32) int"}, - {"ConstantTimeLessOrEq", Func, 2, "func(x int, y int) int"}, - {"ConstantTimeSelect", Func, 0, "func(v int, x int, y int) int"}, - {"WithDataIndependentTiming", Func, 24, "func(f func())"}, - {"XORBytes", Func, 20, "func(dst []byte, x []byte, y []byte) int"}, - }, - "crypto/tls": { - {"(*CertificateRequestInfo).Context", Method, 17, ""}, - {"(*CertificateRequestInfo).SupportsCertificate", Method, 14, ""}, - {"(*CertificateVerificationError).Error", Method, 20, ""}, - {"(*CertificateVerificationError).Unwrap", Method, 20, ""}, - {"(*ClientHelloInfo).Context", Method, 17, ""}, - {"(*ClientHelloInfo).SupportsCertificate", Method, 14, ""}, - {"(*ClientSessionState).ResumptionState", Method, 21, ""}, - {"(*Config).BuildNameToCertificate", Method, 0, ""}, - {"(*Config).Clone", Method, 8, ""}, - {"(*Config).DecryptTicket", Method, 21, ""}, - {"(*Config).EncryptTicket", Method, 21, ""}, - {"(*Config).SetSessionTicketKeys", Method, 5, ""}, - {"(*Conn).Close", Method, 0, ""}, - {"(*Conn).CloseWrite", Method, 8, ""}, - {"(*Conn).ConnectionState", Method, 0, ""}, - {"(*Conn).Handshake", Method, 0, ""}, - {"(*Conn).HandshakeContext", Method, 17, ""}, - {"(*Conn).LocalAddr", Method, 0, ""}, - {"(*Conn).NetConn", Method, 18, ""}, - {"(*Conn).OCSPResponse", Method, 0, ""}, - {"(*Conn).Read", Method, 0, ""}, - {"(*Conn).RemoteAddr", Method, 0, ""}, - {"(*Conn).SetDeadline", Method, 0, ""}, - {"(*Conn).SetReadDeadline", Method, 0, ""}, - {"(*Conn).SetWriteDeadline", Method, 0, ""}, - {"(*Conn).VerifyHostname", Method, 0, ""}, - {"(*Conn).Write", Method, 0, ""}, - {"(*ConnectionState).ExportKeyingMaterial", Method, 11, ""}, - {"(*Dialer).Dial", Method, 15, ""}, - {"(*Dialer).DialContext", Method, 15, ""}, - {"(*ECHRejectionError).Error", Method, 23, ""}, - {"(*QUICConn).Close", Method, 21, ""}, - {"(*QUICConn).ConnectionState", Method, 21, ""}, - {"(*QUICConn).HandleData", Method, 21, ""}, - {"(*QUICConn).NextEvent", Method, 21, ""}, - {"(*QUICConn).SendSessionTicket", Method, 21, ""}, - {"(*QUICConn).SetTransportParameters", Method, 21, ""}, - {"(*QUICConn).Start", Method, 21, ""}, - {"(*QUICConn).StoreSession", Method, 23, ""}, - {"(*SessionState).Bytes", Method, 21, ""}, - {"(AlertError).Error", Method, 21, ""}, - {"(ClientAuthType).String", Method, 15, ""}, - {"(ClientSessionCache).Get", Method, 3, ""}, - {"(ClientSessionCache).Put", Method, 3, ""}, - {"(CurveID).String", Method, 15, ""}, - {"(QUICEncryptionLevel).String", Method, 21, ""}, - {"(RecordHeaderError).Error", Method, 6, ""}, - {"(SignatureScheme).String", Method, 15, ""}, - {"AlertError", Type, 21, ""}, - {"Certificate", Type, 0, ""}, - {"Certificate.Certificate", Field, 0, ""}, - {"Certificate.Leaf", Field, 0, ""}, - {"Certificate.OCSPStaple", Field, 0, ""}, - {"Certificate.PrivateKey", Field, 0, ""}, - {"Certificate.SignedCertificateTimestamps", Field, 5, ""}, - {"Certificate.SupportedSignatureAlgorithms", Field, 14, ""}, - {"CertificateRequestInfo", Type, 8, ""}, - {"CertificateRequestInfo.AcceptableCAs", Field, 8, ""}, - {"CertificateRequestInfo.SignatureSchemes", Field, 8, ""}, - {"CertificateRequestInfo.Version", Field, 14, ""}, - {"CertificateVerificationError", Type, 20, ""}, - {"CertificateVerificationError.Err", Field, 20, ""}, - {"CertificateVerificationError.UnverifiedCertificates", Field, 20, ""}, - {"CipherSuite", Type, 14, ""}, - {"CipherSuite.ID", Field, 14, ""}, - {"CipherSuite.Insecure", Field, 14, ""}, - {"CipherSuite.Name", Field, 14, ""}, - {"CipherSuite.SupportedVersions", Field, 14, ""}, - {"CipherSuiteName", Func, 14, "func(id uint16) string"}, - {"CipherSuites", Func, 14, "func() []*CipherSuite"}, - {"Client", Func, 0, "func(conn net.Conn, config *Config) *Conn"}, - {"ClientAuthType", Type, 0, ""}, - {"ClientHelloInfo", Type, 4, ""}, - {"ClientHelloInfo.CipherSuites", Field, 4, ""}, - {"ClientHelloInfo.Conn", Field, 8, ""}, - {"ClientHelloInfo.Extensions", Field, 24, ""}, - {"ClientHelloInfo.HelloRetryRequest", Field, 26, ""}, - {"ClientHelloInfo.ServerName", Field, 4, ""}, - {"ClientHelloInfo.SignatureSchemes", Field, 8, ""}, - {"ClientHelloInfo.SupportedCurves", Field, 4, ""}, - {"ClientHelloInfo.SupportedPoints", Field, 4, ""}, - {"ClientHelloInfo.SupportedProtos", Field, 8, ""}, - {"ClientHelloInfo.SupportedVersions", Field, 8, ""}, - {"ClientSessionCache", Type, 3, ""}, - {"ClientSessionState", Type, 3, ""}, - {"Config", Type, 0, ""}, - {"Config.Certificates", Field, 0, ""}, - {"Config.CipherSuites", Field, 0, ""}, - {"Config.ClientAuth", Field, 0, ""}, - {"Config.ClientCAs", Field, 0, ""}, - {"Config.ClientSessionCache", Field, 3, ""}, - {"Config.CurvePreferences", Field, 3, ""}, - {"Config.DynamicRecordSizingDisabled", Field, 7, ""}, - {"Config.EncryptedClientHelloConfigList", Field, 23, ""}, - {"Config.EncryptedClientHelloKeys", Field, 24, ""}, - {"Config.EncryptedClientHelloRejectionVerify", Field, 23, ""}, - {"Config.GetCertificate", Field, 4, ""}, - {"Config.GetClientCertificate", Field, 8, ""}, - {"Config.GetConfigForClient", Field, 8, ""}, - {"Config.GetEncryptedClientHelloKeys", Field, 25, ""}, - {"Config.InsecureSkipVerify", Field, 0, ""}, - {"Config.KeyLogWriter", Field, 8, ""}, - {"Config.MaxVersion", Field, 2, ""}, - {"Config.MinVersion", Field, 2, ""}, - {"Config.NameToCertificate", Field, 0, ""}, - {"Config.NextProtos", Field, 0, ""}, - {"Config.PreferServerCipherSuites", Field, 1, ""}, - {"Config.Rand", Field, 0, ""}, - {"Config.Renegotiation", Field, 7, ""}, - {"Config.RootCAs", Field, 0, ""}, - {"Config.ServerName", Field, 0, ""}, - {"Config.SessionTicketKey", Field, 1, ""}, - {"Config.SessionTicketsDisabled", Field, 1, ""}, - {"Config.Time", Field, 0, ""}, - {"Config.UnwrapSession", Field, 21, ""}, - {"Config.VerifyConnection", Field, 15, ""}, - {"Config.VerifyPeerCertificate", Field, 8, ""}, - {"Config.WrapSession", Field, 21, ""}, - {"Conn", Type, 0, ""}, - {"ConnectionState", Type, 0, ""}, - {"ConnectionState.CipherSuite", Field, 0, ""}, - {"ConnectionState.CurveID", Field, 25, ""}, - {"ConnectionState.DidResume", Field, 1, ""}, - {"ConnectionState.ECHAccepted", Field, 23, ""}, - {"ConnectionState.HandshakeComplete", Field, 0, ""}, - {"ConnectionState.HelloRetryRequest", Field, 26, ""}, - {"ConnectionState.NegotiatedProtocol", Field, 0, ""}, - {"ConnectionState.NegotiatedProtocolIsMutual", Field, 0, ""}, - {"ConnectionState.OCSPResponse", Field, 5, ""}, - {"ConnectionState.PeerCertificates", Field, 0, ""}, - {"ConnectionState.ServerName", Field, 0, ""}, - {"ConnectionState.SignedCertificateTimestamps", Field, 5, ""}, - {"ConnectionState.TLSUnique", Field, 4, ""}, - {"ConnectionState.VerifiedChains", Field, 0, ""}, - {"ConnectionState.Version", Field, 3, ""}, - {"CurveID", Type, 3, ""}, - {"CurveP256", Const, 3, ""}, - {"CurveP384", Const, 3, ""}, - {"CurveP521", Const, 3, ""}, - {"Dial", Func, 0, "func(network string, addr string, config *Config) (*Conn, error)"}, - {"DialWithDialer", Func, 3, "func(dialer *net.Dialer, network string, addr string, config *Config) (*Conn, error)"}, - {"Dialer", Type, 15, ""}, - {"Dialer.Config", Field, 15, ""}, - {"Dialer.NetDialer", Field, 15, ""}, - {"ECDSAWithP256AndSHA256", Const, 8, ""}, - {"ECDSAWithP384AndSHA384", Const, 8, ""}, - {"ECDSAWithP521AndSHA512", Const, 8, ""}, - {"ECDSAWithSHA1", Const, 10, ""}, - {"ECHRejectionError", Type, 23, ""}, - {"ECHRejectionError.RetryConfigList", Field, 23, ""}, - {"Ed25519", Const, 13, ""}, - {"EncryptedClientHelloKey", Type, 24, ""}, - {"EncryptedClientHelloKey.Config", Field, 24, ""}, - {"EncryptedClientHelloKey.PrivateKey", Field, 24, ""}, - {"EncryptedClientHelloKey.SendAsRetry", Field, 24, ""}, - {"InsecureCipherSuites", Func, 14, "func() []*CipherSuite"}, - {"Listen", Func, 0, "func(network string, laddr string, config *Config) (net.Listener, error)"}, - {"LoadX509KeyPair", Func, 0, "func(certFile string, keyFile string) (Certificate, error)"}, - {"NewLRUClientSessionCache", Func, 3, "func(capacity int) ClientSessionCache"}, - {"NewListener", Func, 0, "func(inner net.Listener, config *Config) net.Listener"}, - {"NewResumptionState", Func, 21, "func(ticket []byte, state *SessionState) (*ClientSessionState, error)"}, - {"NoClientCert", Const, 0, ""}, - {"PKCS1WithSHA1", Const, 8, ""}, - {"PKCS1WithSHA256", Const, 8, ""}, - {"PKCS1WithSHA384", Const, 8, ""}, - {"PKCS1WithSHA512", Const, 8, ""}, - {"PSSWithSHA256", Const, 8, ""}, - {"PSSWithSHA384", Const, 8, ""}, - {"PSSWithSHA512", Const, 8, ""}, - {"ParseSessionState", Func, 21, "func(data []byte) (*SessionState, error)"}, - {"QUICClient", Func, 21, "func(config *QUICConfig) *QUICConn"}, - {"QUICConfig", Type, 21, ""}, - {"QUICConfig.EnableSessionEvents", Field, 23, ""}, - {"QUICConfig.TLSConfig", Field, 21, ""}, - {"QUICConn", Type, 21, ""}, - {"QUICEncryptionLevel", Type, 21, ""}, - {"QUICEncryptionLevelApplication", Const, 21, ""}, - {"QUICEncryptionLevelEarly", Const, 21, ""}, - {"QUICEncryptionLevelHandshake", Const, 21, ""}, - {"QUICEncryptionLevelInitial", Const, 21, ""}, - {"QUICErrorEvent", Const, 26, ""}, - {"QUICEvent", Type, 21, ""}, - {"QUICEvent.Data", Field, 21, ""}, - {"QUICEvent.Err", Field, 26, ""}, - {"QUICEvent.Kind", Field, 21, ""}, - {"QUICEvent.Level", Field, 21, ""}, - {"QUICEvent.SessionState", Field, 23, ""}, - {"QUICEvent.Suite", Field, 21, ""}, - {"QUICEventKind", Type, 21, ""}, - {"QUICHandshakeDone", Const, 21, ""}, - {"QUICNoEvent", Const, 21, ""}, - {"QUICRejectedEarlyData", Const, 21, ""}, - {"QUICResumeSession", Const, 23, ""}, - {"QUICServer", Func, 21, "func(config *QUICConfig) *QUICConn"}, - {"QUICSessionTicketOptions", Type, 21, ""}, - {"QUICSessionTicketOptions.EarlyData", Field, 21, ""}, - {"QUICSessionTicketOptions.Extra", Field, 23, ""}, - {"QUICSetReadSecret", Const, 21, ""}, - {"QUICSetWriteSecret", Const, 21, ""}, - {"QUICStoreSession", Const, 23, ""}, - {"QUICTransportParameters", Const, 21, ""}, - {"QUICTransportParametersRequired", Const, 21, ""}, - {"QUICWriteData", Const, 21, ""}, - {"RecordHeaderError", Type, 6, ""}, - {"RecordHeaderError.Conn", Field, 12, ""}, - {"RecordHeaderError.Msg", Field, 6, ""}, - {"RecordHeaderError.RecordHeader", Field, 6, ""}, - {"RenegotiateFreelyAsClient", Const, 7, ""}, - {"RenegotiateNever", Const, 7, ""}, - {"RenegotiateOnceAsClient", Const, 7, ""}, - {"RenegotiationSupport", Type, 7, ""}, - {"RequestClientCert", Const, 0, ""}, - {"RequireAndVerifyClientCert", Const, 0, ""}, - {"RequireAnyClientCert", Const, 0, ""}, - {"SecP256r1MLKEM768", Const, 26, ""}, - {"SecP384r1MLKEM1024", Const, 26, ""}, - {"Server", Func, 0, "func(conn net.Conn, config *Config) *Conn"}, - {"SessionState", Type, 21, ""}, - {"SessionState.EarlyData", Field, 21, ""}, - {"SessionState.Extra", Field, 21, ""}, - {"SignatureScheme", Type, 8, ""}, - {"TLS_AES_128_GCM_SHA256", Const, 12, ""}, - {"TLS_AES_256_GCM_SHA384", Const, 12, ""}, - {"TLS_CHACHA20_POLY1305_SHA256", Const, 12, ""}, - {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", Const, 2, ""}, - {"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", Const, 8, ""}, - {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", Const, 2, ""}, - {"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", Const, 2, ""}, - {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", Const, 5, ""}, - {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", Const, 8, ""}, - {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14, ""}, - {"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", Const, 2, ""}, - {"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0, ""}, - {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", Const, 0, ""}, - {"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", Const, 8, ""}, - {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", Const, 2, ""}, - {"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", Const, 1, ""}, - {"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", Const, 5, ""}, - {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", Const, 8, ""}, - {"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", Const, 14, ""}, - {"TLS_ECDHE_RSA_WITH_RC4_128_SHA", Const, 0, ""}, - {"TLS_FALLBACK_SCSV", Const, 4, ""}, - {"TLS_RSA_WITH_3DES_EDE_CBC_SHA", Const, 0, ""}, - {"TLS_RSA_WITH_AES_128_CBC_SHA", Const, 0, ""}, - {"TLS_RSA_WITH_AES_128_CBC_SHA256", Const, 8, ""}, - {"TLS_RSA_WITH_AES_128_GCM_SHA256", Const, 6, ""}, - {"TLS_RSA_WITH_AES_256_CBC_SHA", Const, 1, ""}, - {"TLS_RSA_WITH_AES_256_GCM_SHA384", Const, 6, ""}, - {"TLS_RSA_WITH_RC4_128_SHA", Const, 0, ""}, - {"VerifyClientCertIfGiven", Const, 0, ""}, - {"VersionName", Func, 21, "func(version uint16) string"}, - {"VersionSSL30", Const, 2, ""}, - {"VersionTLS10", Const, 2, ""}, - {"VersionTLS11", Const, 2, ""}, - {"VersionTLS12", Const, 2, ""}, - {"VersionTLS13", Const, 12, ""}, - {"X25519", Const, 8, ""}, - {"X25519MLKEM768", Const, 24, ""}, - {"X509KeyPair", Func, 0, "func(certPEMBlock []byte, keyPEMBlock []byte) (Certificate, error)"}, - }, - "crypto/x509": { - {"(*CertPool).AddCert", Method, 0, ""}, - {"(*CertPool).AddCertWithConstraint", Method, 22, ""}, - {"(*CertPool).AppendCertsFromPEM", Method, 0, ""}, - {"(*CertPool).Clone", Method, 19, ""}, - {"(*CertPool).Equal", Method, 19, ""}, - {"(*CertPool).Subjects", Method, 0, ""}, - {"(*Certificate).CheckCRLSignature", Method, 0, ""}, - {"(*Certificate).CheckSignature", Method, 0, ""}, - {"(*Certificate).CheckSignatureFrom", Method, 0, ""}, - {"(*Certificate).CreateCRL", Method, 0, ""}, - {"(*Certificate).Equal", Method, 0, ""}, - {"(*Certificate).Verify", Method, 0, ""}, - {"(*Certificate).VerifyHostname", Method, 0, ""}, - {"(*CertificateRequest).CheckSignature", Method, 5, ""}, - {"(*OID).UnmarshalBinary", Method, 23, ""}, - {"(*OID).UnmarshalText", Method, 23, ""}, - {"(*RevocationList).CheckSignatureFrom", Method, 19, ""}, - {"(CertificateInvalidError).Error", Method, 0, ""}, - {"(ConstraintViolationError).Error", Method, 0, ""}, - {"(ExtKeyUsage).OID", Method, 26, ""}, - {"(ExtKeyUsage).String", Method, 26, ""}, - {"(HostnameError).Error", Method, 0, ""}, - {"(InsecureAlgorithmError).Error", Method, 6, ""}, - {"(KeyUsage).String", Method, 26, ""}, - {"(OID).AppendBinary", Method, 24, ""}, - {"(OID).AppendText", Method, 24, ""}, - {"(OID).Equal", Method, 22, ""}, - {"(OID).EqualASN1OID", Method, 22, ""}, - {"(OID).MarshalBinary", Method, 23, ""}, - {"(OID).MarshalText", Method, 23, ""}, - {"(OID).String", Method, 22, ""}, - {"(PublicKeyAlgorithm).String", Method, 10, ""}, - {"(SignatureAlgorithm).String", Method, 6, ""}, - {"(SystemRootsError).Error", Method, 1, ""}, - {"(SystemRootsError).Unwrap", Method, 16, ""}, - {"(UnhandledCriticalExtension).Error", Method, 0, ""}, - {"(UnknownAuthorityError).Error", Method, 0, ""}, - {"CANotAuthorizedForExtKeyUsage", Const, 10, ""}, - {"CANotAuthorizedForThisName", Const, 0, ""}, - {"CertPool", Type, 0, ""}, - {"Certificate", Type, 0, ""}, - {"Certificate.AuthorityKeyId", Field, 0, ""}, - {"Certificate.BasicConstraintsValid", Field, 0, ""}, - {"Certificate.CRLDistributionPoints", Field, 2, ""}, - {"Certificate.DNSNames", Field, 0, ""}, - {"Certificate.EmailAddresses", Field, 0, ""}, - {"Certificate.ExcludedDNSDomains", Field, 9, ""}, - {"Certificate.ExcludedEmailAddresses", Field, 10, ""}, - {"Certificate.ExcludedIPRanges", Field, 10, ""}, - {"Certificate.ExcludedURIDomains", Field, 10, ""}, - {"Certificate.ExtKeyUsage", Field, 0, ""}, - {"Certificate.Extensions", Field, 2, ""}, - {"Certificate.ExtraExtensions", Field, 2, ""}, - {"Certificate.IPAddresses", Field, 1, ""}, - {"Certificate.InhibitAnyPolicy", Field, 24, ""}, - {"Certificate.InhibitAnyPolicyZero", Field, 24, ""}, - {"Certificate.InhibitPolicyMapping", Field, 24, ""}, - {"Certificate.InhibitPolicyMappingZero", Field, 24, ""}, - {"Certificate.IsCA", Field, 0, ""}, - {"Certificate.Issuer", Field, 0, ""}, - {"Certificate.IssuingCertificateURL", Field, 2, ""}, - {"Certificate.KeyUsage", Field, 0, ""}, - {"Certificate.MaxPathLen", Field, 0, ""}, - {"Certificate.MaxPathLenZero", Field, 4, ""}, - {"Certificate.NotAfter", Field, 0, ""}, - {"Certificate.NotBefore", Field, 0, ""}, - {"Certificate.OCSPServer", Field, 2, ""}, - {"Certificate.PermittedDNSDomains", Field, 0, ""}, - {"Certificate.PermittedDNSDomainsCritical", Field, 0, ""}, - {"Certificate.PermittedEmailAddresses", Field, 10, ""}, - {"Certificate.PermittedIPRanges", Field, 10, ""}, - {"Certificate.PermittedURIDomains", Field, 10, ""}, - {"Certificate.Policies", Field, 22, ""}, - {"Certificate.PolicyIdentifiers", Field, 0, ""}, - {"Certificate.PolicyMappings", Field, 24, ""}, - {"Certificate.PublicKey", Field, 0, ""}, - {"Certificate.PublicKeyAlgorithm", Field, 0, ""}, - {"Certificate.Raw", Field, 0, ""}, - {"Certificate.RawIssuer", Field, 0, ""}, - {"Certificate.RawSubject", Field, 0, ""}, - {"Certificate.RawSubjectPublicKeyInfo", Field, 0, ""}, - {"Certificate.RawTBSCertificate", Field, 0, ""}, - {"Certificate.RequireExplicitPolicy", Field, 24, ""}, - {"Certificate.RequireExplicitPolicyZero", Field, 24, ""}, - {"Certificate.SerialNumber", Field, 0, ""}, - {"Certificate.Signature", Field, 0, ""}, - {"Certificate.SignatureAlgorithm", Field, 0, ""}, - {"Certificate.Subject", Field, 0, ""}, - {"Certificate.SubjectKeyId", Field, 0, ""}, - {"Certificate.URIs", Field, 10, ""}, - {"Certificate.UnhandledCriticalExtensions", Field, 5, ""}, - {"Certificate.UnknownExtKeyUsage", Field, 0, ""}, - {"Certificate.Version", Field, 0, ""}, - {"CertificateInvalidError", Type, 0, ""}, - {"CertificateInvalidError.Cert", Field, 0, ""}, - {"CertificateInvalidError.Detail", Field, 10, ""}, - {"CertificateInvalidError.Reason", Field, 0, ""}, - {"CertificateRequest", Type, 3, ""}, - {"CertificateRequest.Attributes", Field, 3, ""}, - {"CertificateRequest.DNSNames", Field, 3, ""}, - {"CertificateRequest.EmailAddresses", Field, 3, ""}, - {"CertificateRequest.Extensions", Field, 3, ""}, - {"CertificateRequest.ExtraExtensions", Field, 3, ""}, - {"CertificateRequest.IPAddresses", Field, 3, ""}, - {"CertificateRequest.PublicKey", Field, 3, ""}, - {"CertificateRequest.PublicKeyAlgorithm", Field, 3, ""}, - {"CertificateRequest.Raw", Field, 3, ""}, - {"CertificateRequest.RawSubject", Field, 3, ""}, - {"CertificateRequest.RawSubjectPublicKeyInfo", Field, 3, ""}, - {"CertificateRequest.RawTBSCertificateRequest", Field, 3, ""}, - {"CertificateRequest.Signature", Field, 3, ""}, - {"CertificateRequest.SignatureAlgorithm", Field, 3, ""}, - {"CertificateRequest.Subject", Field, 3, ""}, - {"CertificateRequest.URIs", Field, 10, ""}, - {"CertificateRequest.Version", Field, 3, ""}, - {"ConstraintViolationError", Type, 0, ""}, - {"CreateCertificate", Func, 0, "func(rand io.Reader, template *Certificate, parent *Certificate, pub any, priv any) ([]byte, error)"}, - {"CreateCertificateRequest", Func, 3, "func(rand io.Reader, template *CertificateRequest, priv any) (csr []byte, err error)"}, - {"CreateRevocationList", Func, 15, "func(rand io.Reader, template *RevocationList, issuer *Certificate, priv crypto.Signer) ([]byte, error)"}, - {"DSA", Const, 0, ""}, - {"DSAWithSHA1", Const, 0, ""}, - {"DSAWithSHA256", Const, 0, ""}, - {"DecryptPEMBlock", Func, 1, "func(b *pem.Block, password []byte) ([]byte, error)"}, - {"ECDSA", Const, 1, ""}, - {"ECDSAWithSHA1", Const, 1, ""}, - {"ECDSAWithSHA256", Const, 1, ""}, - {"ECDSAWithSHA384", Const, 1, ""}, - {"ECDSAWithSHA512", Const, 1, ""}, - {"Ed25519", Const, 13, ""}, - {"EncryptPEMBlock", Func, 1, "func(rand io.Reader, blockType string, data []byte, password []byte, alg PEMCipher) (*pem.Block, error)"}, - {"ErrUnsupportedAlgorithm", Var, 0, ""}, - {"Expired", Const, 0, ""}, - {"ExtKeyUsage", Type, 0, ""}, - {"ExtKeyUsageAny", Const, 0, ""}, - {"ExtKeyUsageClientAuth", Const, 0, ""}, - {"ExtKeyUsageCodeSigning", Const, 0, ""}, - {"ExtKeyUsageEmailProtection", Const, 0, ""}, - {"ExtKeyUsageIPSECEndSystem", Const, 1, ""}, - {"ExtKeyUsageIPSECTunnel", Const, 1, ""}, - {"ExtKeyUsageIPSECUser", Const, 1, ""}, - {"ExtKeyUsageMicrosoftCommercialCodeSigning", Const, 10, ""}, - {"ExtKeyUsageMicrosoftKernelCodeSigning", Const, 10, ""}, - {"ExtKeyUsageMicrosoftServerGatedCrypto", Const, 1, ""}, - {"ExtKeyUsageNetscapeServerGatedCrypto", Const, 1, ""}, - {"ExtKeyUsageOCSPSigning", Const, 0, ""}, - {"ExtKeyUsageServerAuth", Const, 0, ""}, - {"ExtKeyUsageTimeStamping", Const, 0, ""}, - {"HostnameError", Type, 0, ""}, - {"HostnameError.Certificate", Field, 0, ""}, - {"HostnameError.Host", Field, 0, ""}, - {"IncompatibleUsage", Const, 1, ""}, - {"IncorrectPasswordError", Var, 1, ""}, - {"InsecureAlgorithmError", Type, 6, ""}, - {"InvalidReason", Type, 0, ""}, - {"IsEncryptedPEMBlock", Func, 1, "func(b *pem.Block) bool"}, - {"KeyUsage", Type, 0, ""}, - {"KeyUsageCRLSign", Const, 0, ""}, - {"KeyUsageCertSign", Const, 0, ""}, - {"KeyUsageContentCommitment", Const, 0, ""}, - {"KeyUsageDataEncipherment", Const, 0, ""}, - {"KeyUsageDecipherOnly", Const, 0, ""}, - {"KeyUsageDigitalSignature", Const, 0, ""}, - {"KeyUsageEncipherOnly", Const, 0, ""}, - {"KeyUsageKeyAgreement", Const, 0, ""}, - {"KeyUsageKeyEncipherment", Const, 0, ""}, - {"MD2WithRSA", Const, 0, ""}, - {"MD5WithRSA", Const, 0, ""}, - {"MarshalECPrivateKey", Func, 2, "func(key *ecdsa.PrivateKey) ([]byte, error)"}, - {"MarshalPKCS1PrivateKey", Func, 0, "func(key *rsa.PrivateKey) []byte"}, - {"MarshalPKCS1PublicKey", Func, 10, "func(key *rsa.PublicKey) []byte"}, - {"MarshalPKCS8PrivateKey", Func, 10, "func(key any) ([]byte, error)"}, - {"MarshalPKIXPublicKey", Func, 0, "func(pub any) ([]byte, error)"}, - {"NameConstraintsWithoutSANs", Const, 10, ""}, - {"NameMismatch", Const, 8, ""}, - {"NewCertPool", Func, 0, "func() *CertPool"}, - {"NoValidChains", Const, 24, ""}, - {"NotAuthorizedToSign", Const, 0, ""}, - {"OID", Type, 22, ""}, - {"OIDFromASN1OID", Func, 26, "func(asn1OID asn1.ObjectIdentifier) (OID, error)"}, - {"OIDFromInts", Func, 22, "func(oid []uint64) (OID, error)"}, - {"PEMCipher", Type, 1, ""}, - {"PEMCipher3DES", Const, 1, ""}, - {"PEMCipherAES128", Const, 1, ""}, - {"PEMCipherAES192", Const, 1, ""}, - {"PEMCipherAES256", Const, 1, ""}, - {"PEMCipherDES", Const, 1, ""}, - {"ParseCRL", Func, 0, "func(crlBytes []byte) (*pkix.CertificateList, error)"}, - {"ParseCertificate", Func, 0, "func(der []byte) (*Certificate, error)"}, - {"ParseCertificateRequest", Func, 3, "func(asn1Data []byte) (*CertificateRequest, error)"}, - {"ParseCertificates", Func, 0, "func(der []byte) ([]*Certificate, error)"}, - {"ParseDERCRL", Func, 0, "func(derBytes []byte) (*pkix.CertificateList, error)"}, - {"ParseECPrivateKey", Func, 1, "func(der []byte) (*ecdsa.PrivateKey, error)"}, - {"ParseOID", Func, 23, "func(oid string) (OID, error)"}, - {"ParsePKCS1PrivateKey", Func, 0, "func(der []byte) (*rsa.PrivateKey, error)"}, - {"ParsePKCS1PublicKey", Func, 10, "func(der []byte) (*rsa.PublicKey, error)"}, - {"ParsePKCS8PrivateKey", Func, 0, "func(der []byte) (key any, err error)"}, - {"ParsePKIXPublicKey", Func, 0, "func(derBytes []byte) (pub any, err error)"}, - {"ParseRevocationList", Func, 19, "func(der []byte) (*RevocationList, error)"}, - {"PolicyMapping", Type, 24, ""}, - {"PolicyMapping.IssuerDomainPolicy", Field, 24, ""}, - {"PolicyMapping.SubjectDomainPolicy", Field, 24, ""}, - {"PublicKeyAlgorithm", Type, 0, ""}, - {"PureEd25519", Const, 13, ""}, - {"RSA", Const, 0, ""}, - {"RevocationList", Type, 15, ""}, - {"RevocationList.AuthorityKeyId", Field, 19, ""}, - {"RevocationList.Extensions", Field, 19, ""}, - {"RevocationList.ExtraExtensions", Field, 15, ""}, - {"RevocationList.Issuer", Field, 19, ""}, - {"RevocationList.NextUpdate", Field, 15, ""}, - {"RevocationList.Number", Field, 15, ""}, - {"RevocationList.Raw", Field, 19, ""}, - {"RevocationList.RawIssuer", Field, 19, ""}, - {"RevocationList.RawTBSRevocationList", Field, 19, ""}, - {"RevocationList.RevokedCertificateEntries", Field, 21, ""}, - {"RevocationList.RevokedCertificates", Field, 15, ""}, - {"RevocationList.Signature", Field, 19, ""}, - {"RevocationList.SignatureAlgorithm", Field, 15, ""}, - {"RevocationList.ThisUpdate", Field, 15, ""}, - {"RevocationListEntry", Type, 21, ""}, - {"RevocationListEntry.Extensions", Field, 21, ""}, - {"RevocationListEntry.ExtraExtensions", Field, 21, ""}, - {"RevocationListEntry.Raw", Field, 21, ""}, - {"RevocationListEntry.ReasonCode", Field, 21, ""}, - {"RevocationListEntry.RevocationTime", Field, 21, ""}, - {"RevocationListEntry.SerialNumber", Field, 21, ""}, - {"SHA1WithRSA", Const, 0, ""}, - {"SHA256WithRSA", Const, 0, ""}, - {"SHA256WithRSAPSS", Const, 8, ""}, - {"SHA384WithRSA", Const, 0, ""}, - {"SHA384WithRSAPSS", Const, 8, ""}, - {"SHA512WithRSA", Const, 0, ""}, - {"SHA512WithRSAPSS", Const, 8, ""}, - {"SetFallbackRoots", Func, 20, "func(roots *CertPool)"}, - {"SignatureAlgorithm", Type, 0, ""}, - {"SystemCertPool", Func, 7, "func() (*CertPool, error)"}, - {"SystemRootsError", Type, 1, ""}, - {"SystemRootsError.Err", Field, 7, ""}, - {"TooManyConstraints", Const, 10, ""}, - {"TooManyIntermediates", Const, 0, ""}, - {"UnconstrainedName", Const, 10, ""}, - {"UnhandledCriticalExtension", Type, 0, ""}, - {"UnknownAuthorityError", Type, 0, ""}, - {"UnknownAuthorityError.Cert", Field, 8, ""}, - {"UnknownPublicKeyAlgorithm", Const, 0, ""}, - {"UnknownSignatureAlgorithm", Const, 0, ""}, - {"VerifyOptions", Type, 0, ""}, - {"VerifyOptions.CertificatePolicies", Field, 24, ""}, - {"VerifyOptions.CurrentTime", Field, 0, ""}, - {"VerifyOptions.DNSName", Field, 0, ""}, - {"VerifyOptions.Intermediates", Field, 0, ""}, - {"VerifyOptions.KeyUsages", Field, 1, ""}, - {"VerifyOptions.MaxConstraintComparisions", Field, 10, ""}, - {"VerifyOptions.Roots", Field, 0, ""}, - }, - "crypto/x509/pkix": { - {"(*CertificateList).HasExpired", Method, 0, ""}, - {"(*Name).FillFromRDNSequence", Method, 0, ""}, - {"(Name).String", Method, 10, ""}, - {"(Name).ToRDNSequence", Method, 0, ""}, - {"(RDNSequence).String", Method, 10, ""}, - {"AlgorithmIdentifier", Type, 0, ""}, - {"AlgorithmIdentifier.Algorithm", Field, 0, ""}, - {"AlgorithmIdentifier.Parameters", Field, 0, ""}, - {"AttributeTypeAndValue", Type, 0, ""}, - {"AttributeTypeAndValue.Type", Field, 0, ""}, - {"AttributeTypeAndValue.Value", Field, 0, ""}, - {"AttributeTypeAndValueSET", Type, 3, ""}, - {"AttributeTypeAndValueSET.Type", Field, 3, ""}, - {"AttributeTypeAndValueSET.Value", Field, 3, ""}, - {"CertificateList", Type, 0, ""}, - {"CertificateList.SignatureAlgorithm", Field, 0, ""}, - {"CertificateList.SignatureValue", Field, 0, ""}, - {"CertificateList.TBSCertList", Field, 0, ""}, - {"Extension", Type, 0, ""}, - {"Extension.Critical", Field, 0, ""}, - {"Extension.Id", Field, 0, ""}, - {"Extension.Value", Field, 0, ""}, - {"Name", Type, 0, ""}, - {"Name.CommonName", Field, 0, ""}, - {"Name.Country", Field, 0, ""}, - {"Name.ExtraNames", Field, 5, ""}, - {"Name.Locality", Field, 0, ""}, - {"Name.Names", Field, 0, ""}, - {"Name.Organization", Field, 0, ""}, - {"Name.OrganizationalUnit", Field, 0, ""}, - {"Name.PostalCode", Field, 0, ""}, - {"Name.Province", Field, 0, ""}, - {"Name.SerialNumber", Field, 0, ""}, - {"Name.StreetAddress", Field, 0, ""}, - {"RDNSequence", Type, 0, ""}, - {"RelativeDistinguishedNameSET", Type, 0, ""}, - {"RevokedCertificate", Type, 0, ""}, - {"RevokedCertificate.Extensions", Field, 0, ""}, - {"RevokedCertificate.RevocationTime", Field, 0, ""}, - {"RevokedCertificate.SerialNumber", Field, 0, ""}, - {"TBSCertificateList", Type, 0, ""}, - {"TBSCertificateList.Extensions", Field, 0, ""}, - {"TBSCertificateList.Issuer", Field, 0, ""}, - {"TBSCertificateList.NextUpdate", Field, 0, ""}, - {"TBSCertificateList.Raw", Field, 0, ""}, - {"TBSCertificateList.RevokedCertificates", Field, 0, ""}, - {"TBSCertificateList.Signature", Field, 0, ""}, - {"TBSCertificateList.ThisUpdate", Field, 0, ""}, - {"TBSCertificateList.Version", Field, 0, ""}, - }, - "database/sql": { - {"(*ColumnType).DatabaseTypeName", Method, 8, ""}, - {"(*ColumnType).DecimalSize", Method, 8, ""}, - {"(*ColumnType).Length", Method, 8, ""}, - {"(*ColumnType).Name", Method, 8, ""}, - {"(*ColumnType).Nullable", Method, 8, ""}, - {"(*ColumnType).ScanType", Method, 8, ""}, - {"(*Conn).BeginTx", Method, 9, ""}, - {"(*Conn).Close", Method, 9, ""}, - {"(*Conn).ExecContext", Method, 9, ""}, - {"(*Conn).PingContext", Method, 9, ""}, - {"(*Conn).PrepareContext", Method, 9, ""}, - {"(*Conn).QueryContext", Method, 9, ""}, - {"(*Conn).QueryRowContext", Method, 9, ""}, - {"(*Conn).Raw", Method, 13, ""}, - {"(*DB).Begin", Method, 0, ""}, - {"(*DB).BeginTx", Method, 8, ""}, - {"(*DB).Close", Method, 0, ""}, - {"(*DB).Conn", Method, 9, ""}, - {"(*DB).Driver", Method, 0, ""}, - {"(*DB).Exec", Method, 0, ""}, - {"(*DB).ExecContext", Method, 8, ""}, - {"(*DB).Ping", Method, 1, ""}, - {"(*DB).PingContext", Method, 8, ""}, - {"(*DB).Prepare", Method, 0, ""}, - {"(*DB).PrepareContext", Method, 8, ""}, - {"(*DB).Query", Method, 0, ""}, - {"(*DB).QueryContext", Method, 8, ""}, - {"(*DB).QueryRow", Method, 0, ""}, - {"(*DB).QueryRowContext", Method, 8, ""}, - {"(*DB).SetConnMaxIdleTime", Method, 15, ""}, - {"(*DB).SetConnMaxLifetime", Method, 6, ""}, - {"(*DB).SetMaxIdleConns", Method, 1, ""}, - {"(*DB).SetMaxOpenConns", Method, 2, ""}, - {"(*DB).Stats", Method, 5, ""}, - {"(*Null).Scan", Method, 22, ""}, - {"(*NullBool).Scan", Method, 0, ""}, - {"(*NullByte).Scan", Method, 17, ""}, - {"(*NullFloat64).Scan", Method, 0, ""}, - {"(*NullInt16).Scan", Method, 17, ""}, - {"(*NullInt32).Scan", Method, 13, ""}, - {"(*NullInt64).Scan", Method, 0, ""}, - {"(*NullString).Scan", Method, 0, ""}, - {"(*NullTime).Scan", Method, 13, ""}, - {"(*Row).Err", Method, 15, ""}, - {"(*Row).Scan", Method, 0, ""}, - {"(*Rows).Close", Method, 0, ""}, - {"(*Rows).ColumnTypes", Method, 8, ""}, - {"(*Rows).Columns", Method, 0, ""}, - {"(*Rows).Err", Method, 0, ""}, - {"(*Rows).Next", Method, 0, ""}, - {"(*Rows).NextResultSet", Method, 8, ""}, - {"(*Rows).Scan", Method, 0, ""}, - {"(*Stmt).Close", Method, 0, ""}, - {"(*Stmt).Exec", Method, 0, ""}, - {"(*Stmt).ExecContext", Method, 8, ""}, - {"(*Stmt).Query", Method, 0, ""}, - {"(*Stmt).QueryContext", Method, 8, ""}, - {"(*Stmt).QueryRow", Method, 0, ""}, - {"(*Stmt).QueryRowContext", Method, 8, ""}, - {"(*Tx).Commit", Method, 0, ""}, - {"(*Tx).Exec", Method, 0, ""}, - {"(*Tx).ExecContext", Method, 8, ""}, - {"(*Tx).Prepare", Method, 0, ""}, - {"(*Tx).PrepareContext", Method, 8, ""}, - {"(*Tx).Query", Method, 0, ""}, - {"(*Tx).QueryContext", Method, 8, ""}, - {"(*Tx).QueryRow", Method, 0, ""}, - {"(*Tx).QueryRowContext", Method, 8, ""}, - {"(*Tx).Rollback", Method, 0, ""}, - {"(*Tx).Stmt", Method, 0, ""}, - {"(*Tx).StmtContext", Method, 8, ""}, - {"(IsolationLevel).String", Method, 11, ""}, - {"(Null).Value", Method, 22, ""}, - {"(NullBool).Value", Method, 0, ""}, - {"(NullByte).Value", Method, 17, ""}, - {"(NullFloat64).Value", Method, 0, ""}, - {"(NullInt16).Value", Method, 17, ""}, - {"(NullInt32).Value", Method, 13, ""}, - {"(NullInt64).Value", Method, 0, ""}, - {"(NullString).Value", Method, 0, ""}, - {"(NullTime).Value", Method, 13, ""}, - {"(Result).LastInsertId", Method, 0, ""}, - {"(Result).RowsAffected", Method, 0, ""}, - {"(Scanner).Scan", Method, 0, ""}, - {"ColumnType", Type, 8, ""}, - {"Conn", Type, 9, ""}, - {"DB", Type, 0, ""}, - {"DBStats", Type, 5, ""}, - {"DBStats.Idle", Field, 11, ""}, - {"DBStats.InUse", Field, 11, ""}, - {"DBStats.MaxIdleClosed", Field, 11, ""}, - {"DBStats.MaxIdleTimeClosed", Field, 15, ""}, - {"DBStats.MaxLifetimeClosed", Field, 11, ""}, - {"DBStats.MaxOpenConnections", Field, 11, ""}, - {"DBStats.OpenConnections", Field, 5, ""}, - {"DBStats.WaitCount", Field, 11, ""}, - {"DBStats.WaitDuration", Field, 11, ""}, - {"Drivers", Func, 4, "func() []string"}, - {"ErrConnDone", Var, 9, ""}, - {"ErrNoRows", Var, 0, ""}, - {"ErrTxDone", Var, 0, ""}, - {"IsolationLevel", Type, 8, ""}, - {"LevelDefault", Const, 8, ""}, - {"LevelLinearizable", Const, 8, ""}, - {"LevelReadCommitted", Const, 8, ""}, - {"LevelReadUncommitted", Const, 8, ""}, - {"LevelRepeatableRead", Const, 8, ""}, - {"LevelSerializable", Const, 8, ""}, - {"LevelSnapshot", Const, 8, ""}, - {"LevelWriteCommitted", Const, 8, ""}, - {"Named", Func, 8, "func(name string, value any) NamedArg"}, - {"NamedArg", Type, 8, ""}, - {"NamedArg.Name", Field, 8, ""}, - {"NamedArg.Value", Field, 8, ""}, - {"Null", Type, 22, ""}, - {"NullBool", Type, 0, ""}, - {"NullBool.Bool", Field, 0, ""}, - {"NullBool.Valid", Field, 0, ""}, - {"NullByte", Type, 17, ""}, - {"NullByte.Byte", Field, 17, ""}, - {"NullByte.Valid", Field, 17, ""}, - {"NullFloat64", Type, 0, ""}, - {"NullFloat64.Float64", Field, 0, ""}, - {"NullFloat64.Valid", Field, 0, ""}, - {"NullInt16", Type, 17, ""}, - {"NullInt16.Int16", Field, 17, ""}, - {"NullInt16.Valid", Field, 17, ""}, - {"NullInt32", Type, 13, ""}, - {"NullInt32.Int32", Field, 13, ""}, - {"NullInt32.Valid", Field, 13, ""}, - {"NullInt64", Type, 0, ""}, - {"NullInt64.Int64", Field, 0, ""}, - {"NullInt64.Valid", Field, 0, ""}, - {"NullString", Type, 0, ""}, - {"NullString.String", Field, 0, ""}, - {"NullString.Valid", Field, 0, ""}, - {"NullTime", Type, 13, ""}, - {"NullTime.Time", Field, 13, ""}, - {"NullTime.Valid", Field, 13, ""}, - {"Open", Func, 0, "func(driverName string, dataSourceName string) (*DB, error)"}, - {"OpenDB", Func, 10, "func(c driver.Connector) *DB"}, - {"Out", Type, 9, ""}, - {"Out.Dest", Field, 9, ""}, - {"Out.In", Field, 9, ""}, - {"RawBytes", Type, 0, ""}, - {"Register", Func, 0, "func(name string, driver driver.Driver)"}, - {"Result", Type, 0, ""}, - {"Row", Type, 0, ""}, - {"Rows", Type, 0, ""}, - {"Scanner", Type, 0, ""}, - {"Stmt", Type, 0, ""}, - {"Tx", Type, 0, ""}, - {"TxOptions", Type, 8, ""}, - {"TxOptions.Isolation", Field, 8, ""}, - {"TxOptions.ReadOnly", Field, 8, ""}, - }, - "database/sql/driver": { - {"(ColumnConverter).ColumnConverter", Method, 0, ""}, - {"(Conn).Begin", Method, 0, ""}, - {"(Conn).Close", Method, 0, ""}, - {"(Conn).Prepare", Method, 0, ""}, - {"(ConnBeginTx).BeginTx", Method, 8, ""}, - {"(ConnPrepareContext).PrepareContext", Method, 8, ""}, - {"(Connector).Connect", Method, 10, ""}, - {"(Connector).Driver", Method, 10, ""}, - {"(Driver).Open", Method, 0, ""}, - {"(DriverContext).OpenConnector", Method, 10, ""}, - {"(Execer).Exec", Method, 0, ""}, - {"(ExecerContext).ExecContext", Method, 8, ""}, - {"(NamedValueChecker).CheckNamedValue", Method, 9, ""}, - {"(NotNull).ConvertValue", Method, 0, ""}, - {"(Null).ConvertValue", Method, 0, ""}, - {"(Pinger).Ping", Method, 8, ""}, - {"(Queryer).Query", Method, 1, ""}, - {"(QueryerContext).QueryContext", Method, 8, ""}, - {"(Result).LastInsertId", Method, 0, ""}, - {"(Result).RowsAffected", Method, 0, ""}, - {"(Rows).Close", Method, 0, ""}, - {"(Rows).Columns", Method, 0, ""}, - {"(Rows).Next", Method, 0, ""}, - {"(RowsAffected).LastInsertId", Method, 0, ""}, - {"(RowsAffected).RowsAffected", Method, 0, ""}, - {"(RowsColumnTypeDatabaseTypeName).Close", Method, 8, ""}, - {"(RowsColumnTypeDatabaseTypeName).ColumnTypeDatabaseTypeName", Method, 8, ""}, - {"(RowsColumnTypeDatabaseTypeName).Columns", Method, 8, ""}, - {"(RowsColumnTypeDatabaseTypeName).Next", Method, 8, ""}, - {"(RowsColumnTypeLength).Close", Method, 8, ""}, - {"(RowsColumnTypeLength).ColumnTypeLength", Method, 8, ""}, - {"(RowsColumnTypeLength).Columns", Method, 8, ""}, - {"(RowsColumnTypeLength).Next", Method, 8, ""}, - {"(RowsColumnTypeNullable).Close", Method, 8, ""}, - {"(RowsColumnTypeNullable).ColumnTypeNullable", Method, 8, ""}, - {"(RowsColumnTypeNullable).Columns", Method, 8, ""}, - {"(RowsColumnTypeNullable).Next", Method, 8, ""}, - {"(RowsColumnTypePrecisionScale).Close", Method, 8, ""}, - {"(RowsColumnTypePrecisionScale).ColumnTypePrecisionScale", Method, 8, ""}, - {"(RowsColumnTypePrecisionScale).Columns", Method, 8, ""}, - {"(RowsColumnTypePrecisionScale).Next", Method, 8, ""}, - {"(RowsColumnTypeScanType).Close", Method, 8, ""}, - {"(RowsColumnTypeScanType).ColumnTypeScanType", Method, 8, ""}, - {"(RowsColumnTypeScanType).Columns", Method, 8, ""}, - {"(RowsColumnTypeScanType).Next", Method, 8, ""}, - {"(RowsNextResultSet).Close", Method, 8, ""}, - {"(RowsNextResultSet).Columns", Method, 8, ""}, - {"(RowsNextResultSet).HasNextResultSet", Method, 8, ""}, - {"(RowsNextResultSet).Next", Method, 8, ""}, - {"(RowsNextResultSet).NextResultSet", Method, 8, ""}, - {"(SessionResetter).ResetSession", Method, 10, ""}, - {"(Stmt).Close", Method, 0, ""}, - {"(Stmt).Exec", Method, 0, ""}, - {"(Stmt).NumInput", Method, 0, ""}, - {"(Stmt).Query", Method, 0, ""}, - {"(StmtExecContext).ExecContext", Method, 8, ""}, - {"(StmtQueryContext).QueryContext", Method, 8, ""}, - {"(Tx).Commit", Method, 0, ""}, - {"(Tx).Rollback", Method, 0, ""}, - {"(Validator).IsValid", Method, 15, ""}, - {"(ValueConverter).ConvertValue", Method, 0, ""}, - {"(Valuer).Value", Method, 0, ""}, - {"Bool", Var, 0, ""}, - {"ColumnConverter", Type, 0, ""}, - {"Conn", Type, 0, ""}, - {"ConnBeginTx", Type, 8, ""}, - {"ConnPrepareContext", Type, 8, ""}, - {"Connector", Type, 10, ""}, - {"DefaultParameterConverter", Var, 0, ""}, - {"Driver", Type, 0, ""}, - {"DriverContext", Type, 10, ""}, - {"ErrBadConn", Var, 0, ""}, - {"ErrRemoveArgument", Var, 9, ""}, - {"ErrSkip", Var, 0, ""}, - {"Execer", Type, 0, ""}, - {"ExecerContext", Type, 8, ""}, - {"Int32", Var, 0, ""}, - {"IsScanValue", Func, 0, "func(v any) bool"}, - {"IsValue", Func, 0, "func(v any) bool"}, - {"IsolationLevel", Type, 8, ""}, - {"NamedValue", Type, 8, ""}, - {"NamedValue.Name", Field, 8, ""}, - {"NamedValue.Ordinal", Field, 8, ""}, - {"NamedValue.Value", Field, 8, ""}, - {"NamedValueChecker", Type, 9, ""}, - {"NotNull", Type, 0, ""}, - {"NotNull.Converter", Field, 0, ""}, - {"Null", Type, 0, ""}, - {"Null.Converter", Field, 0, ""}, - {"Pinger", Type, 8, ""}, - {"Queryer", Type, 1, ""}, - {"QueryerContext", Type, 8, ""}, - {"Result", Type, 0, ""}, - {"ResultNoRows", Var, 0, ""}, - {"Rows", Type, 0, ""}, - {"RowsAffected", Type, 0, ""}, - {"RowsColumnTypeDatabaseTypeName", Type, 8, ""}, - {"RowsColumnTypeLength", Type, 8, ""}, - {"RowsColumnTypeNullable", Type, 8, ""}, - {"RowsColumnTypePrecisionScale", Type, 8, ""}, - {"RowsColumnTypeScanType", Type, 8, ""}, - {"RowsNextResultSet", Type, 8, ""}, - {"SessionResetter", Type, 10, ""}, - {"Stmt", Type, 0, ""}, - {"StmtExecContext", Type, 8, ""}, - {"StmtQueryContext", Type, 8, ""}, - {"String", Var, 0, ""}, - {"Tx", Type, 0, ""}, - {"TxOptions", Type, 8, ""}, - {"TxOptions.Isolation", Field, 8, ""}, - {"TxOptions.ReadOnly", Field, 8, ""}, - {"Validator", Type, 15, ""}, - {"Value", Type, 0, ""}, - {"ValueConverter", Type, 0, ""}, - {"Valuer", Type, 0, ""}, - }, - "debug/buildinfo": { - {"BuildInfo", Type, 18, ""}, - {"Read", Func, 18, "func(r io.ReaderAt) (*BuildInfo, error)"}, - {"ReadFile", Func, 18, "func(name string) (info *BuildInfo, err error)"}, - }, - "debug/dwarf": { - {"(*AddrType).Basic", Method, 0, ""}, - {"(*AddrType).Common", Method, 0, ""}, - {"(*AddrType).Size", Method, 0, ""}, - {"(*AddrType).String", Method, 0, ""}, - {"(*ArrayType).Common", Method, 0, ""}, - {"(*ArrayType).Size", Method, 0, ""}, - {"(*ArrayType).String", Method, 0, ""}, - {"(*BasicType).Basic", Method, 0, ""}, - {"(*BasicType).Common", Method, 0, ""}, - {"(*BasicType).Size", Method, 0, ""}, - {"(*BasicType).String", Method, 0, ""}, - {"(*BoolType).Basic", Method, 0, ""}, - {"(*BoolType).Common", Method, 0, ""}, - {"(*BoolType).Size", Method, 0, ""}, - {"(*BoolType).String", Method, 0, ""}, - {"(*CharType).Basic", Method, 0, ""}, - {"(*CharType).Common", Method, 0, ""}, - {"(*CharType).Size", Method, 0, ""}, - {"(*CharType).String", Method, 0, ""}, - {"(*CommonType).Common", Method, 0, ""}, - {"(*CommonType).Size", Method, 0, ""}, - {"(*ComplexType).Basic", Method, 0, ""}, - {"(*ComplexType).Common", Method, 0, ""}, - {"(*ComplexType).Size", Method, 0, ""}, - {"(*ComplexType).String", Method, 0, ""}, - {"(*Data).AddSection", Method, 14, ""}, - {"(*Data).AddTypes", Method, 3, ""}, - {"(*Data).LineReader", Method, 5, ""}, - {"(*Data).Ranges", Method, 7, ""}, - {"(*Data).Reader", Method, 0, ""}, - {"(*Data).Type", Method, 0, ""}, - {"(*DotDotDotType).Common", Method, 0, ""}, - {"(*DotDotDotType).Size", Method, 0, ""}, - {"(*DotDotDotType).String", Method, 0, ""}, - {"(*Entry).AttrField", Method, 5, ""}, - {"(*Entry).Val", Method, 0, ""}, - {"(*EnumType).Common", Method, 0, ""}, - {"(*EnumType).Size", Method, 0, ""}, - {"(*EnumType).String", Method, 0, ""}, - {"(*FloatType).Basic", Method, 0, ""}, - {"(*FloatType).Common", Method, 0, ""}, - {"(*FloatType).Size", Method, 0, ""}, - {"(*FloatType).String", Method, 0, ""}, - {"(*FuncType).Common", Method, 0, ""}, - {"(*FuncType).Size", Method, 0, ""}, - {"(*FuncType).String", Method, 0, ""}, - {"(*IntType).Basic", Method, 0, ""}, - {"(*IntType).Common", Method, 0, ""}, - {"(*IntType).Size", Method, 0, ""}, - {"(*IntType).String", Method, 0, ""}, - {"(*LineReader).Files", Method, 14, ""}, - {"(*LineReader).Next", Method, 5, ""}, - {"(*LineReader).Reset", Method, 5, ""}, - {"(*LineReader).Seek", Method, 5, ""}, - {"(*LineReader).SeekPC", Method, 5, ""}, - {"(*LineReader).Tell", Method, 5, ""}, - {"(*PtrType).Common", Method, 0, ""}, - {"(*PtrType).Size", Method, 0, ""}, - {"(*PtrType).String", Method, 0, ""}, - {"(*QualType).Common", Method, 0, ""}, - {"(*QualType).Size", Method, 0, ""}, - {"(*QualType).String", Method, 0, ""}, - {"(*Reader).AddressSize", Method, 5, ""}, - {"(*Reader).ByteOrder", Method, 14, ""}, - {"(*Reader).Next", Method, 0, ""}, - {"(*Reader).Seek", Method, 0, ""}, - {"(*Reader).SeekPC", Method, 7, ""}, - {"(*Reader).SkipChildren", Method, 0, ""}, - {"(*StructType).Common", Method, 0, ""}, - {"(*StructType).Defn", Method, 0, ""}, - {"(*StructType).Size", Method, 0, ""}, - {"(*StructType).String", Method, 0, ""}, - {"(*TypedefType).Common", Method, 0, ""}, - {"(*TypedefType).Size", Method, 0, ""}, - {"(*TypedefType).String", Method, 0, ""}, - {"(*UcharType).Basic", Method, 0, ""}, - {"(*UcharType).Common", Method, 0, ""}, - {"(*UcharType).Size", Method, 0, ""}, - {"(*UcharType).String", Method, 0, ""}, - {"(*UintType).Basic", Method, 0, ""}, - {"(*UintType).Common", Method, 0, ""}, - {"(*UintType).Size", Method, 0, ""}, - {"(*UintType).String", Method, 0, ""}, - {"(*UnspecifiedType).Basic", Method, 4, ""}, - {"(*UnspecifiedType).Common", Method, 4, ""}, - {"(*UnspecifiedType).Size", Method, 4, ""}, - {"(*UnspecifiedType).String", Method, 4, ""}, - {"(*UnsupportedType).Common", Method, 13, ""}, - {"(*UnsupportedType).Size", Method, 13, ""}, - {"(*UnsupportedType).String", Method, 13, ""}, - {"(*VoidType).Common", Method, 0, ""}, - {"(*VoidType).Size", Method, 0, ""}, - {"(*VoidType).String", Method, 0, ""}, - {"(Attr).GoString", Method, 0, ""}, - {"(Attr).String", Method, 0, ""}, - {"(Class).GoString", Method, 5, ""}, - {"(Class).String", Method, 5, ""}, - {"(DecodeError).Error", Method, 0, ""}, - {"(Tag).GoString", Method, 0, ""}, - {"(Tag).String", Method, 0, ""}, - {"(Type).Common", Method, 0, ""}, - {"(Type).Size", Method, 0, ""}, - {"(Type).String", Method, 0, ""}, - {"AddrType", Type, 0, ""}, - {"AddrType.BasicType", Field, 0, ""}, - {"ArrayType", Type, 0, ""}, - {"ArrayType.CommonType", Field, 0, ""}, - {"ArrayType.Count", Field, 0, ""}, - {"ArrayType.StrideBitSize", Field, 0, ""}, - {"ArrayType.Type", Field, 0, ""}, - {"Attr", Type, 0, ""}, - {"AttrAbstractOrigin", Const, 0, ""}, - {"AttrAccessibility", Const, 0, ""}, - {"AttrAddrBase", Const, 14, ""}, - {"AttrAddrClass", Const, 0, ""}, - {"AttrAlignment", Const, 14, ""}, - {"AttrAllocated", Const, 0, ""}, - {"AttrArtificial", Const, 0, ""}, - {"AttrAssociated", Const, 0, ""}, - {"AttrBaseTypes", Const, 0, ""}, - {"AttrBinaryScale", Const, 14, ""}, - {"AttrBitOffset", Const, 0, ""}, - {"AttrBitSize", Const, 0, ""}, - {"AttrByteSize", Const, 0, ""}, - {"AttrCallAllCalls", Const, 14, ""}, - {"AttrCallAllSourceCalls", Const, 14, ""}, - {"AttrCallAllTailCalls", Const, 14, ""}, - {"AttrCallColumn", Const, 0, ""}, - {"AttrCallDataLocation", Const, 14, ""}, - {"AttrCallDataValue", Const, 14, ""}, - {"AttrCallFile", Const, 0, ""}, - {"AttrCallLine", Const, 0, ""}, - {"AttrCallOrigin", Const, 14, ""}, - {"AttrCallPC", Const, 14, ""}, - {"AttrCallParameter", Const, 14, ""}, - {"AttrCallReturnPC", Const, 14, ""}, - {"AttrCallTailCall", Const, 14, ""}, - {"AttrCallTarget", Const, 14, ""}, - {"AttrCallTargetClobbered", Const, 14, ""}, - {"AttrCallValue", Const, 14, ""}, - {"AttrCalling", Const, 0, ""}, - {"AttrCommonRef", Const, 0, ""}, - {"AttrCompDir", Const, 0, ""}, - {"AttrConstExpr", Const, 14, ""}, - {"AttrConstValue", Const, 0, ""}, - {"AttrContainingType", Const, 0, ""}, - {"AttrCount", Const, 0, ""}, - {"AttrDataBitOffset", Const, 14, ""}, - {"AttrDataLocation", Const, 0, ""}, - {"AttrDataMemberLoc", Const, 0, ""}, - {"AttrDecimalScale", Const, 14, ""}, - {"AttrDecimalSign", Const, 14, ""}, - {"AttrDeclColumn", Const, 0, ""}, - {"AttrDeclFile", Const, 0, ""}, - {"AttrDeclLine", Const, 0, ""}, - {"AttrDeclaration", Const, 0, ""}, - {"AttrDefaultValue", Const, 0, ""}, - {"AttrDefaulted", Const, 14, ""}, - {"AttrDeleted", Const, 14, ""}, - {"AttrDescription", Const, 0, ""}, - {"AttrDigitCount", Const, 14, ""}, - {"AttrDiscr", Const, 0, ""}, - {"AttrDiscrList", Const, 0, ""}, - {"AttrDiscrValue", Const, 0, ""}, - {"AttrDwoName", Const, 14, ""}, - {"AttrElemental", Const, 14, ""}, - {"AttrEncoding", Const, 0, ""}, - {"AttrEndianity", Const, 14, ""}, - {"AttrEntrypc", Const, 0, ""}, - {"AttrEnumClass", Const, 14, ""}, - {"AttrExplicit", Const, 14, ""}, - {"AttrExportSymbols", Const, 14, ""}, - {"AttrExtension", Const, 0, ""}, - {"AttrExternal", Const, 0, ""}, - {"AttrFrameBase", Const, 0, ""}, - {"AttrFriend", Const, 0, ""}, - {"AttrHighpc", Const, 0, ""}, - {"AttrIdentifierCase", Const, 0, ""}, - {"AttrImport", Const, 0, ""}, - {"AttrInline", Const, 0, ""}, - {"AttrIsOptional", Const, 0, ""}, - {"AttrLanguage", Const, 0, ""}, - {"AttrLinkageName", Const, 14, ""}, - {"AttrLocation", Const, 0, ""}, - {"AttrLoclistsBase", Const, 14, ""}, - {"AttrLowerBound", Const, 0, ""}, - {"AttrLowpc", Const, 0, ""}, - {"AttrMacroInfo", Const, 0, ""}, - {"AttrMacros", Const, 14, ""}, - {"AttrMainSubprogram", Const, 14, ""}, - {"AttrMutable", Const, 14, ""}, - {"AttrName", Const, 0, ""}, - {"AttrNamelistItem", Const, 0, ""}, - {"AttrNoreturn", Const, 14, ""}, - {"AttrObjectPointer", Const, 14, ""}, - {"AttrOrdering", Const, 0, ""}, - {"AttrPictureString", Const, 14, ""}, - {"AttrPriority", Const, 0, ""}, - {"AttrProducer", Const, 0, ""}, - {"AttrPrototyped", Const, 0, ""}, - {"AttrPure", Const, 14, ""}, - {"AttrRanges", Const, 0, ""}, - {"AttrRank", Const, 14, ""}, - {"AttrRecursive", Const, 14, ""}, - {"AttrReference", Const, 14, ""}, - {"AttrReturnAddr", Const, 0, ""}, - {"AttrRnglistsBase", Const, 14, ""}, - {"AttrRvalueReference", Const, 14, ""}, - {"AttrSegment", Const, 0, ""}, - {"AttrSibling", Const, 0, ""}, - {"AttrSignature", Const, 14, ""}, - {"AttrSmall", Const, 14, ""}, - {"AttrSpecification", Const, 0, ""}, - {"AttrStartScope", Const, 0, ""}, - {"AttrStaticLink", Const, 0, ""}, - {"AttrStmtList", Const, 0, ""}, - {"AttrStrOffsetsBase", Const, 14, ""}, - {"AttrStride", Const, 0, ""}, - {"AttrStrideSize", Const, 0, ""}, - {"AttrStringLength", Const, 0, ""}, - {"AttrStringLengthBitSize", Const, 14, ""}, - {"AttrStringLengthByteSize", Const, 14, ""}, - {"AttrThreadsScaled", Const, 14, ""}, - {"AttrTrampoline", Const, 0, ""}, - {"AttrType", Const, 0, ""}, - {"AttrUpperBound", Const, 0, ""}, - {"AttrUseLocation", Const, 0, ""}, - {"AttrUseUTF8", Const, 0, ""}, - {"AttrVarParam", Const, 0, ""}, - {"AttrVirtuality", Const, 0, ""}, - {"AttrVisibility", Const, 0, ""}, - {"AttrVtableElemLoc", Const, 0, ""}, - {"BasicType", Type, 0, ""}, - {"BasicType.BitOffset", Field, 0, ""}, - {"BasicType.BitSize", Field, 0, ""}, - {"BasicType.CommonType", Field, 0, ""}, - {"BasicType.DataBitOffset", Field, 18, ""}, - {"BoolType", Type, 0, ""}, - {"BoolType.BasicType", Field, 0, ""}, - {"CharType", Type, 0, ""}, - {"CharType.BasicType", Field, 0, ""}, - {"Class", Type, 5, ""}, - {"ClassAddrPtr", Const, 14, ""}, - {"ClassAddress", Const, 5, ""}, - {"ClassBlock", Const, 5, ""}, - {"ClassConstant", Const, 5, ""}, - {"ClassExprLoc", Const, 5, ""}, - {"ClassFlag", Const, 5, ""}, - {"ClassLinePtr", Const, 5, ""}, - {"ClassLocList", Const, 14, ""}, - {"ClassLocListPtr", Const, 5, ""}, - {"ClassMacPtr", Const, 5, ""}, - {"ClassRangeListPtr", Const, 5, ""}, - {"ClassReference", Const, 5, ""}, - {"ClassReferenceAlt", Const, 5, ""}, - {"ClassReferenceSig", Const, 5, ""}, - {"ClassRngList", Const, 14, ""}, - {"ClassRngListsPtr", Const, 14, ""}, - {"ClassStrOffsetsPtr", Const, 14, ""}, - {"ClassString", Const, 5, ""}, - {"ClassStringAlt", Const, 5, ""}, - {"ClassUnknown", Const, 6, ""}, - {"CommonType", Type, 0, ""}, - {"CommonType.ByteSize", Field, 0, ""}, - {"CommonType.Name", Field, 0, ""}, - {"ComplexType", Type, 0, ""}, - {"ComplexType.BasicType", Field, 0, ""}, - {"Data", Type, 0, ""}, - {"DecodeError", Type, 0, ""}, - {"DecodeError.Err", Field, 0, ""}, - {"DecodeError.Name", Field, 0, ""}, - {"DecodeError.Offset", Field, 0, ""}, - {"DotDotDotType", Type, 0, ""}, - {"DotDotDotType.CommonType", Field, 0, ""}, - {"Entry", Type, 0, ""}, - {"Entry.Children", Field, 0, ""}, - {"Entry.Field", Field, 0, ""}, - {"Entry.Offset", Field, 0, ""}, - {"Entry.Tag", Field, 0, ""}, - {"EnumType", Type, 0, ""}, - {"EnumType.CommonType", Field, 0, ""}, - {"EnumType.EnumName", Field, 0, ""}, - {"EnumType.Val", Field, 0, ""}, - {"EnumValue", Type, 0, ""}, - {"EnumValue.Name", Field, 0, ""}, - {"EnumValue.Val", Field, 0, ""}, - {"ErrUnknownPC", Var, 5, ""}, - {"Field", Type, 0, ""}, - {"Field.Attr", Field, 0, ""}, - {"Field.Class", Field, 5, ""}, - {"Field.Val", Field, 0, ""}, - {"FloatType", Type, 0, ""}, - {"FloatType.BasicType", Field, 0, ""}, - {"FuncType", Type, 0, ""}, - {"FuncType.CommonType", Field, 0, ""}, - {"FuncType.ParamType", Field, 0, ""}, - {"FuncType.ReturnType", Field, 0, ""}, - {"IntType", Type, 0, ""}, - {"IntType.BasicType", Field, 0, ""}, - {"LineEntry", Type, 5, ""}, - {"LineEntry.Address", Field, 5, ""}, - {"LineEntry.BasicBlock", Field, 5, ""}, - {"LineEntry.Column", Field, 5, ""}, - {"LineEntry.Discriminator", Field, 5, ""}, - {"LineEntry.EndSequence", Field, 5, ""}, - {"LineEntry.EpilogueBegin", Field, 5, ""}, - {"LineEntry.File", Field, 5, ""}, - {"LineEntry.ISA", Field, 5, ""}, - {"LineEntry.IsStmt", Field, 5, ""}, - {"LineEntry.Line", Field, 5, ""}, - {"LineEntry.OpIndex", Field, 5, ""}, - {"LineEntry.PrologueEnd", Field, 5, ""}, - {"LineFile", Type, 5, ""}, - {"LineFile.Length", Field, 5, ""}, - {"LineFile.Mtime", Field, 5, ""}, - {"LineFile.Name", Field, 5, ""}, - {"LineReader", Type, 5, ""}, - {"LineReaderPos", Type, 5, ""}, - {"New", Func, 0, "func(abbrev []byte, aranges []byte, frame []byte, info []byte, line []byte, pubnames []byte, ranges []byte, str []byte) (*Data, error)"}, - {"Offset", Type, 0, ""}, - {"PtrType", Type, 0, ""}, - {"PtrType.CommonType", Field, 0, ""}, - {"PtrType.Type", Field, 0, ""}, - {"QualType", Type, 0, ""}, - {"QualType.CommonType", Field, 0, ""}, - {"QualType.Qual", Field, 0, ""}, - {"QualType.Type", Field, 0, ""}, - {"Reader", Type, 0, ""}, - {"StructField", Type, 0, ""}, - {"StructField.BitOffset", Field, 0, ""}, - {"StructField.BitSize", Field, 0, ""}, - {"StructField.ByteOffset", Field, 0, ""}, - {"StructField.ByteSize", Field, 0, ""}, - {"StructField.DataBitOffset", Field, 18, ""}, - {"StructField.Name", Field, 0, ""}, - {"StructField.Type", Field, 0, ""}, - {"StructType", Type, 0, ""}, - {"StructType.CommonType", Field, 0, ""}, - {"StructType.Field", Field, 0, ""}, - {"StructType.Incomplete", Field, 0, ""}, - {"StructType.Kind", Field, 0, ""}, - {"StructType.StructName", Field, 0, ""}, - {"Tag", Type, 0, ""}, - {"TagAccessDeclaration", Const, 0, ""}, - {"TagArrayType", Const, 0, ""}, - {"TagAtomicType", Const, 14, ""}, - {"TagBaseType", Const, 0, ""}, - {"TagCallSite", Const, 14, ""}, - {"TagCallSiteParameter", Const, 14, ""}, - {"TagCatchDwarfBlock", Const, 0, ""}, - {"TagClassType", Const, 0, ""}, - {"TagCoarrayType", Const, 14, ""}, - {"TagCommonDwarfBlock", Const, 0, ""}, - {"TagCommonInclusion", Const, 0, ""}, - {"TagCompileUnit", Const, 0, ""}, - {"TagCondition", Const, 3, ""}, - {"TagConstType", Const, 0, ""}, - {"TagConstant", Const, 0, ""}, - {"TagDwarfProcedure", Const, 0, ""}, - {"TagDynamicType", Const, 14, ""}, - {"TagEntryPoint", Const, 0, ""}, - {"TagEnumerationType", Const, 0, ""}, - {"TagEnumerator", Const, 0, ""}, - {"TagFileType", Const, 0, ""}, - {"TagFormalParameter", Const, 0, ""}, - {"TagFriend", Const, 0, ""}, - {"TagGenericSubrange", Const, 14, ""}, - {"TagImmutableType", Const, 14, ""}, - {"TagImportedDeclaration", Const, 0, ""}, - {"TagImportedModule", Const, 0, ""}, - {"TagImportedUnit", Const, 0, ""}, - {"TagInheritance", Const, 0, ""}, - {"TagInlinedSubroutine", Const, 0, ""}, - {"TagInterfaceType", Const, 0, ""}, - {"TagLabel", Const, 0, ""}, - {"TagLexDwarfBlock", Const, 0, ""}, - {"TagMember", Const, 0, ""}, - {"TagModule", Const, 0, ""}, - {"TagMutableType", Const, 0, ""}, - {"TagNamelist", Const, 0, ""}, - {"TagNamelistItem", Const, 0, ""}, - {"TagNamespace", Const, 0, ""}, - {"TagPackedType", Const, 0, ""}, - {"TagPartialUnit", Const, 0, ""}, - {"TagPointerType", Const, 0, ""}, - {"TagPtrToMemberType", Const, 0, ""}, - {"TagReferenceType", Const, 0, ""}, - {"TagRestrictType", Const, 0, ""}, - {"TagRvalueReferenceType", Const, 3, ""}, - {"TagSetType", Const, 0, ""}, - {"TagSharedType", Const, 3, ""}, - {"TagSkeletonUnit", Const, 14, ""}, - {"TagStringType", Const, 0, ""}, - {"TagStructType", Const, 0, ""}, - {"TagSubprogram", Const, 0, ""}, - {"TagSubrangeType", Const, 0, ""}, - {"TagSubroutineType", Const, 0, ""}, - {"TagTemplateAlias", Const, 3, ""}, - {"TagTemplateTypeParameter", Const, 0, ""}, - {"TagTemplateValueParameter", Const, 0, ""}, - {"TagThrownType", Const, 0, ""}, - {"TagTryDwarfBlock", Const, 0, ""}, - {"TagTypeUnit", Const, 3, ""}, - {"TagTypedef", Const, 0, ""}, - {"TagUnionType", Const, 0, ""}, - {"TagUnspecifiedParameters", Const, 0, ""}, - {"TagUnspecifiedType", Const, 0, ""}, - {"TagVariable", Const, 0, ""}, - {"TagVariant", Const, 0, ""}, - {"TagVariantPart", Const, 0, ""}, - {"TagVolatileType", Const, 0, ""}, - {"TagWithStmt", Const, 0, ""}, - {"Type", Type, 0, ""}, - {"TypedefType", Type, 0, ""}, - {"TypedefType.CommonType", Field, 0, ""}, - {"TypedefType.Type", Field, 0, ""}, - {"UcharType", Type, 0, ""}, - {"UcharType.BasicType", Field, 0, ""}, - {"UintType", Type, 0, ""}, - {"UintType.BasicType", Field, 0, ""}, - {"UnspecifiedType", Type, 4, ""}, - {"UnspecifiedType.BasicType", Field, 4, ""}, - {"UnsupportedType", Type, 13, ""}, - {"UnsupportedType.CommonType", Field, 13, ""}, - {"UnsupportedType.Tag", Field, 13, ""}, - {"VoidType", Type, 0, ""}, - {"VoidType.CommonType", Field, 0, ""}, - }, - "debug/elf": { - {"(*File).Close", Method, 0, ""}, - {"(*File).DWARF", Method, 0, ""}, - {"(*File).DynString", Method, 1, ""}, - {"(*File).DynValue", Method, 21, ""}, - {"(*File).DynamicSymbols", Method, 4, ""}, - {"(*File).DynamicVersionNeeds", Method, 24, ""}, - {"(*File).DynamicVersions", Method, 24, ""}, - {"(*File).ImportedLibraries", Method, 0, ""}, - {"(*File).ImportedSymbols", Method, 0, ""}, - {"(*File).Section", Method, 0, ""}, - {"(*File).SectionByType", Method, 0, ""}, - {"(*File).Symbols", Method, 0, ""}, - {"(*FormatError).Error", Method, 0, ""}, - {"(*Prog).Open", Method, 0, ""}, - {"(*Section).Data", Method, 0, ""}, - {"(*Section).Open", Method, 0, ""}, - {"(Class).GoString", Method, 0, ""}, - {"(Class).String", Method, 0, ""}, - {"(CompressionType).GoString", Method, 6, ""}, - {"(CompressionType).String", Method, 6, ""}, - {"(Data).GoString", Method, 0, ""}, - {"(Data).String", Method, 0, ""}, - {"(DynFlag).GoString", Method, 0, ""}, - {"(DynFlag).String", Method, 0, ""}, - {"(DynFlag1).GoString", Method, 21, ""}, - {"(DynFlag1).String", Method, 21, ""}, - {"(DynTag).GoString", Method, 0, ""}, - {"(DynTag).String", Method, 0, ""}, - {"(Machine).GoString", Method, 0, ""}, - {"(Machine).String", Method, 0, ""}, - {"(NType).GoString", Method, 0, ""}, - {"(NType).String", Method, 0, ""}, - {"(OSABI).GoString", Method, 0, ""}, - {"(OSABI).String", Method, 0, ""}, - {"(Prog).ReadAt", Method, 0, ""}, - {"(ProgFlag).GoString", Method, 0, ""}, - {"(ProgFlag).String", Method, 0, ""}, - {"(ProgType).GoString", Method, 0, ""}, - {"(ProgType).String", Method, 0, ""}, - {"(R_386).GoString", Method, 0, ""}, - {"(R_386).String", Method, 0, ""}, - {"(R_390).GoString", Method, 7, ""}, - {"(R_390).String", Method, 7, ""}, - {"(R_AARCH64).GoString", Method, 4, ""}, - {"(R_AARCH64).String", Method, 4, ""}, - {"(R_ALPHA).GoString", Method, 0, ""}, - {"(R_ALPHA).String", Method, 0, ""}, - {"(R_ARM).GoString", Method, 0, ""}, - {"(R_ARM).String", Method, 0, ""}, - {"(R_LARCH).GoString", Method, 19, ""}, - {"(R_LARCH).String", Method, 19, ""}, - {"(R_MIPS).GoString", Method, 6, ""}, - {"(R_MIPS).String", Method, 6, ""}, - {"(R_PPC).GoString", Method, 0, ""}, - {"(R_PPC).String", Method, 0, ""}, - {"(R_PPC64).GoString", Method, 5, ""}, - {"(R_PPC64).String", Method, 5, ""}, - {"(R_RISCV).GoString", Method, 11, ""}, - {"(R_RISCV).String", Method, 11, ""}, - {"(R_SPARC).GoString", Method, 0, ""}, - {"(R_SPARC).String", Method, 0, ""}, - {"(R_X86_64).GoString", Method, 0, ""}, - {"(R_X86_64).String", Method, 0, ""}, - {"(Section).ReadAt", Method, 0, ""}, - {"(SectionFlag).GoString", Method, 0, ""}, - {"(SectionFlag).String", Method, 0, ""}, - {"(SectionIndex).GoString", Method, 0, ""}, - {"(SectionIndex).String", Method, 0, ""}, - {"(SectionType).GoString", Method, 0, ""}, - {"(SectionType).String", Method, 0, ""}, - {"(SymBind).GoString", Method, 0, ""}, - {"(SymBind).String", Method, 0, ""}, - {"(SymType).GoString", Method, 0, ""}, - {"(SymType).String", Method, 0, ""}, - {"(SymVis).GoString", Method, 0, ""}, - {"(SymVis).String", Method, 0, ""}, - {"(Type).GoString", Method, 0, ""}, - {"(Type).String", Method, 0, ""}, - {"(Version).GoString", Method, 0, ""}, - {"(Version).String", Method, 0, ""}, - {"(VersionIndex).Index", Method, 24, ""}, - {"(VersionIndex).IsHidden", Method, 24, ""}, - {"ARM_MAGIC_TRAMP_NUMBER", Const, 0, ""}, - {"COMPRESS_HIOS", Const, 6, ""}, - {"COMPRESS_HIPROC", Const, 6, ""}, - {"COMPRESS_LOOS", Const, 6, ""}, - {"COMPRESS_LOPROC", Const, 6, ""}, - {"COMPRESS_ZLIB", Const, 6, ""}, - {"COMPRESS_ZSTD", Const, 21, ""}, - {"Chdr32", Type, 6, ""}, - {"Chdr32.Addralign", Field, 6, ""}, - {"Chdr32.Size", Field, 6, ""}, - {"Chdr32.Type", Field, 6, ""}, - {"Chdr64", Type, 6, ""}, - {"Chdr64.Addralign", Field, 6, ""}, - {"Chdr64.Size", Field, 6, ""}, - {"Chdr64.Type", Field, 6, ""}, - {"Class", Type, 0, ""}, - {"CompressionType", Type, 6, ""}, - {"DF_1_CONFALT", Const, 21, ""}, - {"DF_1_DIRECT", Const, 21, ""}, - {"DF_1_DISPRELDNE", Const, 21, ""}, - {"DF_1_DISPRELPND", Const, 21, ""}, - {"DF_1_EDITED", Const, 21, ""}, - {"DF_1_ENDFILTEE", Const, 21, ""}, - {"DF_1_GLOBAL", Const, 21, ""}, - {"DF_1_GLOBAUDIT", Const, 21, ""}, - {"DF_1_GROUP", Const, 21, ""}, - {"DF_1_IGNMULDEF", Const, 21, ""}, - {"DF_1_INITFIRST", Const, 21, ""}, - {"DF_1_INTERPOSE", Const, 21, ""}, - {"DF_1_KMOD", Const, 21, ""}, - {"DF_1_LOADFLTR", Const, 21, ""}, - {"DF_1_NOCOMMON", Const, 21, ""}, - {"DF_1_NODEFLIB", Const, 21, ""}, - {"DF_1_NODELETE", Const, 21, ""}, - {"DF_1_NODIRECT", Const, 21, ""}, - {"DF_1_NODUMP", Const, 21, ""}, - {"DF_1_NOHDR", Const, 21, ""}, - {"DF_1_NOKSYMS", Const, 21, ""}, - {"DF_1_NOOPEN", Const, 21, ""}, - {"DF_1_NORELOC", Const, 21, ""}, - {"DF_1_NOW", Const, 21, ""}, - {"DF_1_ORIGIN", Const, 21, ""}, - {"DF_1_PIE", Const, 21, ""}, - {"DF_1_SINGLETON", Const, 21, ""}, - {"DF_1_STUB", Const, 21, ""}, - {"DF_1_SYMINTPOSE", Const, 21, ""}, - {"DF_1_TRANS", Const, 21, ""}, - {"DF_1_WEAKFILTER", Const, 21, ""}, - {"DF_BIND_NOW", Const, 0, ""}, - {"DF_ORIGIN", Const, 0, ""}, - {"DF_STATIC_TLS", Const, 0, ""}, - {"DF_SYMBOLIC", Const, 0, ""}, - {"DF_TEXTREL", Const, 0, ""}, - {"DT_ADDRRNGHI", Const, 16, ""}, - {"DT_ADDRRNGLO", Const, 16, ""}, - {"DT_AUDIT", Const, 16, ""}, - {"DT_AUXILIARY", Const, 16, ""}, - {"DT_BIND_NOW", Const, 0, ""}, - {"DT_CHECKSUM", Const, 16, ""}, - {"DT_CONFIG", Const, 16, ""}, - {"DT_DEBUG", Const, 0, ""}, - {"DT_DEPAUDIT", Const, 16, ""}, - {"DT_ENCODING", Const, 0, ""}, - {"DT_FEATURE", Const, 16, ""}, - {"DT_FILTER", Const, 16, ""}, - {"DT_FINI", Const, 0, ""}, - {"DT_FINI_ARRAY", Const, 0, ""}, - {"DT_FINI_ARRAYSZ", Const, 0, ""}, - {"DT_FLAGS", Const, 0, ""}, - {"DT_FLAGS_1", Const, 16, ""}, - {"DT_GNU_CONFLICT", Const, 16, ""}, - {"DT_GNU_CONFLICTSZ", Const, 16, ""}, - {"DT_GNU_HASH", Const, 16, ""}, - {"DT_GNU_LIBLIST", Const, 16, ""}, - {"DT_GNU_LIBLISTSZ", Const, 16, ""}, - {"DT_GNU_PRELINKED", Const, 16, ""}, - {"DT_HASH", Const, 0, ""}, - {"DT_HIOS", Const, 0, ""}, - {"DT_HIPROC", Const, 0, ""}, - {"DT_INIT", Const, 0, ""}, - {"DT_INIT_ARRAY", Const, 0, ""}, - {"DT_INIT_ARRAYSZ", Const, 0, ""}, - {"DT_JMPREL", Const, 0, ""}, - {"DT_LOOS", Const, 0, ""}, - {"DT_LOPROC", Const, 0, ""}, - {"DT_MIPS_AUX_DYNAMIC", Const, 16, ""}, - {"DT_MIPS_BASE_ADDRESS", Const, 16, ""}, - {"DT_MIPS_COMPACT_SIZE", Const, 16, ""}, - {"DT_MIPS_CONFLICT", Const, 16, ""}, - {"DT_MIPS_CONFLICTNO", Const, 16, ""}, - {"DT_MIPS_CXX_FLAGS", Const, 16, ""}, - {"DT_MIPS_DELTA_CLASS", Const, 16, ""}, - {"DT_MIPS_DELTA_CLASSSYM", Const, 16, ""}, - {"DT_MIPS_DELTA_CLASSSYM_NO", Const, 16, ""}, - {"DT_MIPS_DELTA_CLASS_NO", Const, 16, ""}, - {"DT_MIPS_DELTA_INSTANCE", Const, 16, ""}, - {"DT_MIPS_DELTA_INSTANCE_NO", Const, 16, ""}, - {"DT_MIPS_DELTA_RELOC", Const, 16, ""}, - {"DT_MIPS_DELTA_RELOC_NO", Const, 16, ""}, - {"DT_MIPS_DELTA_SYM", Const, 16, ""}, - {"DT_MIPS_DELTA_SYM_NO", Const, 16, ""}, - {"DT_MIPS_DYNSTR_ALIGN", Const, 16, ""}, - {"DT_MIPS_FLAGS", Const, 16, ""}, - {"DT_MIPS_GOTSYM", Const, 16, ""}, - {"DT_MIPS_GP_VALUE", Const, 16, ""}, - {"DT_MIPS_HIDDEN_GOTIDX", Const, 16, ""}, - {"DT_MIPS_HIPAGENO", Const, 16, ""}, - {"DT_MIPS_ICHECKSUM", Const, 16, ""}, - {"DT_MIPS_INTERFACE", Const, 16, ""}, - {"DT_MIPS_INTERFACE_SIZE", Const, 16, ""}, - {"DT_MIPS_IVERSION", Const, 16, ""}, - {"DT_MIPS_LIBLIST", Const, 16, ""}, - {"DT_MIPS_LIBLISTNO", Const, 16, ""}, - {"DT_MIPS_LOCALPAGE_GOTIDX", Const, 16, ""}, - {"DT_MIPS_LOCAL_GOTIDX", Const, 16, ""}, - {"DT_MIPS_LOCAL_GOTNO", Const, 16, ""}, - {"DT_MIPS_MSYM", Const, 16, ""}, - {"DT_MIPS_OPTIONS", Const, 16, ""}, - {"DT_MIPS_PERF_SUFFIX", Const, 16, ""}, - {"DT_MIPS_PIXIE_INIT", Const, 16, ""}, - {"DT_MIPS_PLTGOT", Const, 16, ""}, - {"DT_MIPS_PROTECTED_GOTIDX", Const, 16, ""}, - {"DT_MIPS_RLD_MAP", Const, 16, ""}, - {"DT_MIPS_RLD_MAP_REL", Const, 16, ""}, - {"DT_MIPS_RLD_TEXT_RESOLVE_ADDR", Const, 16, ""}, - {"DT_MIPS_RLD_VERSION", Const, 16, ""}, - {"DT_MIPS_RWPLT", Const, 16, ""}, - {"DT_MIPS_SYMBOL_LIB", Const, 16, ""}, - {"DT_MIPS_SYMTABNO", Const, 16, ""}, - {"DT_MIPS_TIME_STAMP", Const, 16, ""}, - {"DT_MIPS_UNREFEXTNO", Const, 16, ""}, - {"DT_MOVEENT", Const, 16, ""}, - {"DT_MOVESZ", Const, 16, ""}, - {"DT_MOVETAB", Const, 16, ""}, - {"DT_NEEDED", Const, 0, ""}, - {"DT_NULL", Const, 0, ""}, - {"DT_PLTGOT", Const, 0, ""}, - {"DT_PLTPAD", Const, 16, ""}, - {"DT_PLTPADSZ", Const, 16, ""}, - {"DT_PLTREL", Const, 0, ""}, - {"DT_PLTRELSZ", Const, 0, ""}, - {"DT_POSFLAG_1", Const, 16, ""}, - {"DT_PPC64_GLINK", Const, 16, ""}, - {"DT_PPC64_OPD", Const, 16, ""}, - {"DT_PPC64_OPDSZ", Const, 16, ""}, - {"DT_PPC64_OPT", Const, 16, ""}, - {"DT_PPC_GOT", Const, 16, ""}, - {"DT_PPC_OPT", Const, 16, ""}, - {"DT_PREINIT_ARRAY", Const, 0, ""}, - {"DT_PREINIT_ARRAYSZ", Const, 0, ""}, - {"DT_REL", Const, 0, ""}, - {"DT_RELA", Const, 0, ""}, - {"DT_RELACOUNT", Const, 16, ""}, - {"DT_RELAENT", Const, 0, ""}, - {"DT_RELASZ", Const, 0, ""}, - {"DT_RELCOUNT", Const, 16, ""}, - {"DT_RELENT", Const, 0, ""}, - {"DT_RELSZ", Const, 0, ""}, - {"DT_RPATH", Const, 0, ""}, - {"DT_RUNPATH", Const, 0, ""}, - {"DT_SONAME", Const, 0, ""}, - {"DT_SPARC_REGISTER", Const, 16, ""}, - {"DT_STRSZ", Const, 0, ""}, - {"DT_STRTAB", Const, 0, ""}, - {"DT_SYMBOLIC", Const, 0, ""}, - {"DT_SYMENT", Const, 0, ""}, - {"DT_SYMINENT", Const, 16, ""}, - {"DT_SYMINFO", Const, 16, ""}, - {"DT_SYMINSZ", Const, 16, ""}, - {"DT_SYMTAB", Const, 0, ""}, - {"DT_SYMTAB_SHNDX", Const, 16, ""}, - {"DT_TEXTREL", Const, 0, ""}, - {"DT_TLSDESC_GOT", Const, 16, ""}, - {"DT_TLSDESC_PLT", Const, 16, ""}, - {"DT_USED", Const, 16, ""}, - {"DT_VALRNGHI", Const, 16, ""}, - {"DT_VALRNGLO", Const, 16, ""}, - {"DT_VERDEF", Const, 16, ""}, - {"DT_VERDEFNUM", Const, 16, ""}, - {"DT_VERNEED", Const, 0, ""}, - {"DT_VERNEEDNUM", Const, 0, ""}, - {"DT_VERSYM", Const, 0, ""}, - {"Data", Type, 0, ""}, - {"Dyn32", Type, 0, ""}, - {"Dyn32.Tag", Field, 0, ""}, - {"Dyn32.Val", Field, 0, ""}, - {"Dyn64", Type, 0, ""}, - {"Dyn64.Tag", Field, 0, ""}, - {"Dyn64.Val", Field, 0, ""}, - {"DynFlag", Type, 0, ""}, - {"DynFlag1", Type, 21, ""}, - {"DynTag", Type, 0, ""}, - {"DynamicVersion", Type, 24, ""}, - {"DynamicVersion.Deps", Field, 24, ""}, - {"DynamicVersion.Flags", Field, 24, ""}, - {"DynamicVersion.Index", Field, 24, ""}, - {"DynamicVersion.Name", Field, 24, ""}, - {"DynamicVersionDep", Type, 24, ""}, - {"DynamicVersionDep.Dep", Field, 24, ""}, - {"DynamicVersionDep.Flags", Field, 24, ""}, - {"DynamicVersionDep.Index", Field, 24, ""}, - {"DynamicVersionFlag", Type, 24, ""}, - {"DynamicVersionNeed", Type, 24, ""}, - {"DynamicVersionNeed.Name", Field, 24, ""}, - {"DynamicVersionNeed.Needs", Field, 24, ""}, - {"EI_ABIVERSION", Const, 0, ""}, - {"EI_CLASS", Const, 0, ""}, - {"EI_DATA", Const, 0, ""}, - {"EI_NIDENT", Const, 0, ""}, - {"EI_OSABI", Const, 0, ""}, - {"EI_PAD", Const, 0, ""}, - {"EI_VERSION", Const, 0, ""}, - {"ELFCLASS32", Const, 0, ""}, - {"ELFCLASS64", Const, 0, ""}, - {"ELFCLASSNONE", Const, 0, ""}, - {"ELFDATA2LSB", Const, 0, ""}, - {"ELFDATA2MSB", Const, 0, ""}, - {"ELFDATANONE", Const, 0, ""}, - {"ELFMAG", Const, 0, ""}, - {"ELFOSABI_86OPEN", Const, 0, ""}, - {"ELFOSABI_AIX", Const, 0, ""}, - {"ELFOSABI_ARM", Const, 0, ""}, - {"ELFOSABI_AROS", Const, 11, ""}, - {"ELFOSABI_CLOUDABI", Const, 11, ""}, - {"ELFOSABI_FENIXOS", Const, 11, ""}, - {"ELFOSABI_FREEBSD", Const, 0, ""}, - {"ELFOSABI_HPUX", Const, 0, ""}, - {"ELFOSABI_HURD", Const, 0, ""}, - {"ELFOSABI_IRIX", Const, 0, ""}, - {"ELFOSABI_LINUX", Const, 0, ""}, - {"ELFOSABI_MODESTO", Const, 0, ""}, - {"ELFOSABI_NETBSD", Const, 0, ""}, - {"ELFOSABI_NONE", Const, 0, ""}, - {"ELFOSABI_NSK", Const, 0, ""}, - {"ELFOSABI_OPENBSD", Const, 0, ""}, - {"ELFOSABI_OPENVMS", Const, 0, ""}, - {"ELFOSABI_SOLARIS", Const, 0, ""}, - {"ELFOSABI_STANDALONE", Const, 0, ""}, - {"ELFOSABI_TRU64", Const, 0, ""}, - {"EM_386", Const, 0, ""}, - {"EM_486", Const, 0, ""}, - {"EM_56800EX", Const, 11, ""}, - {"EM_68HC05", Const, 11, ""}, - {"EM_68HC08", Const, 11, ""}, - {"EM_68HC11", Const, 11, ""}, - {"EM_68HC12", Const, 0, ""}, - {"EM_68HC16", Const, 11, ""}, - {"EM_68K", Const, 0, ""}, - {"EM_78KOR", Const, 11, ""}, - {"EM_8051", Const, 11, ""}, - {"EM_860", Const, 0, ""}, - {"EM_88K", Const, 0, ""}, - {"EM_960", Const, 0, ""}, - {"EM_AARCH64", Const, 4, ""}, - {"EM_ALPHA", Const, 0, ""}, - {"EM_ALPHA_STD", Const, 0, ""}, - {"EM_ALTERA_NIOS2", Const, 11, ""}, - {"EM_AMDGPU", Const, 11, ""}, - {"EM_ARC", Const, 0, ""}, - {"EM_ARCA", Const, 11, ""}, - {"EM_ARC_COMPACT", Const, 11, ""}, - {"EM_ARC_COMPACT2", Const, 11, ""}, - {"EM_ARM", Const, 0, ""}, - {"EM_AVR", Const, 11, ""}, - {"EM_AVR32", Const, 11, ""}, - {"EM_BA1", Const, 11, ""}, - {"EM_BA2", Const, 11, ""}, - {"EM_BLACKFIN", Const, 11, ""}, - {"EM_BPF", Const, 11, ""}, - {"EM_C166", Const, 11, ""}, - {"EM_CDP", Const, 11, ""}, - {"EM_CE", Const, 11, ""}, - {"EM_CLOUDSHIELD", Const, 11, ""}, - {"EM_COGE", Const, 11, ""}, - {"EM_COLDFIRE", Const, 0, ""}, - {"EM_COOL", Const, 11, ""}, - {"EM_COREA_1ST", Const, 11, ""}, - {"EM_COREA_2ND", Const, 11, ""}, - {"EM_CR", Const, 11, ""}, - {"EM_CR16", Const, 11, ""}, - {"EM_CRAYNV2", Const, 11, ""}, - {"EM_CRIS", Const, 11, ""}, - {"EM_CRX", Const, 11, ""}, - {"EM_CSR_KALIMBA", Const, 11, ""}, - {"EM_CUDA", Const, 11, ""}, - {"EM_CYPRESS_M8C", Const, 11, ""}, - {"EM_D10V", Const, 11, ""}, - {"EM_D30V", Const, 11, ""}, - {"EM_DSP24", Const, 11, ""}, - {"EM_DSPIC30F", Const, 11, ""}, - {"EM_DXP", Const, 11, ""}, - {"EM_ECOG1", Const, 11, ""}, - {"EM_ECOG16", Const, 11, ""}, - {"EM_ECOG1X", Const, 11, ""}, - {"EM_ECOG2", Const, 11, ""}, - {"EM_ETPU", Const, 11, ""}, - {"EM_EXCESS", Const, 11, ""}, - {"EM_F2MC16", Const, 11, ""}, - {"EM_FIREPATH", Const, 11, ""}, - {"EM_FR20", Const, 0, ""}, - {"EM_FR30", Const, 11, ""}, - {"EM_FT32", Const, 11, ""}, - {"EM_FX66", Const, 11, ""}, - {"EM_H8S", Const, 0, ""}, - {"EM_H8_300", Const, 0, ""}, - {"EM_H8_300H", Const, 0, ""}, - {"EM_H8_500", Const, 0, ""}, - {"EM_HUANY", Const, 11, ""}, - {"EM_IA_64", Const, 0, ""}, - {"EM_INTEL205", Const, 11, ""}, - {"EM_INTEL206", Const, 11, ""}, - {"EM_INTEL207", Const, 11, ""}, - {"EM_INTEL208", Const, 11, ""}, - {"EM_INTEL209", Const, 11, ""}, - {"EM_IP2K", Const, 11, ""}, - {"EM_JAVELIN", Const, 11, ""}, - {"EM_K10M", Const, 11, ""}, - {"EM_KM32", Const, 11, ""}, - {"EM_KMX16", Const, 11, ""}, - {"EM_KMX32", Const, 11, ""}, - {"EM_KMX8", Const, 11, ""}, - {"EM_KVARC", Const, 11, ""}, - {"EM_L10M", Const, 11, ""}, - {"EM_LANAI", Const, 11, ""}, - {"EM_LATTICEMICO32", Const, 11, ""}, - {"EM_LOONGARCH", Const, 19, ""}, - {"EM_M16C", Const, 11, ""}, - {"EM_M32", Const, 0, ""}, - {"EM_M32C", Const, 11, ""}, - {"EM_M32R", Const, 11, ""}, - {"EM_MANIK", Const, 11, ""}, - {"EM_MAX", Const, 11, ""}, - {"EM_MAXQ30", Const, 11, ""}, - {"EM_MCHP_PIC", Const, 11, ""}, - {"EM_MCST_ELBRUS", Const, 11, ""}, - {"EM_ME16", Const, 0, ""}, - {"EM_METAG", Const, 11, ""}, - {"EM_MICROBLAZE", Const, 11, ""}, - {"EM_MIPS", Const, 0, ""}, - {"EM_MIPS_RS3_LE", Const, 0, ""}, - {"EM_MIPS_RS4_BE", Const, 0, ""}, - {"EM_MIPS_X", Const, 0, ""}, - {"EM_MMA", Const, 0, ""}, - {"EM_MMDSP_PLUS", Const, 11, ""}, - {"EM_MMIX", Const, 11, ""}, - {"EM_MN10200", Const, 11, ""}, - {"EM_MN10300", Const, 11, ""}, - {"EM_MOXIE", Const, 11, ""}, - {"EM_MSP430", Const, 11, ""}, - {"EM_NCPU", Const, 0, ""}, - {"EM_NDR1", Const, 0, ""}, - {"EM_NDS32", Const, 11, ""}, - {"EM_NONE", Const, 0, ""}, - {"EM_NORC", Const, 11, ""}, - {"EM_NS32K", Const, 11, ""}, - {"EM_OPEN8", Const, 11, ""}, - {"EM_OPENRISC", Const, 11, ""}, - {"EM_PARISC", Const, 0, ""}, - {"EM_PCP", Const, 0, ""}, - {"EM_PDP10", Const, 11, ""}, - {"EM_PDP11", Const, 11, ""}, - {"EM_PDSP", Const, 11, ""}, - {"EM_PJ", Const, 11, ""}, - {"EM_PPC", Const, 0, ""}, - {"EM_PPC64", Const, 0, ""}, - {"EM_PRISM", Const, 11, ""}, - {"EM_QDSP6", Const, 11, ""}, - {"EM_R32C", Const, 11, ""}, - {"EM_RCE", Const, 0, ""}, - {"EM_RH32", Const, 0, ""}, - {"EM_RISCV", Const, 11, ""}, - {"EM_RL78", Const, 11, ""}, - {"EM_RS08", Const, 11, ""}, - {"EM_RX", Const, 11, ""}, - {"EM_S370", Const, 0, ""}, - {"EM_S390", Const, 0, ""}, - {"EM_SCORE7", Const, 11, ""}, - {"EM_SEP", Const, 11, ""}, - {"EM_SE_C17", Const, 11, ""}, - {"EM_SE_C33", Const, 11, ""}, - {"EM_SH", Const, 0, ""}, - {"EM_SHARC", Const, 11, ""}, - {"EM_SLE9X", Const, 11, ""}, - {"EM_SNP1K", Const, 11, ""}, - {"EM_SPARC", Const, 0, ""}, - {"EM_SPARC32PLUS", Const, 0, ""}, - {"EM_SPARCV9", Const, 0, ""}, - {"EM_ST100", Const, 0, ""}, - {"EM_ST19", Const, 11, ""}, - {"EM_ST200", Const, 11, ""}, - {"EM_ST7", Const, 11, ""}, - {"EM_ST9PLUS", Const, 11, ""}, - {"EM_STARCORE", Const, 0, ""}, - {"EM_STM8", Const, 11, ""}, - {"EM_STXP7X", Const, 11, ""}, - {"EM_SVX", Const, 11, ""}, - {"EM_TILE64", Const, 11, ""}, - {"EM_TILEGX", Const, 11, ""}, - {"EM_TILEPRO", Const, 11, ""}, - {"EM_TINYJ", Const, 0, ""}, - {"EM_TI_ARP32", Const, 11, ""}, - {"EM_TI_C2000", Const, 11, ""}, - {"EM_TI_C5500", Const, 11, ""}, - {"EM_TI_C6000", Const, 11, ""}, - {"EM_TI_PRU", Const, 11, ""}, - {"EM_TMM_GPP", Const, 11, ""}, - {"EM_TPC", Const, 11, ""}, - {"EM_TRICORE", Const, 0, ""}, - {"EM_TRIMEDIA", Const, 11, ""}, - {"EM_TSK3000", Const, 11, ""}, - {"EM_UNICORE", Const, 11, ""}, - {"EM_V800", Const, 0, ""}, - {"EM_V850", Const, 11, ""}, - {"EM_VAX", Const, 11, ""}, - {"EM_VIDEOCORE", Const, 11, ""}, - {"EM_VIDEOCORE3", Const, 11, ""}, - {"EM_VIDEOCORE5", Const, 11, ""}, - {"EM_VISIUM", Const, 11, ""}, - {"EM_VPP500", Const, 0, ""}, - {"EM_X86_64", Const, 0, ""}, - {"EM_XCORE", Const, 11, ""}, - {"EM_XGATE", Const, 11, ""}, - {"EM_XIMO16", Const, 11, ""}, - {"EM_XTENSA", Const, 11, ""}, - {"EM_Z80", Const, 11, ""}, - {"EM_ZSP", Const, 11, ""}, - {"ET_CORE", Const, 0, ""}, - {"ET_DYN", Const, 0, ""}, - {"ET_EXEC", Const, 0, ""}, - {"ET_HIOS", Const, 0, ""}, - {"ET_HIPROC", Const, 0, ""}, - {"ET_LOOS", Const, 0, ""}, - {"ET_LOPROC", Const, 0, ""}, - {"ET_NONE", Const, 0, ""}, - {"ET_REL", Const, 0, ""}, - {"EV_CURRENT", Const, 0, ""}, - {"EV_NONE", Const, 0, ""}, - {"ErrNoSymbols", Var, 4, ""}, - {"File", Type, 0, ""}, - {"File.FileHeader", Field, 0, ""}, - {"File.Progs", Field, 0, ""}, - {"File.Sections", Field, 0, ""}, - {"FileHeader", Type, 0, ""}, - {"FileHeader.ABIVersion", Field, 0, ""}, - {"FileHeader.ByteOrder", Field, 0, ""}, - {"FileHeader.Class", Field, 0, ""}, - {"FileHeader.Data", Field, 0, ""}, - {"FileHeader.Entry", Field, 1, ""}, - {"FileHeader.Machine", Field, 0, ""}, - {"FileHeader.OSABI", Field, 0, ""}, - {"FileHeader.Type", Field, 0, ""}, - {"FileHeader.Version", Field, 0, ""}, - {"FormatError", Type, 0, ""}, - {"Header32", Type, 0, ""}, - {"Header32.Ehsize", Field, 0, ""}, - {"Header32.Entry", Field, 0, ""}, - {"Header32.Flags", Field, 0, ""}, - {"Header32.Ident", Field, 0, ""}, - {"Header32.Machine", Field, 0, ""}, - {"Header32.Phentsize", Field, 0, ""}, - {"Header32.Phnum", Field, 0, ""}, - {"Header32.Phoff", Field, 0, ""}, - {"Header32.Shentsize", Field, 0, ""}, - {"Header32.Shnum", Field, 0, ""}, - {"Header32.Shoff", Field, 0, ""}, - {"Header32.Shstrndx", Field, 0, ""}, - {"Header32.Type", Field, 0, ""}, - {"Header32.Version", Field, 0, ""}, - {"Header64", Type, 0, ""}, - {"Header64.Ehsize", Field, 0, ""}, - {"Header64.Entry", Field, 0, ""}, - {"Header64.Flags", Field, 0, ""}, - {"Header64.Ident", Field, 0, ""}, - {"Header64.Machine", Field, 0, ""}, - {"Header64.Phentsize", Field, 0, ""}, - {"Header64.Phnum", Field, 0, ""}, - {"Header64.Phoff", Field, 0, ""}, - {"Header64.Shentsize", Field, 0, ""}, - {"Header64.Shnum", Field, 0, ""}, - {"Header64.Shoff", Field, 0, ""}, - {"Header64.Shstrndx", Field, 0, ""}, - {"Header64.Type", Field, 0, ""}, - {"Header64.Version", Field, 0, ""}, - {"ImportedSymbol", Type, 0, ""}, - {"ImportedSymbol.Library", Field, 0, ""}, - {"ImportedSymbol.Name", Field, 0, ""}, - {"ImportedSymbol.Version", Field, 0, ""}, - {"Machine", Type, 0, ""}, - {"NT_FPREGSET", Const, 0, ""}, - {"NT_PRPSINFO", Const, 0, ""}, - {"NT_PRSTATUS", Const, 0, ""}, - {"NType", Type, 0, ""}, - {"NewFile", Func, 0, "func(r io.ReaderAt) (*File, error)"}, - {"OSABI", Type, 0, ""}, - {"Open", Func, 0, "func(name string) (*File, error)"}, - {"PF_MASKOS", Const, 0, ""}, - {"PF_MASKPROC", Const, 0, ""}, - {"PF_R", Const, 0, ""}, - {"PF_W", Const, 0, ""}, - {"PF_X", Const, 0, ""}, - {"PT_AARCH64_ARCHEXT", Const, 16, ""}, - {"PT_AARCH64_UNWIND", Const, 16, ""}, - {"PT_ARM_ARCHEXT", Const, 16, ""}, - {"PT_ARM_EXIDX", Const, 16, ""}, - {"PT_DYNAMIC", Const, 0, ""}, - {"PT_GNU_EH_FRAME", Const, 16, ""}, - {"PT_GNU_MBIND_HI", Const, 16, ""}, - {"PT_GNU_MBIND_LO", Const, 16, ""}, - {"PT_GNU_PROPERTY", Const, 16, ""}, - {"PT_GNU_RELRO", Const, 16, ""}, - {"PT_GNU_STACK", Const, 16, ""}, - {"PT_HIOS", Const, 0, ""}, - {"PT_HIPROC", Const, 0, ""}, - {"PT_INTERP", Const, 0, ""}, - {"PT_LOAD", Const, 0, ""}, - {"PT_LOOS", Const, 0, ""}, - {"PT_LOPROC", Const, 0, ""}, - {"PT_MIPS_ABIFLAGS", Const, 16, ""}, - {"PT_MIPS_OPTIONS", Const, 16, ""}, - {"PT_MIPS_REGINFO", Const, 16, ""}, - {"PT_MIPS_RTPROC", Const, 16, ""}, - {"PT_NOTE", Const, 0, ""}, - {"PT_NULL", Const, 0, ""}, - {"PT_OPENBSD_BOOTDATA", Const, 16, ""}, - {"PT_OPENBSD_NOBTCFI", Const, 23, ""}, - {"PT_OPENBSD_RANDOMIZE", Const, 16, ""}, - {"PT_OPENBSD_WXNEEDED", Const, 16, ""}, - {"PT_PAX_FLAGS", Const, 16, ""}, - {"PT_PHDR", Const, 0, ""}, - {"PT_RISCV_ATTRIBUTES", Const, 25, ""}, - {"PT_S390_PGSTE", Const, 16, ""}, - {"PT_SHLIB", Const, 0, ""}, - {"PT_SUNWSTACK", Const, 16, ""}, - {"PT_SUNW_EH_FRAME", Const, 16, ""}, - {"PT_TLS", Const, 0, ""}, - {"Prog", Type, 0, ""}, - {"Prog.ProgHeader", Field, 0, ""}, - {"Prog.ReaderAt", Field, 0, ""}, - {"Prog32", Type, 0, ""}, - {"Prog32.Align", Field, 0, ""}, - {"Prog32.Filesz", Field, 0, ""}, - {"Prog32.Flags", Field, 0, ""}, - {"Prog32.Memsz", Field, 0, ""}, - {"Prog32.Off", Field, 0, ""}, - {"Prog32.Paddr", Field, 0, ""}, - {"Prog32.Type", Field, 0, ""}, - {"Prog32.Vaddr", Field, 0, ""}, - {"Prog64", Type, 0, ""}, - {"Prog64.Align", Field, 0, ""}, - {"Prog64.Filesz", Field, 0, ""}, - {"Prog64.Flags", Field, 0, ""}, - {"Prog64.Memsz", Field, 0, ""}, - {"Prog64.Off", Field, 0, ""}, - {"Prog64.Paddr", Field, 0, ""}, - {"Prog64.Type", Field, 0, ""}, - {"Prog64.Vaddr", Field, 0, ""}, - {"ProgFlag", Type, 0, ""}, - {"ProgHeader", Type, 0, ""}, - {"ProgHeader.Align", Field, 0, ""}, - {"ProgHeader.Filesz", Field, 0, ""}, - {"ProgHeader.Flags", Field, 0, ""}, - {"ProgHeader.Memsz", Field, 0, ""}, - {"ProgHeader.Off", Field, 0, ""}, - {"ProgHeader.Paddr", Field, 0, ""}, - {"ProgHeader.Type", Field, 0, ""}, - {"ProgHeader.Vaddr", Field, 0, ""}, - {"ProgType", Type, 0, ""}, - {"R_386", Type, 0, ""}, - {"R_386_16", Const, 10, ""}, - {"R_386_32", Const, 0, ""}, - {"R_386_32PLT", Const, 10, ""}, - {"R_386_8", Const, 10, ""}, - {"R_386_COPY", Const, 0, ""}, - {"R_386_GLOB_DAT", Const, 0, ""}, - {"R_386_GOT32", Const, 0, ""}, - {"R_386_GOT32X", Const, 10, ""}, - {"R_386_GOTOFF", Const, 0, ""}, - {"R_386_GOTPC", Const, 0, ""}, - {"R_386_IRELATIVE", Const, 10, ""}, - {"R_386_JMP_SLOT", Const, 0, ""}, - {"R_386_NONE", Const, 0, ""}, - {"R_386_PC16", Const, 10, ""}, - {"R_386_PC32", Const, 0, ""}, - {"R_386_PC8", Const, 10, ""}, - {"R_386_PLT32", Const, 0, ""}, - {"R_386_RELATIVE", Const, 0, ""}, - {"R_386_SIZE32", Const, 10, ""}, - {"R_386_TLS_DESC", Const, 10, ""}, - {"R_386_TLS_DESC_CALL", Const, 10, ""}, - {"R_386_TLS_DTPMOD32", Const, 0, ""}, - {"R_386_TLS_DTPOFF32", Const, 0, ""}, - {"R_386_TLS_GD", Const, 0, ""}, - {"R_386_TLS_GD_32", Const, 0, ""}, - {"R_386_TLS_GD_CALL", Const, 0, ""}, - {"R_386_TLS_GD_POP", Const, 0, ""}, - {"R_386_TLS_GD_PUSH", Const, 0, ""}, - {"R_386_TLS_GOTDESC", Const, 10, ""}, - {"R_386_TLS_GOTIE", Const, 0, ""}, - {"R_386_TLS_IE", Const, 0, ""}, - {"R_386_TLS_IE_32", Const, 0, ""}, - {"R_386_TLS_LDM", Const, 0, ""}, - {"R_386_TLS_LDM_32", Const, 0, ""}, - {"R_386_TLS_LDM_CALL", Const, 0, ""}, - {"R_386_TLS_LDM_POP", Const, 0, ""}, - {"R_386_TLS_LDM_PUSH", Const, 0, ""}, - {"R_386_TLS_LDO_32", Const, 0, ""}, - {"R_386_TLS_LE", Const, 0, ""}, - {"R_386_TLS_LE_32", Const, 0, ""}, - {"R_386_TLS_TPOFF", Const, 0, ""}, - {"R_386_TLS_TPOFF32", Const, 0, ""}, - {"R_390", Type, 7, ""}, - {"R_390_12", Const, 7, ""}, - {"R_390_16", Const, 7, ""}, - {"R_390_20", Const, 7, ""}, - {"R_390_32", Const, 7, ""}, - {"R_390_64", Const, 7, ""}, - {"R_390_8", Const, 7, ""}, - {"R_390_COPY", Const, 7, ""}, - {"R_390_GLOB_DAT", Const, 7, ""}, - {"R_390_GOT12", Const, 7, ""}, - {"R_390_GOT16", Const, 7, ""}, - {"R_390_GOT20", Const, 7, ""}, - {"R_390_GOT32", Const, 7, ""}, - {"R_390_GOT64", Const, 7, ""}, - {"R_390_GOTENT", Const, 7, ""}, - {"R_390_GOTOFF", Const, 7, ""}, - {"R_390_GOTOFF16", Const, 7, ""}, - {"R_390_GOTOFF64", Const, 7, ""}, - {"R_390_GOTPC", Const, 7, ""}, - {"R_390_GOTPCDBL", Const, 7, ""}, - {"R_390_GOTPLT12", Const, 7, ""}, - {"R_390_GOTPLT16", Const, 7, ""}, - {"R_390_GOTPLT20", Const, 7, ""}, - {"R_390_GOTPLT32", Const, 7, ""}, - {"R_390_GOTPLT64", Const, 7, ""}, - {"R_390_GOTPLTENT", Const, 7, ""}, - {"R_390_GOTPLTOFF16", Const, 7, ""}, - {"R_390_GOTPLTOFF32", Const, 7, ""}, - {"R_390_GOTPLTOFF64", Const, 7, ""}, - {"R_390_JMP_SLOT", Const, 7, ""}, - {"R_390_NONE", Const, 7, ""}, - {"R_390_PC16", Const, 7, ""}, - {"R_390_PC16DBL", Const, 7, ""}, - {"R_390_PC32", Const, 7, ""}, - {"R_390_PC32DBL", Const, 7, ""}, - {"R_390_PC64", Const, 7, ""}, - {"R_390_PLT16DBL", Const, 7, ""}, - {"R_390_PLT32", Const, 7, ""}, - {"R_390_PLT32DBL", Const, 7, ""}, - {"R_390_PLT64", Const, 7, ""}, - {"R_390_RELATIVE", Const, 7, ""}, - {"R_390_TLS_DTPMOD", Const, 7, ""}, - {"R_390_TLS_DTPOFF", Const, 7, ""}, - {"R_390_TLS_GD32", Const, 7, ""}, - {"R_390_TLS_GD64", Const, 7, ""}, - {"R_390_TLS_GDCALL", Const, 7, ""}, - {"R_390_TLS_GOTIE12", Const, 7, ""}, - {"R_390_TLS_GOTIE20", Const, 7, ""}, - {"R_390_TLS_GOTIE32", Const, 7, ""}, - {"R_390_TLS_GOTIE64", Const, 7, ""}, - {"R_390_TLS_IE32", Const, 7, ""}, - {"R_390_TLS_IE64", Const, 7, ""}, - {"R_390_TLS_IEENT", Const, 7, ""}, - {"R_390_TLS_LDCALL", Const, 7, ""}, - {"R_390_TLS_LDM32", Const, 7, ""}, - {"R_390_TLS_LDM64", Const, 7, ""}, - {"R_390_TLS_LDO32", Const, 7, ""}, - {"R_390_TLS_LDO64", Const, 7, ""}, - {"R_390_TLS_LE32", Const, 7, ""}, - {"R_390_TLS_LE64", Const, 7, ""}, - {"R_390_TLS_LOAD", Const, 7, ""}, - {"R_390_TLS_TPOFF", Const, 7, ""}, - {"R_AARCH64", Type, 4, ""}, - {"R_AARCH64_ABS16", Const, 4, ""}, - {"R_AARCH64_ABS32", Const, 4, ""}, - {"R_AARCH64_ABS64", Const, 4, ""}, - {"R_AARCH64_ADD_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_ADR_GOT_PAGE", Const, 4, ""}, - {"R_AARCH64_ADR_PREL_LO21", Const, 4, ""}, - {"R_AARCH64_ADR_PREL_PG_HI21", Const, 4, ""}, - {"R_AARCH64_ADR_PREL_PG_HI21_NC", Const, 4, ""}, - {"R_AARCH64_CALL26", Const, 4, ""}, - {"R_AARCH64_CONDBR19", Const, 4, ""}, - {"R_AARCH64_COPY", Const, 4, ""}, - {"R_AARCH64_GLOB_DAT", Const, 4, ""}, - {"R_AARCH64_GOT_LD_PREL19", Const, 4, ""}, - {"R_AARCH64_IRELATIVE", Const, 4, ""}, - {"R_AARCH64_JUMP26", Const, 4, ""}, - {"R_AARCH64_JUMP_SLOT", Const, 4, ""}, - {"R_AARCH64_LD64_GOTOFF_LO15", Const, 10, ""}, - {"R_AARCH64_LD64_GOTPAGE_LO15", Const, 10, ""}, - {"R_AARCH64_LD64_GOT_LO12_NC", Const, 4, ""}, - {"R_AARCH64_LDST128_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_LDST16_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_LDST32_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_LDST64_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_LDST8_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_LD_PREL_LO19", Const, 4, ""}, - {"R_AARCH64_MOVW_SABS_G0", Const, 4, ""}, - {"R_AARCH64_MOVW_SABS_G1", Const, 4, ""}, - {"R_AARCH64_MOVW_SABS_G2", Const, 4, ""}, - {"R_AARCH64_MOVW_UABS_G0", Const, 4, ""}, - {"R_AARCH64_MOVW_UABS_G0_NC", Const, 4, ""}, - {"R_AARCH64_MOVW_UABS_G1", Const, 4, ""}, - {"R_AARCH64_MOVW_UABS_G1_NC", Const, 4, ""}, - {"R_AARCH64_MOVW_UABS_G2", Const, 4, ""}, - {"R_AARCH64_MOVW_UABS_G2_NC", Const, 4, ""}, - {"R_AARCH64_MOVW_UABS_G3", Const, 4, ""}, - {"R_AARCH64_NONE", Const, 4, ""}, - {"R_AARCH64_NULL", Const, 4, ""}, - {"R_AARCH64_P32_ABS16", Const, 4, ""}, - {"R_AARCH64_P32_ABS32", Const, 4, ""}, - {"R_AARCH64_P32_ADD_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_ADR_GOT_PAGE", Const, 4, ""}, - {"R_AARCH64_P32_ADR_PREL_LO21", Const, 4, ""}, - {"R_AARCH64_P32_ADR_PREL_PG_HI21", Const, 4, ""}, - {"R_AARCH64_P32_CALL26", Const, 4, ""}, - {"R_AARCH64_P32_CONDBR19", Const, 4, ""}, - {"R_AARCH64_P32_COPY", Const, 4, ""}, - {"R_AARCH64_P32_GLOB_DAT", Const, 4, ""}, - {"R_AARCH64_P32_GOT_LD_PREL19", Const, 4, ""}, - {"R_AARCH64_P32_IRELATIVE", Const, 4, ""}, - {"R_AARCH64_P32_JUMP26", Const, 4, ""}, - {"R_AARCH64_P32_JUMP_SLOT", Const, 4, ""}, - {"R_AARCH64_P32_LD32_GOT_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_LDST128_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_LDST16_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_LDST32_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_LDST64_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_LDST8_ABS_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_LD_PREL_LO19", Const, 4, ""}, - {"R_AARCH64_P32_MOVW_SABS_G0", Const, 4, ""}, - {"R_AARCH64_P32_MOVW_UABS_G0", Const, 4, ""}, - {"R_AARCH64_P32_MOVW_UABS_G0_NC", Const, 4, ""}, - {"R_AARCH64_P32_MOVW_UABS_G1", Const, 4, ""}, - {"R_AARCH64_P32_PREL16", Const, 4, ""}, - {"R_AARCH64_P32_PREL32", Const, 4, ""}, - {"R_AARCH64_P32_RELATIVE", Const, 4, ""}, - {"R_AARCH64_P32_TLSDESC", Const, 4, ""}, - {"R_AARCH64_P32_TLSDESC_ADD_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_TLSDESC_ADR_PAGE21", Const, 4, ""}, - {"R_AARCH64_P32_TLSDESC_ADR_PREL21", Const, 4, ""}, - {"R_AARCH64_P32_TLSDESC_CALL", Const, 4, ""}, - {"R_AARCH64_P32_TLSDESC_LD32_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_TLSDESC_LD_PREL19", Const, 4, ""}, - {"R_AARCH64_P32_TLSGD_ADD_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_TLSGD_ADR_PAGE21", Const, 4, ""}, - {"R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4, ""}, - {"R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19", Const, 4, ""}, - {"R_AARCH64_P32_TLSLE_ADD_TPREL_HI12", Const, 4, ""}, - {"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12", Const, 4, ""}, - {"R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC", Const, 4, ""}, - {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0", Const, 4, ""}, - {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC", Const, 4, ""}, - {"R_AARCH64_P32_TLSLE_MOVW_TPREL_G1", Const, 4, ""}, - {"R_AARCH64_P32_TLS_DTPMOD", Const, 4, ""}, - {"R_AARCH64_P32_TLS_DTPREL", Const, 4, ""}, - {"R_AARCH64_P32_TLS_TPREL", Const, 4, ""}, - {"R_AARCH64_P32_TSTBR14", Const, 4, ""}, - {"R_AARCH64_PREL16", Const, 4, ""}, - {"R_AARCH64_PREL32", Const, 4, ""}, - {"R_AARCH64_PREL64", Const, 4, ""}, - {"R_AARCH64_RELATIVE", Const, 4, ""}, - {"R_AARCH64_TLSDESC", Const, 4, ""}, - {"R_AARCH64_TLSDESC_ADD", Const, 4, ""}, - {"R_AARCH64_TLSDESC_ADD_LO12_NC", Const, 4, ""}, - {"R_AARCH64_TLSDESC_ADR_PAGE21", Const, 4, ""}, - {"R_AARCH64_TLSDESC_ADR_PREL21", Const, 4, ""}, - {"R_AARCH64_TLSDESC_CALL", Const, 4, ""}, - {"R_AARCH64_TLSDESC_LD64_LO12_NC", Const, 4, ""}, - {"R_AARCH64_TLSDESC_LDR", Const, 4, ""}, - {"R_AARCH64_TLSDESC_LD_PREL19", Const, 4, ""}, - {"R_AARCH64_TLSDESC_OFF_G0_NC", Const, 4, ""}, - {"R_AARCH64_TLSDESC_OFF_G1", Const, 4, ""}, - {"R_AARCH64_TLSGD_ADD_LO12_NC", Const, 4, ""}, - {"R_AARCH64_TLSGD_ADR_PAGE21", Const, 4, ""}, - {"R_AARCH64_TLSGD_ADR_PREL21", Const, 10, ""}, - {"R_AARCH64_TLSGD_MOVW_G0_NC", Const, 10, ""}, - {"R_AARCH64_TLSGD_MOVW_G1", Const, 10, ""}, - {"R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21", Const, 4, ""}, - {"R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC", Const, 4, ""}, - {"R_AARCH64_TLSIE_LD_GOTTPREL_PREL19", Const, 4, ""}, - {"R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC", Const, 4, ""}, - {"R_AARCH64_TLSIE_MOVW_GOTTPREL_G1", Const, 4, ""}, - {"R_AARCH64_TLSLD_ADR_PAGE21", Const, 10, ""}, - {"R_AARCH64_TLSLD_ADR_PREL21", Const, 10, ""}, - {"R_AARCH64_TLSLD_LDST128_DTPREL_LO12", Const, 10, ""}, - {"R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC", Const, 10, ""}, - {"R_AARCH64_TLSLE_ADD_TPREL_HI12", Const, 4, ""}, - {"R_AARCH64_TLSLE_ADD_TPREL_LO12", Const, 4, ""}, - {"R_AARCH64_TLSLE_ADD_TPREL_LO12_NC", Const, 4, ""}, - {"R_AARCH64_TLSLE_LDST128_TPREL_LO12", Const, 10, ""}, - {"R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC", Const, 10, ""}, - {"R_AARCH64_TLSLE_MOVW_TPREL_G0", Const, 4, ""}, - {"R_AARCH64_TLSLE_MOVW_TPREL_G0_NC", Const, 4, ""}, - {"R_AARCH64_TLSLE_MOVW_TPREL_G1", Const, 4, ""}, - {"R_AARCH64_TLSLE_MOVW_TPREL_G1_NC", Const, 4, ""}, - {"R_AARCH64_TLSLE_MOVW_TPREL_G2", Const, 4, ""}, - {"R_AARCH64_TLS_DTPMOD64", Const, 4, ""}, - {"R_AARCH64_TLS_DTPREL64", Const, 4, ""}, - {"R_AARCH64_TLS_TPREL64", Const, 4, ""}, - {"R_AARCH64_TSTBR14", Const, 4, ""}, - {"R_ALPHA", Type, 0, ""}, - {"R_ALPHA_BRADDR", Const, 0, ""}, - {"R_ALPHA_COPY", Const, 0, ""}, - {"R_ALPHA_GLOB_DAT", Const, 0, ""}, - {"R_ALPHA_GPDISP", Const, 0, ""}, - {"R_ALPHA_GPREL32", Const, 0, ""}, - {"R_ALPHA_GPRELHIGH", Const, 0, ""}, - {"R_ALPHA_GPRELLOW", Const, 0, ""}, - {"R_ALPHA_GPVALUE", Const, 0, ""}, - {"R_ALPHA_HINT", Const, 0, ""}, - {"R_ALPHA_IMMED_BR_HI32", Const, 0, ""}, - {"R_ALPHA_IMMED_GP_16", Const, 0, ""}, - {"R_ALPHA_IMMED_GP_HI32", Const, 0, ""}, - {"R_ALPHA_IMMED_LO32", Const, 0, ""}, - {"R_ALPHA_IMMED_SCN_HI32", Const, 0, ""}, - {"R_ALPHA_JMP_SLOT", Const, 0, ""}, - {"R_ALPHA_LITERAL", Const, 0, ""}, - {"R_ALPHA_LITUSE", Const, 0, ""}, - {"R_ALPHA_NONE", Const, 0, ""}, - {"R_ALPHA_OP_PRSHIFT", Const, 0, ""}, - {"R_ALPHA_OP_PSUB", Const, 0, ""}, - {"R_ALPHA_OP_PUSH", Const, 0, ""}, - {"R_ALPHA_OP_STORE", Const, 0, ""}, - {"R_ALPHA_REFLONG", Const, 0, ""}, - {"R_ALPHA_REFQUAD", Const, 0, ""}, - {"R_ALPHA_RELATIVE", Const, 0, ""}, - {"R_ALPHA_SREL16", Const, 0, ""}, - {"R_ALPHA_SREL32", Const, 0, ""}, - {"R_ALPHA_SREL64", Const, 0, ""}, - {"R_ARM", Type, 0, ""}, - {"R_ARM_ABS12", Const, 0, ""}, - {"R_ARM_ABS16", Const, 0, ""}, - {"R_ARM_ABS32", Const, 0, ""}, - {"R_ARM_ABS32_NOI", Const, 10, ""}, - {"R_ARM_ABS8", Const, 0, ""}, - {"R_ARM_ALU_PCREL_15_8", Const, 10, ""}, - {"R_ARM_ALU_PCREL_23_15", Const, 10, ""}, - {"R_ARM_ALU_PCREL_7_0", Const, 10, ""}, - {"R_ARM_ALU_PC_G0", Const, 10, ""}, - {"R_ARM_ALU_PC_G0_NC", Const, 10, ""}, - {"R_ARM_ALU_PC_G1", Const, 10, ""}, - {"R_ARM_ALU_PC_G1_NC", Const, 10, ""}, - {"R_ARM_ALU_PC_G2", Const, 10, ""}, - {"R_ARM_ALU_SBREL_19_12_NC", Const, 10, ""}, - {"R_ARM_ALU_SBREL_27_20_CK", Const, 10, ""}, - {"R_ARM_ALU_SB_G0", Const, 10, ""}, - {"R_ARM_ALU_SB_G0_NC", Const, 10, ""}, - {"R_ARM_ALU_SB_G1", Const, 10, ""}, - {"R_ARM_ALU_SB_G1_NC", Const, 10, ""}, - {"R_ARM_ALU_SB_G2", Const, 10, ""}, - {"R_ARM_AMP_VCALL9", Const, 0, ""}, - {"R_ARM_BASE_ABS", Const, 10, ""}, - {"R_ARM_CALL", Const, 10, ""}, - {"R_ARM_COPY", Const, 0, ""}, - {"R_ARM_GLOB_DAT", Const, 0, ""}, - {"R_ARM_GNU_VTENTRY", Const, 0, ""}, - {"R_ARM_GNU_VTINHERIT", Const, 0, ""}, - {"R_ARM_GOT32", Const, 0, ""}, - {"R_ARM_GOTOFF", Const, 0, ""}, - {"R_ARM_GOTOFF12", Const, 10, ""}, - {"R_ARM_GOTPC", Const, 0, ""}, - {"R_ARM_GOTRELAX", Const, 10, ""}, - {"R_ARM_GOT_ABS", Const, 10, ""}, - {"R_ARM_GOT_BREL12", Const, 10, ""}, - {"R_ARM_GOT_PREL", Const, 10, ""}, - {"R_ARM_IRELATIVE", Const, 10, ""}, - {"R_ARM_JUMP24", Const, 10, ""}, - {"R_ARM_JUMP_SLOT", Const, 0, ""}, - {"R_ARM_LDC_PC_G0", Const, 10, ""}, - {"R_ARM_LDC_PC_G1", Const, 10, ""}, - {"R_ARM_LDC_PC_G2", Const, 10, ""}, - {"R_ARM_LDC_SB_G0", Const, 10, ""}, - {"R_ARM_LDC_SB_G1", Const, 10, ""}, - {"R_ARM_LDC_SB_G2", Const, 10, ""}, - {"R_ARM_LDRS_PC_G0", Const, 10, ""}, - {"R_ARM_LDRS_PC_G1", Const, 10, ""}, - {"R_ARM_LDRS_PC_G2", Const, 10, ""}, - {"R_ARM_LDRS_SB_G0", Const, 10, ""}, - {"R_ARM_LDRS_SB_G1", Const, 10, ""}, - {"R_ARM_LDRS_SB_G2", Const, 10, ""}, - {"R_ARM_LDR_PC_G1", Const, 10, ""}, - {"R_ARM_LDR_PC_G2", Const, 10, ""}, - {"R_ARM_LDR_SBREL_11_10_NC", Const, 10, ""}, - {"R_ARM_LDR_SB_G0", Const, 10, ""}, - {"R_ARM_LDR_SB_G1", Const, 10, ""}, - {"R_ARM_LDR_SB_G2", Const, 10, ""}, - {"R_ARM_ME_TOO", Const, 10, ""}, - {"R_ARM_MOVT_ABS", Const, 10, ""}, - {"R_ARM_MOVT_BREL", Const, 10, ""}, - {"R_ARM_MOVT_PREL", Const, 10, ""}, - {"R_ARM_MOVW_ABS_NC", Const, 10, ""}, - {"R_ARM_MOVW_BREL", Const, 10, ""}, - {"R_ARM_MOVW_BREL_NC", Const, 10, ""}, - {"R_ARM_MOVW_PREL_NC", Const, 10, ""}, - {"R_ARM_NONE", Const, 0, ""}, - {"R_ARM_PC13", Const, 0, ""}, - {"R_ARM_PC24", Const, 0, ""}, - {"R_ARM_PLT32", Const, 0, ""}, - {"R_ARM_PLT32_ABS", Const, 10, ""}, - {"R_ARM_PREL31", Const, 10, ""}, - {"R_ARM_PRIVATE_0", Const, 10, ""}, - {"R_ARM_PRIVATE_1", Const, 10, ""}, - {"R_ARM_PRIVATE_10", Const, 10, ""}, - {"R_ARM_PRIVATE_11", Const, 10, ""}, - {"R_ARM_PRIVATE_12", Const, 10, ""}, - {"R_ARM_PRIVATE_13", Const, 10, ""}, - {"R_ARM_PRIVATE_14", Const, 10, ""}, - {"R_ARM_PRIVATE_15", Const, 10, ""}, - {"R_ARM_PRIVATE_2", Const, 10, ""}, - {"R_ARM_PRIVATE_3", Const, 10, ""}, - {"R_ARM_PRIVATE_4", Const, 10, ""}, - {"R_ARM_PRIVATE_5", Const, 10, ""}, - {"R_ARM_PRIVATE_6", Const, 10, ""}, - {"R_ARM_PRIVATE_7", Const, 10, ""}, - {"R_ARM_PRIVATE_8", Const, 10, ""}, - {"R_ARM_PRIVATE_9", Const, 10, ""}, - {"R_ARM_RABS32", Const, 0, ""}, - {"R_ARM_RBASE", Const, 0, ""}, - {"R_ARM_REL32", Const, 0, ""}, - {"R_ARM_REL32_NOI", Const, 10, ""}, - {"R_ARM_RELATIVE", Const, 0, ""}, - {"R_ARM_RPC24", Const, 0, ""}, - {"R_ARM_RREL32", Const, 0, ""}, - {"R_ARM_RSBREL32", Const, 0, ""}, - {"R_ARM_RXPC25", Const, 10, ""}, - {"R_ARM_SBREL31", Const, 10, ""}, - {"R_ARM_SBREL32", Const, 0, ""}, - {"R_ARM_SWI24", Const, 0, ""}, - {"R_ARM_TARGET1", Const, 10, ""}, - {"R_ARM_TARGET2", Const, 10, ""}, - {"R_ARM_THM_ABS5", Const, 0, ""}, - {"R_ARM_THM_ALU_ABS_G0_NC", Const, 10, ""}, - {"R_ARM_THM_ALU_ABS_G1_NC", Const, 10, ""}, - {"R_ARM_THM_ALU_ABS_G2_NC", Const, 10, ""}, - {"R_ARM_THM_ALU_ABS_G3", Const, 10, ""}, - {"R_ARM_THM_ALU_PREL_11_0", Const, 10, ""}, - {"R_ARM_THM_GOT_BREL12", Const, 10, ""}, - {"R_ARM_THM_JUMP11", Const, 10, ""}, - {"R_ARM_THM_JUMP19", Const, 10, ""}, - {"R_ARM_THM_JUMP24", Const, 10, ""}, - {"R_ARM_THM_JUMP6", Const, 10, ""}, - {"R_ARM_THM_JUMP8", Const, 10, ""}, - {"R_ARM_THM_MOVT_ABS", Const, 10, ""}, - {"R_ARM_THM_MOVT_BREL", Const, 10, ""}, - {"R_ARM_THM_MOVT_PREL", Const, 10, ""}, - {"R_ARM_THM_MOVW_ABS_NC", Const, 10, ""}, - {"R_ARM_THM_MOVW_BREL", Const, 10, ""}, - {"R_ARM_THM_MOVW_BREL_NC", Const, 10, ""}, - {"R_ARM_THM_MOVW_PREL_NC", Const, 10, ""}, - {"R_ARM_THM_PC12", Const, 10, ""}, - {"R_ARM_THM_PC22", Const, 0, ""}, - {"R_ARM_THM_PC8", Const, 0, ""}, - {"R_ARM_THM_RPC22", Const, 0, ""}, - {"R_ARM_THM_SWI8", Const, 0, ""}, - {"R_ARM_THM_TLS_CALL", Const, 10, ""}, - {"R_ARM_THM_TLS_DESCSEQ16", Const, 10, ""}, - {"R_ARM_THM_TLS_DESCSEQ32", Const, 10, ""}, - {"R_ARM_THM_XPC22", Const, 0, ""}, - {"R_ARM_TLS_CALL", Const, 10, ""}, - {"R_ARM_TLS_DESCSEQ", Const, 10, ""}, - {"R_ARM_TLS_DTPMOD32", Const, 10, ""}, - {"R_ARM_TLS_DTPOFF32", Const, 10, ""}, - {"R_ARM_TLS_GD32", Const, 10, ""}, - {"R_ARM_TLS_GOTDESC", Const, 10, ""}, - {"R_ARM_TLS_IE12GP", Const, 10, ""}, - {"R_ARM_TLS_IE32", Const, 10, ""}, - {"R_ARM_TLS_LDM32", Const, 10, ""}, - {"R_ARM_TLS_LDO12", Const, 10, ""}, - {"R_ARM_TLS_LDO32", Const, 10, ""}, - {"R_ARM_TLS_LE12", Const, 10, ""}, - {"R_ARM_TLS_LE32", Const, 10, ""}, - {"R_ARM_TLS_TPOFF32", Const, 10, ""}, - {"R_ARM_V4BX", Const, 10, ""}, - {"R_ARM_XPC25", Const, 0, ""}, - {"R_INFO", Func, 0, "func(sym uint32, typ uint32) uint64"}, - {"R_INFO32", Func, 0, "func(sym uint32, typ uint32) uint32"}, - {"R_LARCH", Type, 19, ""}, - {"R_LARCH_32", Const, 19, ""}, - {"R_LARCH_32_PCREL", Const, 20, ""}, - {"R_LARCH_64", Const, 19, ""}, - {"R_LARCH_64_PCREL", Const, 22, ""}, - {"R_LARCH_ABS64_HI12", Const, 20, ""}, - {"R_LARCH_ABS64_LO20", Const, 20, ""}, - {"R_LARCH_ABS_HI20", Const, 20, ""}, - {"R_LARCH_ABS_LO12", Const, 20, ""}, - {"R_LARCH_ADD16", Const, 19, ""}, - {"R_LARCH_ADD24", Const, 19, ""}, - {"R_LARCH_ADD32", Const, 19, ""}, - {"R_LARCH_ADD6", Const, 22, ""}, - {"R_LARCH_ADD64", Const, 19, ""}, - {"R_LARCH_ADD8", Const, 19, ""}, - {"R_LARCH_ADD_ULEB128", Const, 22, ""}, - {"R_LARCH_ALIGN", Const, 22, ""}, - {"R_LARCH_B16", Const, 20, ""}, - {"R_LARCH_B21", Const, 20, ""}, - {"R_LARCH_B26", Const, 20, ""}, - {"R_LARCH_CALL36", Const, 26, ""}, - {"R_LARCH_CFA", Const, 22, ""}, - {"R_LARCH_COPY", Const, 19, ""}, - {"R_LARCH_DELETE", Const, 22, ""}, - {"R_LARCH_GNU_VTENTRY", Const, 20, ""}, - {"R_LARCH_GNU_VTINHERIT", Const, 20, ""}, - {"R_LARCH_GOT64_HI12", Const, 20, ""}, - {"R_LARCH_GOT64_LO20", Const, 20, ""}, - {"R_LARCH_GOT64_PC_HI12", Const, 20, ""}, - {"R_LARCH_GOT64_PC_LO20", Const, 20, ""}, - {"R_LARCH_GOT_HI20", Const, 20, ""}, - {"R_LARCH_GOT_LO12", Const, 20, ""}, - {"R_LARCH_GOT_PC_HI20", Const, 20, ""}, - {"R_LARCH_GOT_PC_LO12", Const, 20, ""}, - {"R_LARCH_IRELATIVE", Const, 19, ""}, - {"R_LARCH_JUMP_SLOT", Const, 19, ""}, - {"R_LARCH_MARK_LA", Const, 19, ""}, - {"R_LARCH_MARK_PCREL", Const, 19, ""}, - {"R_LARCH_NONE", Const, 19, ""}, - {"R_LARCH_PCALA64_HI12", Const, 20, ""}, - {"R_LARCH_PCALA64_LO20", Const, 20, ""}, - {"R_LARCH_PCALA_HI20", Const, 20, ""}, - {"R_LARCH_PCALA_LO12", Const, 20, ""}, - {"R_LARCH_PCREL20_S2", Const, 22, ""}, - {"R_LARCH_RELATIVE", Const, 19, ""}, - {"R_LARCH_RELAX", Const, 20, ""}, - {"R_LARCH_SOP_ADD", Const, 19, ""}, - {"R_LARCH_SOP_AND", Const, 19, ""}, - {"R_LARCH_SOP_ASSERT", Const, 19, ""}, - {"R_LARCH_SOP_IF_ELSE", Const, 19, ""}, - {"R_LARCH_SOP_NOT", Const, 19, ""}, - {"R_LARCH_SOP_POP_32_S_0_10_10_16_S2", Const, 19, ""}, - {"R_LARCH_SOP_POP_32_S_0_5_10_16_S2", Const, 19, ""}, - {"R_LARCH_SOP_POP_32_S_10_12", Const, 19, ""}, - {"R_LARCH_SOP_POP_32_S_10_16", Const, 19, ""}, - {"R_LARCH_SOP_POP_32_S_10_16_S2", Const, 19, ""}, - {"R_LARCH_SOP_POP_32_S_10_5", Const, 19, ""}, - {"R_LARCH_SOP_POP_32_S_5_20", Const, 19, ""}, - {"R_LARCH_SOP_POP_32_U", Const, 19, ""}, - {"R_LARCH_SOP_POP_32_U_10_12", Const, 19, ""}, - {"R_LARCH_SOP_PUSH_ABSOLUTE", Const, 19, ""}, - {"R_LARCH_SOP_PUSH_DUP", Const, 19, ""}, - {"R_LARCH_SOP_PUSH_GPREL", Const, 19, ""}, - {"R_LARCH_SOP_PUSH_PCREL", Const, 19, ""}, - {"R_LARCH_SOP_PUSH_PLT_PCREL", Const, 19, ""}, - {"R_LARCH_SOP_PUSH_TLS_GD", Const, 19, ""}, - {"R_LARCH_SOP_PUSH_TLS_GOT", Const, 19, ""}, - {"R_LARCH_SOP_PUSH_TLS_TPREL", Const, 19, ""}, - {"R_LARCH_SOP_SL", Const, 19, ""}, - {"R_LARCH_SOP_SR", Const, 19, ""}, - {"R_LARCH_SOP_SUB", Const, 19, ""}, - {"R_LARCH_SUB16", Const, 19, ""}, - {"R_LARCH_SUB24", Const, 19, ""}, - {"R_LARCH_SUB32", Const, 19, ""}, - {"R_LARCH_SUB6", Const, 22, ""}, - {"R_LARCH_SUB64", Const, 19, ""}, - {"R_LARCH_SUB8", Const, 19, ""}, - {"R_LARCH_SUB_ULEB128", Const, 22, ""}, - {"R_LARCH_TLS_DESC32", Const, 26, ""}, - {"R_LARCH_TLS_DESC64", Const, 26, ""}, - {"R_LARCH_TLS_DESC64_HI12", Const, 26, ""}, - {"R_LARCH_TLS_DESC64_LO20", Const, 26, ""}, - {"R_LARCH_TLS_DESC64_PC_HI12", Const, 26, ""}, - {"R_LARCH_TLS_DESC64_PC_LO20", Const, 26, ""}, - {"R_LARCH_TLS_DESC_CALL", Const, 26, ""}, - {"R_LARCH_TLS_DESC_HI20", Const, 26, ""}, - {"R_LARCH_TLS_DESC_LD", Const, 26, ""}, - {"R_LARCH_TLS_DESC_LO12", Const, 26, ""}, - {"R_LARCH_TLS_DESC_PCREL20_S2", Const, 26, ""}, - {"R_LARCH_TLS_DESC_PC_HI20", Const, 26, ""}, - {"R_LARCH_TLS_DESC_PC_LO12", Const, 26, ""}, - {"R_LARCH_TLS_DTPMOD32", Const, 19, ""}, - {"R_LARCH_TLS_DTPMOD64", Const, 19, ""}, - {"R_LARCH_TLS_DTPREL32", Const, 19, ""}, - {"R_LARCH_TLS_DTPREL64", Const, 19, ""}, - {"R_LARCH_TLS_GD_HI20", Const, 20, ""}, - {"R_LARCH_TLS_GD_PCREL20_S2", Const, 26, ""}, - {"R_LARCH_TLS_GD_PC_HI20", Const, 20, ""}, - {"R_LARCH_TLS_IE64_HI12", Const, 20, ""}, - {"R_LARCH_TLS_IE64_LO20", Const, 20, ""}, - {"R_LARCH_TLS_IE64_PC_HI12", Const, 20, ""}, - {"R_LARCH_TLS_IE64_PC_LO20", Const, 20, ""}, - {"R_LARCH_TLS_IE_HI20", Const, 20, ""}, - {"R_LARCH_TLS_IE_LO12", Const, 20, ""}, - {"R_LARCH_TLS_IE_PC_HI20", Const, 20, ""}, - {"R_LARCH_TLS_IE_PC_LO12", Const, 20, ""}, - {"R_LARCH_TLS_LD_HI20", Const, 20, ""}, - {"R_LARCH_TLS_LD_PCREL20_S2", Const, 26, ""}, - {"R_LARCH_TLS_LD_PC_HI20", Const, 20, ""}, - {"R_LARCH_TLS_LE64_HI12", Const, 20, ""}, - {"R_LARCH_TLS_LE64_LO20", Const, 20, ""}, - {"R_LARCH_TLS_LE_ADD_R", Const, 26, ""}, - {"R_LARCH_TLS_LE_HI20", Const, 20, ""}, - {"R_LARCH_TLS_LE_HI20_R", Const, 26, ""}, - {"R_LARCH_TLS_LE_LO12", Const, 20, ""}, - {"R_LARCH_TLS_LE_LO12_R", Const, 26, ""}, - {"R_LARCH_TLS_TPREL32", Const, 19, ""}, - {"R_LARCH_TLS_TPREL64", Const, 19, ""}, - {"R_MIPS", Type, 6, ""}, - {"R_MIPS_16", Const, 6, ""}, - {"R_MIPS_26", Const, 6, ""}, - {"R_MIPS_32", Const, 6, ""}, - {"R_MIPS_64", Const, 6, ""}, - {"R_MIPS_ADD_IMMEDIATE", Const, 6, ""}, - {"R_MIPS_CALL16", Const, 6, ""}, - {"R_MIPS_CALL_HI16", Const, 6, ""}, - {"R_MIPS_CALL_LO16", Const, 6, ""}, - {"R_MIPS_DELETE", Const, 6, ""}, - {"R_MIPS_GOT16", Const, 6, ""}, - {"R_MIPS_GOT_DISP", Const, 6, ""}, - {"R_MIPS_GOT_HI16", Const, 6, ""}, - {"R_MIPS_GOT_LO16", Const, 6, ""}, - {"R_MIPS_GOT_OFST", Const, 6, ""}, - {"R_MIPS_GOT_PAGE", Const, 6, ""}, - {"R_MIPS_GPREL16", Const, 6, ""}, - {"R_MIPS_GPREL32", Const, 6, ""}, - {"R_MIPS_HI16", Const, 6, ""}, - {"R_MIPS_HIGHER", Const, 6, ""}, - {"R_MIPS_HIGHEST", Const, 6, ""}, - {"R_MIPS_INSERT_A", Const, 6, ""}, - {"R_MIPS_INSERT_B", Const, 6, ""}, - {"R_MIPS_JALR", Const, 6, ""}, - {"R_MIPS_LITERAL", Const, 6, ""}, - {"R_MIPS_LO16", Const, 6, ""}, - {"R_MIPS_NONE", Const, 6, ""}, - {"R_MIPS_PC16", Const, 6, ""}, - {"R_MIPS_PC32", Const, 22, ""}, - {"R_MIPS_PJUMP", Const, 6, ""}, - {"R_MIPS_REL16", Const, 6, ""}, - {"R_MIPS_REL32", Const, 6, ""}, - {"R_MIPS_RELGOT", Const, 6, ""}, - {"R_MIPS_SCN_DISP", Const, 6, ""}, - {"R_MIPS_SHIFT5", Const, 6, ""}, - {"R_MIPS_SHIFT6", Const, 6, ""}, - {"R_MIPS_SUB", Const, 6, ""}, - {"R_MIPS_TLS_DTPMOD32", Const, 6, ""}, - {"R_MIPS_TLS_DTPMOD64", Const, 6, ""}, - {"R_MIPS_TLS_DTPREL32", Const, 6, ""}, - {"R_MIPS_TLS_DTPREL64", Const, 6, ""}, - {"R_MIPS_TLS_DTPREL_HI16", Const, 6, ""}, - {"R_MIPS_TLS_DTPREL_LO16", Const, 6, ""}, - {"R_MIPS_TLS_GD", Const, 6, ""}, - {"R_MIPS_TLS_GOTTPREL", Const, 6, ""}, - {"R_MIPS_TLS_LDM", Const, 6, ""}, - {"R_MIPS_TLS_TPREL32", Const, 6, ""}, - {"R_MIPS_TLS_TPREL64", Const, 6, ""}, - {"R_MIPS_TLS_TPREL_HI16", Const, 6, ""}, - {"R_MIPS_TLS_TPREL_LO16", Const, 6, ""}, - {"R_PPC", Type, 0, ""}, - {"R_PPC64", Type, 5, ""}, - {"R_PPC64_ADDR14", Const, 5, ""}, - {"R_PPC64_ADDR14_BRNTAKEN", Const, 5, ""}, - {"R_PPC64_ADDR14_BRTAKEN", Const, 5, ""}, - {"R_PPC64_ADDR16", Const, 5, ""}, - {"R_PPC64_ADDR16_DS", Const, 5, ""}, - {"R_PPC64_ADDR16_HA", Const, 5, ""}, - {"R_PPC64_ADDR16_HI", Const, 5, ""}, - {"R_PPC64_ADDR16_HIGH", Const, 10, ""}, - {"R_PPC64_ADDR16_HIGHA", Const, 10, ""}, - {"R_PPC64_ADDR16_HIGHER", Const, 5, ""}, - {"R_PPC64_ADDR16_HIGHER34", Const, 20, ""}, - {"R_PPC64_ADDR16_HIGHERA", Const, 5, ""}, - {"R_PPC64_ADDR16_HIGHERA34", Const, 20, ""}, - {"R_PPC64_ADDR16_HIGHEST", Const, 5, ""}, - {"R_PPC64_ADDR16_HIGHEST34", Const, 20, ""}, - {"R_PPC64_ADDR16_HIGHESTA", Const, 5, ""}, - {"R_PPC64_ADDR16_HIGHESTA34", Const, 20, ""}, - {"R_PPC64_ADDR16_LO", Const, 5, ""}, - {"R_PPC64_ADDR16_LO_DS", Const, 5, ""}, - {"R_PPC64_ADDR24", Const, 5, ""}, - {"R_PPC64_ADDR32", Const, 5, ""}, - {"R_PPC64_ADDR64", Const, 5, ""}, - {"R_PPC64_ADDR64_LOCAL", Const, 10, ""}, - {"R_PPC64_COPY", Const, 20, ""}, - {"R_PPC64_D28", Const, 20, ""}, - {"R_PPC64_D34", Const, 20, ""}, - {"R_PPC64_D34_HA30", Const, 20, ""}, - {"R_PPC64_D34_HI30", Const, 20, ""}, - {"R_PPC64_D34_LO", Const, 20, ""}, - {"R_PPC64_DTPMOD64", Const, 5, ""}, - {"R_PPC64_DTPREL16", Const, 5, ""}, - {"R_PPC64_DTPREL16_DS", Const, 5, ""}, - {"R_PPC64_DTPREL16_HA", Const, 5, ""}, - {"R_PPC64_DTPREL16_HI", Const, 5, ""}, - {"R_PPC64_DTPREL16_HIGH", Const, 10, ""}, - {"R_PPC64_DTPREL16_HIGHA", Const, 10, ""}, - {"R_PPC64_DTPREL16_HIGHER", Const, 5, ""}, - {"R_PPC64_DTPREL16_HIGHERA", Const, 5, ""}, - {"R_PPC64_DTPREL16_HIGHEST", Const, 5, ""}, - {"R_PPC64_DTPREL16_HIGHESTA", Const, 5, ""}, - {"R_PPC64_DTPREL16_LO", Const, 5, ""}, - {"R_PPC64_DTPREL16_LO_DS", Const, 5, ""}, - {"R_PPC64_DTPREL34", Const, 20, ""}, - {"R_PPC64_DTPREL64", Const, 5, ""}, - {"R_PPC64_ENTRY", Const, 10, ""}, - {"R_PPC64_GLOB_DAT", Const, 20, ""}, - {"R_PPC64_GNU_VTENTRY", Const, 20, ""}, - {"R_PPC64_GNU_VTINHERIT", Const, 20, ""}, - {"R_PPC64_GOT16", Const, 5, ""}, - {"R_PPC64_GOT16_DS", Const, 5, ""}, - {"R_PPC64_GOT16_HA", Const, 5, ""}, - {"R_PPC64_GOT16_HI", Const, 5, ""}, - {"R_PPC64_GOT16_LO", Const, 5, ""}, - {"R_PPC64_GOT16_LO_DS", Const, 5, ""}, - {"R_PPC64_GOT_DTPREL16_DS", Const, 5, ""}, - {"R_PPC64_GOT_DTPREL16_HA", Const, 5, ""}, - {"R_PPC64_GOT_DTPREL16_HI", Const, 5, ""}, - {"R_PPC64_GOT_DTPREL16_LO_DS", Const, 5, ""}, - {"R_PPC64_GOT_DTPREL_PCREL34", Const, 20, ""}, - {"R_PPC64_GOT_PCREL34", Const, 20, ""}, - {"R_PPC64_GOT_TLSGD16", Const, 5, ""}, - {"R_PPC64_GOT_TLSGD16_HA", Const, 5, ""}, - {"R_PPC64_GOT_TLSGD16_HI", Const, 5, ""}, - {"R_PPC64_GOT_TLSGD16_LO", Const, 5, ""}, - {"R_PPC64_GOT_TLSGD_PCREL34", Const, 20, ""}, - {"R_PPC64_GOT_TLSLD16", Const, 5, ""}, - {"R_PPC64_GOT_TLSLD16_HA", Const, 5, ""}, - {"R_PPC64_GOT_TLSLD16_HI", Const, 5, ""}, - {"R_PPC64_GOT_TLSLD16_LO", Const, 5, ""}, - {"R_PPC64_GOT_TLSLD_PCREL34", Const, 20, ""}, - {"R_PPC64_GOT_TPREL16_DS", Const, 5, ""}, - {"R_PPC64_GOT_TPREL16_HA", Const, 5, ""}, - {"R_PPC64_GOT_TPREL16_HI", Const, 5, ""}, - {"R_PPC64_GOT_TPREL16_LO_DS", Const, 5, ""}, - {"R_PPC64_GOT_TPREL_PCREL34", Const, 20, ""}, - {"R_PPC64_IRELATIVE", Const, 10, ""}, - {"R_PPC64_JMP_IREL", Const, 10, ""}, - {"R_PPC64_JMP_SLOT", Const, 5, ""}, - {"R_PPC64_NONE", Const, 5, ""}, - {"R_PPC64_PCREL28", Const, 20, ""}, - {"R_PPC64_PCREL34", Const, 20, ""}, - {"R_PPC64_PCREL_OPT", Const, 20, ""}, - {"R_PPC64_PLT16_HA", Const, 20, ""}, - {"R_PPC64_PLT16_HI", Const, 20, ""}, - {"R_PPC64_PLT16_LO", Const, 20, ""}, - {"R_PPC64_PLT16_LO_DS", Const, 10, ""}, - {"R_PPC64_PLT32", Const, 20, ""}, - {"R_PPC64_PLT64", Const, 20, ""}, - {"R_PPC64_PLTCALL", Const, 20, ""}, - {"R_PPC64_PLTCALL_NOTOC", Const, 20, ""}, - {"R_PPC64_PLTGOT16", Const, 10, ""}, - {"R_PPC64_PLTGOT16_DS", Const, 10, ""}, - {"R_PPC64_PLTGOT16_HA", Const, 10, ""}, - {"R_PPC64_PLTGOT16_HI", Const, 10, ""}, - {"R_PPC64_PLTGOT16_LO", Const, 10, ""}, - {"R_PPC64_PLTGOT_LO_DS", Const, 10, ""}, - {"R_PPC64_PLTREL32", Const, 20, ""}, - {"R_PPC64_PLTREL64", Const, 20, ""}, - {"R_PPC64_PLTSEQ", Const, 20, ""}, - {"R_PPC64_PLTSEQ_NOTOC", Const, 20, ""}, - {"R_PPC64_PLT_PCREL34", Const, 20, ""}, - {"R_PPC64_PLT_PCREL34_NOTOC", Const, 20, ""}, - {"R_PPC64_REL14", Const, 5, ""}, - {"R_PPC64_REL14_BRNTAKEN", Const, 5, ""}, - {"R_PPC64_REL14_BRTAKEN", Const, 5, ""}, - {"R_PPC64_REL16", Const, 5, ""}, - {"R_PPC64_REL16DX_HA", Const, 10, ""}, - {"R_PPC64_REL16_HA", Const, 5, ""}, - {"R_PPC64_REL16_HI", Const, 5, ""}, - {"R_PPC64_REL16_HIGH", Const, 20, ""}, - {"R_PPC64_REL16_HIGHA", Const, 20, ""}, - {"R_PPC64_REL16_HIGHER", Const, 20, ""}, - {"R_PPC64_REL16_HIGHER34", Const, 20, ""}, - {"R_PPC64_REL16_HIGHERA", Const, 20, ""}, - {"R_PPC64_REL16_HIGHERA34", Const, 20, ""}, - {"R_PPC64_REL16_HIGHEST", Const, 20, ""}, - {"R_PPC64_REL16_HIGHEST34", Const, 20, ""}, - {"R_PPC64_REL16_HIGHESTA", Const, 20, ""}, - {"R_PPC64_REL16_HIGHESTA34", Const, 20, ""}, - {"R_PPC64_REL16_LO", Const, 5, ""}, - {"R_PPC64_REL24", Const, 5, ""}, - {"R_PPC64_REL24_NOTOC", Const, 10, ""}, - {"R_PPC64_REL24_P9NOTOC", Const, 21, ""}, - {"R_PPC64_REL30", Const, 20, ""}, - {"R_PPC64_REL32", Const, 5, ""}, - {"R_PPC64_REL64", Const, 5, ""}, - {"R_PPC64_RELATIVE", Const, 18, ""}, - {"R_PPC64_SECTOFF", Const, 20, ""}, - {"R_PPC64_SECTOFF_DS", Const, 10, ""}, - {"R_PPC64_SECTOFF_HA", Const, 20, ""}, - {"R_PPC64_SECTOFF_HI", Const, 20, ""}, - {"R_PPC64_SECTOFF_LO", Const, 20, ""}, - {"R_PPC64_SECTOFF_LO_DS", Const, 10, ""}, - {"R_PPC64_TLS", Const, 5, ""}, - {"R_PPC64_TLSGD", Const, 5, ""}, - {"R_PPC64_TLSLD", Const, 5, ""}, - {"R_PPC64_TOC", Const, 5, ""}, - {"R_PPC64_TOC16", Const, 5, ""}, - {"R_PPC64_TOC16_DS", Const, 5, ""}, - {"R_PPC64_TOC16_HA", Const, 5, ""}, - {"R_PPC64_TOC16_HI", Const, 5, ""}, - {"R_PPC64_TOC16_LO", Const, 5, ""}, - {"R_PPC64_TOC16_LO_DS", Const, 5, ""}, - {"R_PPC64_TOCSAVE", Const, 10, ""}, - {"R_PPC64_TPREL16", Const, 5, ""}, - {"R_PPC64_TPREL16_DS", Const, 5, ""}, - {"R_PPC64_TPREL16_HA", Const, 5, ""}, - {"R_PPC64_TPREL16_HI", Const, 5, ""}, - {"R_PPC64_TPREL16_HIGH", Const, 10, ""}, - {"R_PPC64_TPREL16_HIGHA", Const, 10, ""}, - {"R_PPC64_TPREL16_HIGHER", Const, 5, ""}, - {"R_PPC64_TPREL16_HIGHERA", Const, 5, ""}, - {"R_PPC64_TPREL16_HIGHEST", Const, 5, ""}, - {"R_PPC64_TPREL16_HIGHESTA", Const, 5, ""}, - {"R_PPC64_TPREL16_LO", Const, 5, ""}, - {"R_PPC64_TPREL16_LO_DS", Const, 5, ""}, - {"R_PPC64_TPREL34", Const, 20, ""}, - {"R_PPC64_TPREL64", Const, 5, ""}, - {"R_PPC64_UADDR16", Const, 20, ""}, - {"R_PPC64_UADDR32", Const, 20, ""}, - {"R_PPC64_UADDR64", Const, 20, ""}, - {"R_PPC_ADDR14", Const, 0, ""}, - {"R_PPC_ADDR14_BRNTAKEN", Const, 0, ""}, - {"R_PPC_ADDR14_BRTAKEN", Const, 0, ""}, - {"R_PPC_ADDR16", Const, 0, ""}, - {"R_PPC_ADDR16_HA", Const, 0, ""}, - {"R_PPC_ADDR16_HI", Const, 0, ""}, - {"R_PPC_ADDR16_LO", Const, 0, ""}, - {"R_PPC_ADDR24", Const, 0, ""}, - {"R_PPC_ADDR32", Const, 0, ""}, - {"R_PPC_COPY", Const, 0, ""}, - {"R_PPC_DTPMOD32", Const, 0, ""}, - {"R_PPC_DTPREL16", Const, 0, ""}, - {"R_PPC_DTPREL16_HA", Const, 0, ""}, - {"R_PPC_DTPREL16_HI", Const, 0, ""}, - {"R_PPC_DTPREL16_LO", Const, 0, ""}, - {"R_PPC_DTPREL32", Const, 0, ""}, - {"R_PPC_EMB_BIT_FLD", Const, 0, ""}, - {"R_PPC_EMB_MRKREF", Const, 0, ""}, - {"R_PPC_EMB_NADDR16", Const, 0, ""}, - {"R_PPC_EMB_NADDR16_HA", Const, 0, ""}, - {"R_PPC_EMB_NADDR16_HI", Const, 0, ""}, - {"R_PPC_EMB_NADDR16_LO", Const, 0, ""}, - {"R_PPC_EMB_NADDR32", Const, 0, ""}, - {"R_PPC_EMB_RELSDA", Const, 0, ""}, - {"R_PPC_EMB_RELSEC16", Const, 0, ""}, - {"R_PPC_EMB_RELST_HA", Const, 0, ""}, - {"R_PPC_EMB_RELST_HI", Const, 0, ""}, - {"R_PPC_EMB_RELST_LO", Const, 0, ""}, - {"R_PPC_EMB_SDA21", Const, 0, ""}, - {"R_PPC_EMB_SDA2I16", Const, 0, ""}, - {"R_PPC_EMB_SDA2REL", Const, 0, ""}, - {"R_PPC_EMB_SDAI16", Const, 0, ""}, - {"R_PPC_GLOB_DAT", Const, 0, ""}, - {"R_PPC_GOT16", Const, 0, ""}, - {"R_PPC_GOT16_HA", Const, 0, ""}, - {"R_PPC_GOT16_HI", Const, 0, ""}, - {"R_PPC_GOT16_LO", Const, 0, ""}, - {"R_PPC_GOT_TLSGD16", Const, 0, ""}, - {"R_PPC_GOT_TLSGD16_HA", Const, 0, ""}, - {"R_PPC_GOT_TLSGD16_HI", Const, 0, ""}, - {"R_PPC_GOT_TLSGD16_LO", Const, 0, ""}, - {"R_PPC_GOT_TLSLD16", Const, 0, ""}, - {"R_PPC_GOT_TLSLD16_HA", Const, 0, ""}, - {"R_PPC_GOT_TLSLD16_HI", Const, 0, ""}, - {"R_PPC_GOT_TLSLD16_LO", Const, 0, ""}, - {"R_PPC_GOT_TPREL16", Const, 0, ""}, - {"R_PPC_GOT_TPREL16_HA", Const, 0, ""}, - {"R_PPC_GOT_TPREL16_HI", Const, 0, ""}, - {"R_PPC_GOT_TPREL16_LO", Const, 0, ""}, - {"R_PPC_JMP_SLOT", Const, 0, ""}, - {"R_PPC_LOCAL24PC", Const, 0, ""}, - {"R_PPC_NONE", Const, 0, ""}, - {"R_PPC_PLT16_HA", Const, 0, ""}, - {"R_PPC_PLT16_HI", Const, 0, ""}, - {"R_PPC_PLT16_LO", Const, 0, ""}, - {"R_PPC_PLT32", Const, 0, ""}, - {"R_PPC_PLTREL24", Const, 0, ""}, - {"R_PPC_PLTREL32", Const, 0, ""}, - {"R_PPC_REL14", Const, 0, ""}, - {"R_PPC_REL14_BRNTAKEN", Const, 0, ""}, - {"R_PPC_REL14_BRTAKEN", Const, 0, ""}, - {"R_PPC_REL24", Const, 0, ""}, - {"R_PPC_REL32", Const, 0, ""}, - {"R_PPC_RELATIVE", Const, 0, ""}, - {"R_PPC_SDAREL16", Const, 0, ""}, - {"R_PPC_SECTOFF", Const, 0, ""}, - {"R_PPC_SECTOFF_HA", Const, 0, ""}, - {"R_PPC_SECTOFF_HI", Const, 0, ""}, - {"R_PPC_SECTOFF_LO", Const, 0, ""}, - {"R_PPC_TLS", Const, 0, ""}, - {"R_PPC_TPREL16", Const, 0, ""}, - {"R_PPC_TPREL16_HA", Const, 0, ""}, - {"R_PPC_TPREL16_HI", Const, 0, ""}, - {"R_PPC_TPREL16_LO", Const, 0, ""}, - {"R_PPC_TPREL32", Const, 0, ""}, - {"R_PPC_UADDR16", Const, 0, ""}, - {"R_PPC_UADDR32", Const, 0, ""}, - {"R_RISCV", Type, 11, ""}, - {"R_RISCV_32", Const, 11, ""}, - {"R_RISCV_32_PCREL", Const, 12, ""}, - {"R_RISCV_64", Const, 11, ""}, - {"R_RISCV_ADD16", Const, 11, ""}, - {"R_RISCV_ADD32", Const, 11, ""}, - {"R_RISCV_ADD64", Const, 11, ""}, - {"R_RISCV_ADD8", Const, 11, ""}, - {"R_RISCV_ALIGN", Const, 11, ""}, - {"R_RISCV_BRANCH", Const, 11, ""}, - {"R_RISCV_CALL", Const, 11, ""}, - {"R_RISCV_CALL_PLT", Const, 11, ""}, - {"R_RISCV_COPY", Const, 11, ""}, - {"R_RISCV_GNU_VTENTRY", Const, 11, ""}, - {"R_RISCV_GNU_VTINHERIT", Const, 11, ""}, - {"R_RISCV_GOT_HI20", Const, 11, ""}, - {"R_RISCV_GPREL_I", Const, 11, ""}, - {"R_RISCV_GPREL_S", Const, 11, ""}, - {"R_RISCV_HI20", Const, 11, ""}, - {"R_RISCV_JAL", Const, 11, ""}, - {"R_RISCV_JUMP_SLOT", Const, 11, ""}, - {"R_RISCV_LO12_I", Const, 11, ""}, - {"R_RISCV_LO12_S", Const, 11, ""}, - {"R_RISCV_NONE", Const, 11, ""}, - {"R_RISCV_PCREL_HI20", Const, 11, ""}, - {"R_RISCV_PCREL_LO12_I", Const, 11, ""}, - {"R_RISCV_PCREL_LO12_S", Const, 11, ""}, - {"R_RISCV_RELATIVE", Const, 11, ""}, - {"R_RISCV_RELAX", Const, 11, ""}, - {"R_RISCV_RVC_BRANCH", Const, 11, ""}, - {"R_RISCV_RVC_JUMP", Const, 11, ""}, - {"R_RISCV_RVC_LUI", Const, 11, ""}, - {"R_RISCV_SET16", Const, 11, ""}, - {"R_RISCV_SET32", Const, 11, ""}, - {"R_RISCV_SET6", Const, 11, ""}, - {"R_RISCV_SET8", Const, 11, ""}, - {"R_RISCV_SUB16", Const, 11, ""}, - {"R_RISCV_SUB32", Const, 11, ""}, - {"R_RISCV_SUB6", Const, 11, ""}, - {"R_RISCV_SUB64", Const, 11, ""}, - {"R_RISCV_SUB8", Const, 11, ""}, - {"R_RISCV_TLS_DTPMOD32", Const, 11, ""}, - {"R_RISCV_TLS_DTPMOD64", Const, 11, ""}, - {"R_RISCV_TLS_DTPREL32", Const, 11, ""}, - {"R_RISCV_TLS_DTPREL64", Const, 11, ""}, - {"R_RISCV_TLS_GD_HI20", Const, 11, ""}, - {"R_RISCV_TLS_GOT_HI20", Const, 11, ""}, - {"R_RISCV_TLS_TPREL32", Const, 11, ""}, - {"R_RISCV_TLS_TPREL64", Const, 11, ""}, - {"R_RISCV_TPREL_ADD", Const, 11, ""}, - {"R_RISCV_TPREL_HI20", Const, 11, ""}, - {"R_RISCV_TPREL_I", Const, 11, ""}, - {"R_RISCV_TPREL_LO12_I", Const, 11, ""}, - {"R_RISCV_TPREL_LO12_S", Const, 11, ""}, - {"R_RISCV_TPREL_S", Const, 11, ""}, - {"R_SPARC", Type, 0, ""}, - {"R_SPARC_10", Const, 0, ""}, - {"R_SPARC_11", Const, 0, ""}, - {"R_SPARC_13", Const, 0, ""}, - {"R_SPARC_16", Const, 0, ""}, - {"R_SPARC_22", Const, 0, ""}, - {"R_SPARC_32", Const, 0, ""}, - {"R_SPARC_5", Const, 0, ""}, - {"R_SPARC_6", Const, 0, ""}, - {"R_SPARC_64", Const, 0, ""}, - {"R_SPARC_7", Const, 0, ""}, - {"R_SPARC_8", Const, 0, ""}, - {"R_SPARC_COPY", Const, 0, ""}, - {"R_SPARC_DISP16", Const, 0, ""}, - {"R_SPARC_DISP32", Const, 0, ""}, - {"R_SPARC_DISP64", Const, 0, ""}, - {"R_SPARC_DISP8", Const, 0, ""}, - {"R_SPARC_GLOB_DAT", Const, 0, ""}, - {"R_SPARC_GLOB_JMP", Const, 0, ""}, - {"R_SPARC_GOT10", Const, 0, ""}, - {"R_SPARC_GOT13", Const, 0, ""}, - {"R_SPARC_GOT22", Const, 0, ""}, - {"R_SPARC_H44", Const, 0, ""}, - {"R_SPARC_HH22", Const, 0, ""}, - {"R_SPARC_HI22", Const, 0, ""}, - {"R_SPARC_HIPLT22", Const, 0, ""}, - {"R_SPARC_HIX22", Const, 0, ""}, - {"R_SPARC_HM10", Const, 0, ""}, - {"R_SPARC_JMP_SLOT", Const, 0, ""}, - {"R_SPARC_L44", Const, 0, ""}, - {"R_SPARC_LM22", Const, 0, ""}, - {"R_SPARC_LO10", Const, 0, ""}, - {"R_SPARC_LOPLT10", Const, 0, ""}, - {"R_SPARC_LOX10", Const, 0, ""}, - {"R_SPARC_M44", Const, 0, ""}, - {"R_SPARC_NONE", Const, 0, ""}, - {"R_SPARC_OLO10", Const, 0, ""}, - {"R_SPARC_PC10", Const, 0, ""}, - {"R_SPARC_PC22", Const, 0, ""}, - {"R_SPARC_PCPLT10", Const, 0, ""}, - {"R_SPARC_PCPLT22", Const, 0, ""}, - {"R_SPARC_PCPLT32", Const, 0, ""}, - {"R_SPARC_PC_HH22", Const, 0, ""}, - {"R_SPARC_PC_HM10", Const, 0, ""}, - {"R_SPARC_PC_LM22", Const, 0, ""}, - {"R_SPARC_PLT32", Const, 0, ""}, - {"R_SPARC_PLT64", Const, 0, ""}, - {"R_SPARC_REGISTER", Const, 0, ""}, - {"R_SPARC_RELATIVE", Const, 0, ""}, - {"R_SPARC_UA16", Const, 0, ""}, - {"R_SPARC_UA32", Const, 0, ""}, - {"R_SPARC_UA64", Const, 0, ""}, - {"R_SPARC_WDISP16", Const, 0, ""}, - {"R_SPARC_WDISP19", Const, 0, ""}, - {"R_SPARC_WDISP22", Const, 0, ""}, - {"R_SPARC_WDISP30", Const, 0, ""}, - {"R_SPARC_WPLT30", Const, 0, ""}, - {"R_SYM32", Func, 0, "func(info uint32) uint32"}, - {"R_SYM64", Func, 0, "func(info uint64) uint32"}, - {"R_TYPE32", Func, 0, "func(info uint32) uint32"}, - {"R_TYPE64", Func, 0, "func(info uint64) uint32"}, - {"R_X86_64", Type, 0, ""}, - {"R_X86_64_16", Const, 0, ""}, - {"R_X86_64_32", Const, 0, ""}, - {"R_X86_64_32S", Const, 0, ""}, - {"R_X86_64_64", Const, 0, ""}, - {"R_X86_64_8", Const, 0, ""}, - {"R_X86_64_COPY", Const, 0, ""}, - {"R_X86_64_DTPMOD64", Const, 0, ""}, - {"R_X86_64_DTPOFF32", Const, 0, ""}, - {"R_X86_64_DTPOFF64", Const, 0, ""}, - {"R_X86_64_GLOB_DAT", Const, 0, ""}, - {"R_X86_64_GOT32", Const, 0, ""}, - {"R_X86_64_GOT64", Const, 10, ""}, - {"R_X86_64_GOTOFF64", Const, 10, ""}, - {"R_X86_64_GOTPC32", Const, 10, ""}, - {"R_X86_64_GOTPC32_TLSDESC", Const, 10, ""}, - {"R_X86_64_GOTPC64", Const, 10, ""}, - {"R_X86_64_GOTPCREL", Const, 0, ""}, - {"R_X86_64_GOTPCREL64", Const, 10, ""}, - {"R_X86_64_GOTPCRELX", Const, 10, ""}, - {"R_X86_64_GOTPLT64", Const, 10, ""}, - {"R_X86_64_GOTTPOFF", Const, 0, ""}, - {"R_X86_64_IRELATIVE", Const, 10, ""}, - {"R_X86_64_JMP_SLOT", Const, 0, ""}, - {"R_X86_64_NONE", Const, 0, ""}, - {"R_X86_64_PC16", Const, 0, ""}, - {"R_X86_64_PC32", Const, 0, ""}, - {"R_X86_64_PC32_BND", Const, 10, ""}, - {"R_X86_64_PC64", Const, 10, ""}, - {"R_X86_64_PC8", Const, 0, ""}, - {"R_X86_64_PLT32", Const, 0, ""}, - {"R_X86_64_PLT32_BND", Const, 10, ""}, - {"R_X86_64_PLTOFF64", Const, 10, ""}, - {"R_X86_64_RELATIVE", Const, 0, ""}, - {"R_X86_64_RELATIVE64", Const, 10, ""}, - {"R_X86_64_REX_GOTPCRELX", Const, 10, ""}, - {"R_X86_64_SIZE32", Const, 10, ""}, - {"R_X86_64_SIZE64", Const, 10, ""}, - {"R_X86_64_TLSDESC", Const, 10, ""}, - {"R_X86_64_TLSDESC_CALL", Const, 10, ""}, - {"R_X86_64_TLSGD", Const, 0, ""}, - {"R_X86_64_TLSLD", Const, 0, ""}, - {"R_X86_64_TPOFF32", Const, 0, ""}, - {"R_X86_64_TPOFF64", Const, 0, ""}, - {"Rel32", Type, 0, ""}, - {"Rel32.Info", Field, 0, ""}, - {"Rel32.Off", Field, 0, ""}, - {"Rel64", Type, 0, ""}, - {"Rel64.Info", Field, 0, ""}, - {"Rel64.Off", Field, 0, ""}, - {"Rela32", Type, 0, ""}, - {"Rela32.Addend", Field, 0, ""}, - {"Rela32.Info", Field, 0, ""}, - {"Rela32.Off", Field, 0, ""}, - {"Rela64", Type, 0, ""}, - {"Rela64.Addend", Field, 0, ""}, - {"Rela64.Info", Field, 0, ""}, - {"Rela64.Off", Field, 0, ""}, - {"SHF_ALLOC", Const, 0, ""}, - {"SHF_COMPRESSED", Const, 6, ""}, - {"SHF_EXECINSTR", Const, 0, ""}, - {"SHF_GROUP", Const, 0, ""}, - {"SHF_INFO_LINK", Const, 0, ""}, - {"SHF_LINK_ORDER", Const, 0, ""}, - {"SHF_MASKOS", Const, 0, ""}, - {"SHF_MASKPROC", Const, 0, ""}, - {"SHF_MERGE", Const, 0, ""}, - {"SHF_OS_NONCONFORMING", Const, 0, ""}, - {"SHF_STRINGS", Const, 0, ""}, - {"SHF_TLS", Const, 0, ""}, - {"SHF_WRITE", Const, 0, ""}, - {"SHN_ABS", Const, 0, ""}, - {"SHN_COMMON", Const, 0, ""}, - {"SHN_HIOS", Const, 0, ""}, - {"SHN_HIPROC", Const, 0, ""}, - {"SHN_HIRESERVE", Const, 0, ""}, - {"SHN_LOOS", Const, 0, ""}, - {"SHN_LOPROC", Const, 0, ""}, - {"SHN_LORESERVE", Const, 0, ""}, - {"SHN_UNDEF", Const, 0, ""}, - {"SHN_XINDEX", Const, 0, ""}, - {"SHT_DYNAMIC", Const, 0, ""}, - {"SHT_DYNSYM", Const, 0, ""}, - {"SHT_FINI_ARRAY", Const, 0, ""}, - {"SHT_GNU_ATTRIBUTES", Const, 0, ""}, - {"SHT_GNU_HASH", Const, 0, ""}, - {"SHT_GNU_LIBLIST", Const, 0, ""}, - {"SHT_GNU_VERDEF", Const, 0, ""}, - {"SHT_GNU_VERNEED", Const, 0, ""}, - {"SHT_GNU_VERSYM", Const, 0, ""}, - {"SHT_GROUP", Const, 0, ""}, - {"SHT_HASH", Const, 0, ""}, - {"SHT_HIOS", Const, 0, ""}, - {"SHT_HIPROC", Const, 0, ""}, - {"SHT_HIUSER", Const, 0, ""}, - {"SHT_INIT_ARRAY", Const, 0, ""}, - {"SHT_LOOS", Const, 0, ""}, - {"SHT_LOPROC", Const, 0, ""}, - {"SHT_LOUSER", Const, 0, ""}, - {"SHT_MIPS_ABIFLAGS", Const, 17, ""}, - {"SHT_NOBITS", Const, 0, ""}, - {"SHT_NOTE", Const, 0, ""}, - {"SHT_NULL", Const, 0, ""}, - {"SHT_PREINIT_ARRAY", Const, 0, ""}, - {"SHT_PROGBITS", Const, 0, ""}, - {"SHT_REL", Const, 0, ""}, - {"SHT_RELA", Const, 0, ""}, - {"SHT_RISCV_ATTRIBUTES", Const, 25, ""}, - {"SHT_SHLIB", Const, 0, ""}, - {"SHT_STRTAB", Const, 0, ""}, - {"SHT_SYMTAB", Const, 0, ""}, - {"SHT_SYMTAB_SHNDX", Const, 0, ""}, - {"STB_GLOBAL", Const, 0, ""}, - {"STB_HIOS", Const, 0, ""}, - {"STB_HIPROC", Const, 0, ""}, - {"STB_LOCAL", Const, 0, ""}, - {"STB_LOOS", Const, 0, ""}, - {"STB_LOPROC", Const, 0, ""}, - {"STB_WEAK", Const, 0, ""}, - {"STT_COMMON", Const, 0, ""}, - {"STT_FILE", Const, 0, ""}, - {"STT_FUNC", Const, 0, ""}, - {"STT_GNU_IFUNC", Const, 23, ""}, - {"STT_HIOS", Const, 0, ""}, - {"STT_HIPROC", Const, 0, ""}, - {"STT_LOOS", Const, 0, ""}, - {"STT_LOPROC", Const, 0, ""}, - {"STT_NOTYPE", Const, 0, ""}, - {"STT_OBJECT", Const, 0, ""}, - {"STT_RELC", Const, 23, ""}, - {"STT_SECTION", Const, 0, ""}, - {"STT_SRELC", Const, 23, ""}, - {"STT_TLS", Const, 0, ""}, - {"STV_DEFAULT", Const, 0, ""}, - {"STV_HIDDEN", Const, 0, ""}, - {"STV_INTERNAL", Const, 0, ""}, - {"STV_PROTECTED", Const, 0, ""}, - {"ST_BIND", Func, 0, "func(info uint8) SymBind"}, - {"ST_INFO", Func, 0, "func(bind SymBind, typ SymType) uint8"}, - {"ST_TYPE", Func, 0, "func(info uint8) SymType"}, - {"ST_VISIBILITY", Func, 0, "func(other uint8) SymVis"}, - {"Section", Type, 0, ""}, - {"Section.ReaderAt", Field, 0, ""}, - {"Section.SectionHeader", Field, 0, ""}, - {"Section32", Type, 0, ""}, - {"Section32.Addr", Field, 0, ""}, - {"Section32.Addralign", Field, 0, ""}, - {"Section32.Entsize", Field, 0, ""}, - {"Section32.Flags", Field, 0, ""}, - {"Section32.Info", Field, 0, ""}, - {"Section32.Link", Field, 0, ""}, - {"Section32.Name", Field, 0, ""}, - {"Section32.Off", Field, 0, ""}, - {"Section32.Size", Field, 0, ""}, - {"Section32.Type", Field, 0, ""}, - {"Section64", Type, 0, ""}, - {"Section64.Addr", Field, 0, ""}, - {"Section64.Addralign", Field, 0, ""}, - {"Section64.Entsize", Field, 0, ""}, - {"Section64.Flags", Field, 0, ""}, - {"Section64.Info", Field, 0, ""}, - {"Section64.Link", Field, 0, ""}, - {"Section64.Name", Field, 0, ""}, - {"Section64.Off", Field, 0, ""}, - {"Section64.Size", Field, 0, ""}, - {"Section64.Type", Field, 0, ""}, - {"SectionFlag", Type, 0, ""}, - {"SectionHeader", Type, 0, ""}, - {"SectionHeader.Addr", Field, 0, ""}, - {"SectionHeader.Addralign", Field, 0, ""}, - {"SectionHeader.Entsize", Field, 0, ""}, - {"SectionHeader.FileSize", Field, 6, ""}, - {"SectionHeader.Flags", Field, 0, ""}, - {"SectionHeader.Info", Field, 0, ""}, - {"SectionHeader.Link", Field, 0, ""}, - {"SectionHeader.Name", Field, 0, ""}, - {"SectionHeader.Offset", Field, 0, ""}, - {"SectionHeader.Size", Field, 0, ""}, - {"SectionHeader.Type", Field, 0, ""}, - {"SectionIndex", Type, 0, ""}, - {"SectionType", Type, 0, ""}, - {"Sym32", Type, 0, ""}, - {"Sym32.Info", Field, 0, ""}, - {"Sym32.Name", Field, 0, ""}, - {"Sym32.Other", Field, 0, ""}, - {"Sym32.Shndx", Field, 0, ""}, - {"Sym32.Size", Field, 0, ""}, - {"Sym32.Value", Field, 0, ""}, - {"Sym32Size", Const, 0, ""}, - {"Sym64", Type, 0, ""}, - {"Sym64.Info", Field, 0, ""}, - {"Sym64.Name", Field, 0, ""}, - {"Sym64.Other", Field, 0, ""}, - {"Sym64.Shndx", Field, 0, ""}, - {"Sym64.Size", Field, 0, ""}, - {"Sym64.Value", Field, 0, ""}, - {"Sym64Size", Const, 0, ""}, - {"SymBind", Type, 0, ""}, - {"SymType", Type, 0, ""}, - {"SymVis", Type, 0, ""}, - {"Symbol", Type, 0, ""}, - {"Symbol.HasVersion", Field, 24, ""}, - {"Symbol.Info", Field, 0, ""}, - {"Symbol.Library", Field, 13, ""}, - {"Symbol.Name", Field, 0, ""}, - {"Symbol.Other", Field, 0, ""}, - {"Symbol.Section", Field, 0, ""}, - {"Symbol.Size", Field, 0, ""}, - {"Symbol.Value", Field, 0, ""}, - {"Symbol.Version", Field, 13, ""}, - {"Symbol.VersionIndex", Field, 24, ""}, - {"Type", Type, 0, ""}, - {"VER_FLG_BASE", Const, 24, ""}, - {"VER_FLG_INFO", Const, 24, ""}, - {"VER_FLG_WEAK", Const, 24, ""}, - {"Version", Type, 0, ""}, - {"VersionIndex", Type, 24, ""}, - }, - "debug/gosym": { - {"(*DecodingError).Error", Method, 0, ""}, - {"(*LineTable).LineToPC", Method, 0, ""}, - {"(*LineTable).PCToLine", Method, 0, ""}, - {"(*Sym).BaseName", Method, 0, ""}, - {"(*Sym).PackageName", Method, 0, ""}, - {"(*Sym).ReceiverName", Method, 0, ""}, - {"(*Sym).Static", Method, 0, ""}, - {"(*Table).LineToPC", Method, 0, ""}, - {"(*Table).LookupFunc", Method, 0, ""}, - {"(*Table).LookupSym", Method, 0, ""}, - {"(*Table).PCToFunc", Method, 0, ""}, - {"(*Table).PCToLine", Method, 0, ""}, - {"(*Table).SymByAddr", Method, 0, ""}, - {"(*UnknownLineError).Error", Method, 0, ""}, - {"(Func).BaseName", Method, 0, ""}, - {"(Func).PackageName", Method, 0, ""}, - {"(Func).ReceiverName", Method, 0, ""}, - {"(Func).Static", Method, 0, ""}, - {"(UnknownFileError).Error", Method, 0, ""}, - {"DecodingError", Type, 0, ""}, - {"Func", Type, 0, ""}, - {"Func.End", Field, 0, ""}, - {"Func.Entry", Field, 0, ""}, - {"Func.FrameSize", Field, 0, ""}, - {"Func.LineTable", Field, 0, ""}, - {"Func.Locals", Field, 0, ""}, - {"Func.Obj", Field, 0, ""}, - {"Func.Params", Field, 0, ""}, - {"Func.Sym", Field, 0, ""}, - {"LineTable", Type, 0, ""}, - {"LineTable.Data", Field, 0, ""}, - {"LineTable.Line", Field, 0, ""}, - {"LineTable.PC", Field, 0, ""}, - {"NewLineTable", Func, 0, "func(data []byte, text uint64) *LineTable"}, - {"NewTable", Func, 0, "func(symtab []byte, pcln *LineTable) (*Table, error)"}, - {"Obj", Type, 0, ""}, - {"Obj.Funcs", Field, 0, ""}, - {"Obj.Paths", Field, 0, ""}, - {"Sym", Type, 0, ""}, - {"Sym.Func", Field, 0, ""}, - {"Sym.GoType", Field, 0, ""}, - {"Sym.Name", Field, 0, ""}, - {"Sym.Type", Field, 0, ""}, - {"Sym.Value", Field, 0, ""}, - {"Table", Type, 0, ""}, - {"Table.Files", Field, 0, ""}, - {"Table.Funcs", Field, 0, ""}, - {"Table.Objs", Field, 0, ""}, - {"Table.Syms", Field, 0, ""}, - {"UnknownFileError", Type, 0, ""}, - {"UnknownLineError", Type, 0, ""}, - {"UnknownLineError.File", Field, 0, ""}, - {"UnknownLineError.Line", Field, 0, ""}, - }, - "debug/macho": { - {"(*FatFile).Close", Method, 3, ""}, - {"(*File).Close", Method, 0, ""}, - {"(*File).DWARF", Method, 0, ""}, - {"(*File).ImportedLibraries", Method, 0, ""}, - {"(*File).ImportedSymbols", Method, 0, ""}, - {"(*File).Section", Method, 0, ""}, - {"(*File).Segment", Method, 0, ""}, - {"(*FormatError).Error", Method, 0, ""}, - {"(*Section).Data", Method, 0, ""}, - {"(*Section).Open", Method, 0, ""}, - {"(*Segment).Data", Method, 0, ""}, - {"(*Segment).Open", Method, 0, ""}, - {"(Cpu).GoString", Method, 0, ""}, - {"(Cpu).String", Method, 0, ""}, - {"(Dylib).Raw", Method, 0, ""}, - {"(Dysymtab).Raw", Method, 0, ""}, - {"(FatArch).Close", Method, 3, ""}, - {"(FatArch).DWARF", Method, 3, ""}, - {"(FatArch).ImportedLibraries", Method, 3, ""}, - {"(FatArch).ImportedSymbols", Method, 3, ""}, - {"(FatArch).Section", Method, 3, ""}, - {"(FatArch).Segment", Method, 3, ""}, - {"(Load).Raw", Method, 0, ""}, - {"(LoadBytes).Raw", Method, 0, ""}, - {"(LoadCmd).GoString", Method, 0, ""}, - {"(LoadCmd).String", Method, 0, ""}, - {"(RelocTypeARM).GoString", Method, 10, ""}, - {"(RelocTypeARM).String", Method, 10, ""}, - {"(RelocTypeARM64).GoString", Method, 10, ""}, - {"(RelocTypeARM64).String", Method, 10, ""}, - {"(RelocTypeGeneric).GoString", Method, 10, ""}, - {"(RelocTypeGeneric).String", Method, 10, ""}, - {"(RelocTypeX86_64).GoString", Method, 10, ""}, - {"(RelocTypeX86_64).String", Method, 10, ""}, - {"(Rpath).Raw", Method, 10, ""}, - {"(Section).ReadAt", Method, 0, ""}, - {"(Segment).Raw", Method, 0, ""}, - {"(Segment).ReadAt", Method, 0, ""}, - {"(Symtab).Raw", Method, 0, ""}, - {"(Type).GoString", Method, 10, ""}, - {"(Type).String", Method, 10, ""}, - {"ARM64_RELOC_ADDEND", Const, 10, ""}, - {"ARM64_RELOC_BRANCH26", Const, 10, ""}, - {"ARM64_RELOC_GOT_LOAD_PAGE21", Const, 10, ""}, - {"ARM64_RELOC_GOT_LOAD_PAGEOFF12", Const, 10, ""}, - {"ARM64_RELOC_PAGE21", Const, 10, ""}, - {"ARM64_RELOC_PAGEOFF12", Const, 10, ""}, - {"ARM64_RELOC_POINTER_TO_GOT", Const, 10, ""}, - {"ARM64_RELOC_SUBTRACTOR", Const, 10, ""}, - {"ARM64_RELOC_TLVP_LOAD_PAGE21", Const, 10, ""}, - {"ARM64_RELOC_TLVP_LOAD_PAGEOFF12", Const, 10, ""}, - {"ARM64_RELOC_UNSIGNED", Const, 10, ""}, - {"ARM_RELOC_BR24", Const, 10, ""}, - {"ARM_RELOC_HALF", Const, 10, ""}, - {"ARM_RELOC_HALF_SECTDIFF", Const, 10, ""}, - {"ARM_RELOC_LOCAL_SECTDIFF", Const, 10, ""}, - {"ARM_RELOC_PAIR", Const, 10, ""}, - {"ARM_RELOC_PB_LA_PTR", Const, 10, ""}, - {"ARM_RELOC_SECTDIFF", Const, 10, ""}, - {"ARM_RELOC_VANILLA", Const, 10, ""}, - {"ARM_THUMB_32BIT_BRANCH", Const, 10, ""}, - {"ARM_THUMB_RELOC_BR22", Const, 10, ""}, - {"Cpu", Type, 0, ""}, - {"Cpu386", Const, 0, ""}, - {"CpuAmd64", Const, 0, ""}, - {"CpuArm", Const, 3, ""}, - {"CpuArm64", Const, 11, ""}, - {"CpuPpc", Const, 3, ""}, - {"CpuPpc64", Const, 3, ""}, - {"Dylib", Type, 0, ""}, - {"Dylib.CompatVersion", Field, 0, ""}, - {"Dylib.CurrentVersion", Field, 0, ""}, - {"Dylib.LoadBytes", Field, 0, ""}, - {"Dylib.Name", Field, 0, ""}, - {"Dylib.Time", Field, 0, ""}, - {"DylibCmd", Type, 0, ""}, - {"DylibCmd.Cmd", Field, 0, ""}, - {"DylibCmd.CompatVersion", Field, 0, ""}, - {"DylibCmd.CurrentVersion", Field, 0, ""}, - {"DylibCmd.Len", Field, 0, ""}, - {"DylibCmd.Name", Field, 0, ""}, - {"DylibCmd.Time", Field, 0, ""}, - {"Dysymtab", Type, 0, ""}, - {"Dysymtab.DysymtabCmd", Field, 0, ""}, - {"Dysymtab.IndirectSyms", Field, 0, ""}, - {"Dysymtab.LoadBytes", Field, 0, ""}, - {"DysymtabCmd", Type, 0, ""}, - {"DysymtabCmd.Cmd", Field, 0, ""}, - {"DysymtabCmd.Extrefsymoff", Field, 0, ""}, - {"DysymtabCmd.Extreloff", Field, 0, ""}, - {"DysymtabCmd.Iextdefsym", Field, 0, ""}, - {"DysymtabCmd.Ilocalsym", Field, 0, ""}, - {"DysymtabCmd.Indirectsymoff", Field, 0, ""}, - {"DysymtabCmd.Iundefsym", Field, 0, ""}, - {"DysymtabCmd.Len", Field, 0, ""}, - {"DysymtabCmd.Locreloff", Field, 0, ""}, - {"DysymtabCmd.Modtaboff", Field, 0, ""}, - {"DysymtabCmd.Nextdefsym", Field, 0, ""}, - {"DysymtabCmd.Nextrefsyms", Field, 0, ""}, - {"DysymtabCmd.Nextrel", Field, 0, ""}, - {"DysymtabCmd.Nindirectsyms", Field, 0, ""}, - {"DysymtabCmd.Nlocalsym", Field, 0, ""}, - {"DysymtabCmd.Nlocrel", Field, 0, ""}, - {"DysymtabCmd.Nmodtab", Field, 0, ""}, - {"DysymtabCmd.Ntoc", Field, 0, ""}, - {"DysymtabCmd.Nundefsym", Field, 0, ""}, - {"DysymtabCmd.Tocoffset", Field, 0, ""}, - {"ErrNotFat", Var, 3, ""}, - {"FatArch", Type, 3, ""}, - {"FatArch.FatArchHeader", Field, 3, ""}, - {"FatArch.File", Field, 3, ""}, - {"FatArchHeader", Type, 3, ""}, - {"FatArchHeader.Align", Field, 3, ""}, - {"FatArchHeader.Cpu", Field, 3, ""}, - {"FatArchHeader.Offset", Field, 3, ""}, - {"FatArchHeader.Size", Field, 3, ""}, - {"FatArchHeader.SubCpu", Field, 3, ""}, - {"FatFile", Type, 3, ""}, - {"FatFile.Arches", Field, 3, ""}, - {"FatFile.Magic", Field, 3, ""}, - {"File", Type, 0, ""}, - {"File.ByteOrder", Field, 0, ""}, - {"File.Dysymtab", Field, 0, ""}, - {"File.FileHeader", Field, 0, ""}, - {"File.Loads", Field, 0, ""}, - {"File.Sections", Field, 0, ""}, - {"File.Symtab", Field, 0, ""}, - {"FileHeader", Type, 0, ""}, - {"FileHeader.Cmdsz", Field, 0, ""}, - {"FileHeader.Cpu", Field, 0, ""}, - {"FileHeader.Flags", Field, 0, ""}, - {"FileHeader.Magic", Field, 0, ""}, - {"FileHeader.Ncmd", Field, 0, ""}, - {"FileHeader.SubCpu", Field, 0, ""}, - {"FileHeader.Type", Field, 0, ""}, - {"FlagAllModsBound", Const, 10, ""}, - {"FlagAllowStackExecution", Const, 10, ""}, - {"FlagAppExtensionSafe", Const, 10, ""}, - {"FlagBindAtLoad", Const, 10, ""}, - {"FlagBindsToWeak", Const, 10, ""}, - {"FlagCanonical", Const, 10, ""}, - {"FlagDeadStrippableDylib", Const, 10, ""}, - {"FlagDyldLink", Const, 10, ""}, - {"FlagForceFlat", Const, 10, ""}, - {"FlagHasTLVDescriptors", Const, 10, ""}, - {"FlagIncrLink", Const, 10, ""}, - {"FlagLazyInit", Const, 10, ""}, - {"FlagNoFixPrebinding", Const, 10, ""}, - {"FlagNoHeapExecution", Const, 10, ""}, - {"FlagNoMultiDefs", Const, 10, ""}, - {"FlagNoReexportedDylibs", Const, 10, ""}, - {"FlagNoUndefs", Const, 10, ""}, - {"FlagPIE", Const, 10, ""}, - {"FlagPrebindable", Const, 10, ""}, - {"FlagPrebound", Const, 10, ""}, - {"FlagRootSafe", Const, 10, ""}, - {"FlagSetuidSafe", Const, 10, ""}, - {"FlagSplitSegs", Const, 10, ""}, - {"FlagSubsectionsViaSymbols", Const, 10, ""}, - {"FlagTwoLevel", Const, 10, ""}, - {"FlagWeakDefines", Const, 10, ""}, - {"FormatError", Type, 0, ""}, - {"GENERIC_RELOC_LOCAL_SECTDIFF", Const, 10, ""}, - {"GENERIC_RELOC_PAIR", Const, 10, ""}, - {"GENERIC_RELOC_PB_LA_PTR", Const, 10, ""}, - {"GENERIC_RELOC_SECTDIFF", Const, 10, ""}, - {"GENERIC_RELOC_TLV", Const, 10, ""}, - {"GENERIC_RELOC_VANILLA", Const, 10, ""}, - {"Load", Type, 0, ""}, - {"LoadBytes", Type, 0, ""}, - {"LoadCmd", Type, 0, ""}, - {"LoadCmdDylib", Const, 0, ""}, - {"LoadCmdDylinker", Const, 0, ""}, - {"LoadCmdDysymtab", Const, 0, ""}, - {"LoadCmdRpath", Const, 10, ""}, - {"LoadCmdSegment", Const, 0, ""}, - {"LoadCmdSegment64", Const, 0, ""}, - {"LoadCmdSymtab", Const, 0, ""}, - {"LoadCmdThread", Const, 0, ""}, - {"LoadCmdUnixThread", Const, 0, ""}, - {"Magic32", Const, 0, ""}, - {"Magic64", Const, 0, ""}, - {"MagicFat", Const, 3, ""}, - {"NewFatFile", Func, 3, "func(r io.ReaderAt) (*FatFile, error)"}, - {"NewFile", Func, 0, "func(r io.ReaderAt) (*File, error)"}, - {"Nlist32", Type, 0, ""}, - {"Nlist32.Desc", Field, 0, ""}, - {"Nlist32.Name", Field, 0, ""}, - {"Nlist32.Sect", Field, 0, ""}, - {"Nlist32.Type", Field, 0, ""}, - {"Nlist32.Value", Field, 0, ""}, - {"Nlist64", Type, 0, ""}, - {"Nlist64.Desc", Field, 0, ""}, - {"Nlist64.Name", Field, 0, ""}, - {"Nlist64.Sect", Field, 0, ""}, - {"Nlist64.Type", Field, 0, ""}, - {"Nlist64.Value", Field, 0, ""}, - {"Open", Func, 0, "func(name string) (*File, error)"}, - {"OpenFat", Func, 3, "func(name string) (*FatFile, error)"}, - {"Regs386", Type, 0, ""}, - {"Regs386.AX", Field, 0, ""}, - {"Regs386.BP", Field, 0, ""}, - {"Regs386.BX", Field, 0, ""}, - {"Regs386.CS", Field, 0, ""}, - {"Regs386.CX", Field, 0, ""}, - {"Regs386.DI", Field, 0, ""}, - {"Regs386.DS", Field, 0, ""}, - {"Regs386.DX", Field, 0, ""}, - {"Regs386.ES", Field, 0, ""}, - {"Regs386.FLAGS", Field, 0, ""}, - {"Regs386.FS", Field, 0, ""}, - {"Regs386.GS", Field, 0, ""}, - {"Regs386.IP", Field, 0, ""}, - {"Regs386.SI", Field, 0, ""}, - {"Regs386.SP", Field, 0, ""}, - {"Regs386.SS", Field, 0, ""}, - {"RegsAMD64", Type, 0, ""}, - {"RegsAMD64.AX", Field, 0, ""}, - {"RegsAMD64.BP", Field, 0, ""}, - {"RegsAMD64.BX", Field, 0, ""}, - {"RegsAMD64.CS", Field, 0, ""}, - {"RegsAMD64.CX", Field, 0, ""}, - {"RegsAMD64.DI", Field, 0, ""}, - {"RegsAMD64.DX", Field, 0, ""}, - {"RegsAMD64.FLAGS", Field, 0, ""}, - {"RegsAMD64.FS", Field, 0, ""}, - {"RegsAMD64.GS", Field, 0, ""}, - {"RegsAMD64.IP", Field, 0, ""}, - {"RegsAMD64.R10", Field, 0, ""}, - {"RegsAMD64.R11", Field, 0, ""}, - {"RegsAMD64.R12", Field, 0, ""}, - {"RegsAMD64.R13", Field, 0, ""}, - {"RegsAMD64.R14", Field, 0, ""}, - {"RegsAMD64.R15", Field, 0, ""}, - {"RegsAMD64.R8", Field, 0, ""}, - {"RegsAMD64.R9", Field, 0, ""}, - {"RegsAMD64.SI", Field, 0, ""}, - {"RegsAMD64.SP", Field, 0, ""}, - {"Reloc", Type, 10, ""}, - {"Reloc.Addr", Field, 10, ""}, - {"Reloc.Extern", Field, 10, ""}, - {"Reloc.Len", Field, 10, ""}, - {"Reloc.Pcrel", Field, 10, ""}, - {"Reloc.Scattered", Field, 10, ""}, - {"Reloc.Type", Field, 10, ""}, - {"Reloc.Value", Field, 10, ""}, - {"RelocTypeARM", Type, 10, ""}, - {"RelocTypeARM64", Type, 10, ""}, - {"RelocTypeGeneric", Type, 10, ""}, - {"RelocTypeX86_64", Type, 10, ""}, - {"Rpath", Type, 10, ""}, - {"Rpath.LoadBytes", Field, 10, ""}, - {"Rpath.Path", Field, 10, ""}, - {"RpathCmd", Type, 10, ""}, - {"RpathCmd.Cmd", Field, 10, ""}, - {"RpathCmd.Len", Field, 10, ""}, - {"RpathCmd.Path", Field, 10, ""}, - {"Section", Type, 0, ""}, - {"Section.ReaderAt", Field, 0, ""}, - {"Section.Relocs", Field, 10, ""}, - {"Section.SectionHeader", Field, 0, ""}, - {"Section32", Type, 0, ""}, - {"Section32.Addr", Field, 0, ""}, - {"Section32.Align", Field, 0, ""}, - {"Section32.Flags", Field, 0, ""}, - {"Section32.Name", Field, 0, ""}, - {"Section32.Nreloc", Field, 0, ""}, - {"Section32.Offset", Field, 0, ""}, - {"Section32.Reloff", Field, 0, ""}, - {"Section32.Reserve1", Field, 0, ""}, - {"Section32.Reserve2", Field, 0, ""}, - {"Section32.Seg", Field, 0, ""}, - {"Section32.Size", Field, 0, ""}, - {"Section64", Type, 0, ""}, - {"Section64.Addr", Field, 0, ""}, - {"Section64.Align", Field, 0, ""}, - {"Section64.Flags", Field, 0, ""}, - {"Section64.Name", Field, 0, ""}, - {"Section64.Nreloc", Field, 0, ""}, - {"Section64.Offset", Field, 0, ""}, - {"Section64.Reloff", Field, 0, ""}, - {"Section64.Reserve1", Field, 0, ""}, - {"Section64.Reserve2", Field, 0, ""}, - {"Section64.Reserve3", Field, 0, ""}, - {"Section64.Seg", Field, 0, ""}, - {"Section64.Size", Field, 0, ""}, - {"SectionHeader", Type, 0, ""}, - {"SectionHeader.Addr", Field, 0, ""}, - {"SectionHeader.Align", Field, 0, ""}, - {"SectionHeader.Flags", Field, 0, ""}, - {"SectionHeader.Name", Field, 0, ""}, - {"SectionHeader.Nreloc", Field, 0, ""}, - {"SectionHeader.Offset", Field, 0, ""}, - {"SectionHeader.Reloff", Field, 0, ""}, - {"SectionHeader.Seg", Field, 0, ""}, - {"SectionHeader.Size", Field, 0, ""}, - {"Segment", Type, 0, ""}, - {"Segment.LoadBytes", Field, 0, ""}, - {"Segment.ReaderAt", Field, 0, ""}, - {"Segment.SegmentHeader", Field, 0, ""}, - {"Segment32", Type, 0, ""}, - {"Segment32.Addr", Field, 0, ""}, - {"Segment32.Cmd", Field, 0, ""}, - {"Segment32.Filesz", Field, 0, ""}, - {"Segment32.Flag", Field, 0, ""}, - {"Segment32.Len", Field, 0, ""}, - {"Segment32.Maxprot", Field, 0, ""}, - {"Segment32.Memsz", Field, 0, ""}, - {"Segment32.Name", Field, 0, ""}, - {"Segment32.Nsect", Field, 0, ""}, - {"Segment32.Offset", Field, 0, ""}, - {"Segment32.Prot", Field, 0, ""}, - {"Segment64", Type, 0, ""}, - {"Segment64.Addr", Field, 0, ""}, - {"Segment64.Cmd", Field, 0, ""}, - {"Segment64.Filesz", Field, 0, ""}, - {"Segment64.Flag", Field, 0, ""}, - {"Segment64.Len", Field, 0, ""}, - {"Segment64.Maxprot", Field, 0, ""}, - {"Segment64.Memsz", Field, 0, ""}, - {"Segment64.Name", Field, 0, ""}, - {"Segment64.Nsect", Field, 0, ""}, - {"Segment64.Offset", Field, 0, ""}, - {"Segment64.Prot", Field, 0, ""}, - {"SegmentHeader", Type, 0, ""}, - {"SegmentHeader.Addr", Field, 0, ""}, - {"SegmentHeader.Cmd", Field, 0, ""}, - {"SegmentHeader.Filesz", Field, 0, ""}, - {"SegmentHeader.Flag", Field, 0, ""}, - {"SegmentHeader.Len", Field, 0, ""}, - {"SegmentHeader.Maxprot", Field, 0, ""}, - {"SegmentHeader.Memsz", Field, 0, ""}, - {"SegmentHeader.Name", Field, 0, ""}, - {"SegmentHeader.Nsect", Field, 0, ""}, - {"SegmentHeader.Offset", Field, 0, ""}, - {"SegmentHeader.Prot", Field, 0, ""}, - {"Symbol", Type, 0, ""}, - {"Symbol.Desc", Field, 0, ""}, - {"Symbol.Name", Field, 0, ""}, - {"Symbol.Sect", Field, 0, ""}, - {"Symbol.Type", Field, 0, ""}, - {"Symbol.Value", Field, 0, ""}, - {"Symtab", Type, 0, ""}, - {"Symtab.LoadBytes", Field, 0, ""}, - {"Symtab.Syms", Field, 0, ""}, - {"Symtab.SymtabCmd", Field, 0, ""}, - {"SymtabCmd", Type, 0, ""}, - {"SymtabCmd.Cmd", Field, 0, ""}, - {"SymtabCmd.Len", Field, 0, ""}, - {"SymtabCmd.Nsyms", Field, 0, ""}, - {"SymtabCmd.Stroff", Field, 0, ""}, - {"SymtabCmd.Strsize", Field, 0, ""}, - {"SymtabCmd.Symoff", Field, 0, ""}, - {"Thread", Type, 0, ""}, - {"Thread.Cmd", Field, 0, ""}, - {"Thread.Data", Field, 0, ""}, - {"Thread.Len", Field, 0, ""}, - {"Thread.Type", Field, 0, ""}, - {"Type", Type, 0, ""}, - {"TypeBundle", Const, 3, ""}, - {"TypeDylib", Const, 3, ""}, - {"TypeExec", Const, 0, ""}, - {"TypeObj", Const, 0, ""}, - {"X86_64_RELOC_BRANCH", Const, 10, ""}, - {"X86_64_RELOC_GOT", Const, 10, ""}, - {"X86_64_RELOC_GOT_LOAD", Const, 10, ""}, - {"X86_64_RELOC_SIGNED", Const, 10, ""}, - {"X86_64_RELOC_SIGNED_1", Const, 10, ""}, - {"X86_64_RELOC_SIGNED_2", Const, 10, ""}, - {"X86_64_RELOC_SIGNED_4", Const, 10, ""}, - {"X86_64_RELOC_SUBTRACTOR", Const, 10, ""}, - {"X86_64_RELOC_TLV", Const, 10, ""}, - {"X86_64_RELOC_UNSIGNED", Const, 10, ""}, - }, - "debug/pe": { - {"(*COFFSymbol).FullName", Method, 8, ""}, - {"(*File).COFFSymbolReadSectionDefAux", Method, 19, ""}, - {"(*File).Close", Method, 0, ""}, - {"(*File).DWARF", Method, 0, ""}, - {"(*File).ImportedLibraries", Method, 0, ""}, - {"(*File).ImportedSymbols", Method, 0, ""}, - {"(*File).Section", Method, 0, ""}, - {"(*FormatError).Error", Method, 0, ""}, - {"(*Section).Data", Method, 0, ""}, - {"(*Section).Open", Method, 0, ""}, - {"(Section).ReadAt", Method, 0, ""}, - {"(StringTable).String", Method, 8, ""}, - {"COFFSymbol", Type, 1, ""}, - {"COFFSymbol.Name", Field, 1, ""}, - {"COFFSymbol.NumberOfAuxSymbols", Field, 1, ""}, - {"COFFSymbol.SectionNumber", Field, 1, ""}, - {"COFFSymbol.StorageClass", Field, 1, ""}, - {"COFFSymbol.Type", Field, 1, ""}, - {"COFFSymbol.Value", Field, 1, ""}, - {"COFFSymbolAuxFormat5", Type, 19, ""}, - {"COFFSymbolAuxFormat5.Checksum", Field, 19, ""}, - {"COFFSymbolAuxFormat5.NumLineNumbers", Field, 19, ""}, - {"COFFSymbolAuxFormat5.NumRelocs", Field, 19, ""}, - {"COFFSymbolAuxFormat5.SecNum", Field, 19, ""}, - {"COFFSymbolAuxFormat5.Selection", Field, 19, ""}, - {"COFFSymbolAuxFormat5.Size", Field, 19, ""}, - {"COFFSymbolSize", Const, 1, ""}, - {"DataDirectory", Type, 3, ""}, - {"DataDirectory.Size", Field, 3, ""}, - {"DataDirectory.VirtualAddress", Field, 3, ""}, - {"File", Type, 0, ""}, - {"File.COFFSymbols", Field, 8, ""}, - {"File.FileHeader", Field, 0, ""}, - {"File.OptionalHeader", Field, 3, ""}, - {"File.Sections", Field, 0, ""}, - {"File.StringTable", Field, 8, ""}, - {"File.Symbols", Field, 1, ""}, - {"FileHeader", Type, 0, ""}, - {"FileHeader.Characteristics", Field, 0, ""}, - {"FileHeader.Machine", Field, 0, ""}, - {"FileHeader.NumberOfSections", Field, 0, ""}, - {"FileHeader.NumberOfSymbols", Field, 0, ""}, - {"FileHeader.PointerToSymbolTable", Field, 0, ""}, - {"FileHeader.SizeOfOptionalHeader", Field, 0, ""}, - {"FileHeader.TimeDateStamp", Field, 0, ""}, - {"FormatError", Type, 0, ""}, - {"IMAGE_COMDAT_SELECT_ANY", Const, 19, ""}, - {"IMAGE_COMDAT_SELECT_ASSOCIATIVE", Const, 19, ""}, - {"IMAGE_COMDAT_SELECT_EXACT_MATCH", Const, 19, ""}, - {"IMAGE_COMDAT_SELECT_LARGEST", Const, 19, ""}, - {"IMAGE_COMDAT_SELECT_NODUPLICATES", Const, 19, ""}, - {"IMAGE_COMDAT_SELECT_SAME_SIZE", Const, 19, ""}, - {"IMAGE_DIRECTORY_ENTRY_ARCHITECTURE", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_BASERELOC", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_DEBUG", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_EXCEPTION", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_EXPORT", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_GLOBALPTR", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_IAT", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_IMPORT", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_RESOURCE", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_SECURITY", Const, 11, ""}, - {"IMAGE_DIRECTORY_ENTRY_TLS", Const, 11, ""}, - {"IMAGE_DLLCHARACTERISTICS_APPCONTAINER", Const, 15, ""}, - {"IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE", Const, 15, ""}, - {"IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY", Const, 15, ""}, - {"IMAGE_DLLCHARACTERISTICS_GUARD_CF", Const, 15, ""}, - {"IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA", Const, 15, ""}, - {"IMAGE_DLLCHARACTERISTICS_NO_BIND", Const, 15, ""}, - {"IMAGE_DLLCHARACTERISTICS_NO_ISOLATION", Const, 15, ""}, - {"IMAGE_DLLCHARACTERISTICS_NO_SEH", Const, 15, ""}, - {"IMAGE_DLLCHARACTERISTICS_NX_COMPAT", Const, 15, ""}, - {"IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE", Const, 15, ""}, - {"IMAGE_DLLCHARACTERISTICS_WDM_DRIVER", Const, 15, ""}, - {"IMAGE_FILE_32BIT_MACHINE", Const, 15, ""}, - {"IMAGE_FILE_AGGRESIVE_WS_TRIM", Const, 15, ""}, - {"IMAGE_FILE_BYTES_REVERSED_HI", Const, 15, ""}, - {"IMAGE_FILE_BYTES_REVERSED_LO", Const, 15, ""}, - {"IMAGE_FILE_DEBUG_STRIPPED", Const, 15, ""}, - {"IMAGE_FILE_DLL", Const, 15, ""}, - {"IMAGE_FILE_EXECUTABLE_IMAGE", Const, 15, ""}, - {"IMAGE_FILE_LARGE_ADDRESS_AWARE", Const, 15, ""}, - {"IMAGE_FILE_LINE_NUMS_STRIPPED", Const, 15, ""}, - {"IMAGE_FILE_LOCAL_SYMS_STRIPPED", Const, 15, ""}, - {"IMAGE_FILE_MACHINE_AM33", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_AMD64", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_ARM", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_ARM64", Const, 11, ""}, - {"IMAGE_FILE_MACHINE_ARMNT", Const, 12, ""}, - {"IMAGE_FILE_MACHINE_EBC", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_I386", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_IA64", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_LOONGARCH32", Const, 19, ""}, - {"IMAGE_FILE_MACHINE_LOONGARCH64", Const, 19, ""}, - {"IMAGE_FILE_MACHINE_M32R", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_MIPS16", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_MIPSFPU", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_MIPSFPU16", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_POWERPC", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_POWERPCFP", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_R4000", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_RISCV128", Const, 20, ""}, - {"IMAGE_FILE_MACHINE_RISCV32", Const, 20, ""}, - {"IMAGE_FILE_MACHINE_RISCV64", Const, 20, ""}, - {"IMAGE_FILE_MACHINE_SH3", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_SH3DSP", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_SH4", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_SH5", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_THUMB", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_UNKNOWN", Const, 0, ""}, - {"IMAGE_FILE_MACHINE_WCEMIPSV2", Const, 0, ""}, - {"IMAGE_FILE_NET_RUN_FROM_SWAP", Const, 15, ""}, - {"IMAGE_FILE_RELOCS_STRIPPED", Const, 15, ""}, - {"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP", Const, 15, ""}, - {"IMAGE_FILE_SYSTEM", Const, 15, ""}, - {"IMAGE_FILE_UP_SYSTEM_ONLY", Const, 15, ""}, - {"IMAGE_SCN_CNT_CODE", Const, 19, ""}, - {"IMAGE_SCN_CNT_INITIALIZED_DATA", Const, 19, ""}, - {"IMAGE_SCN_CNT_UNINITIALIZED_DATA", Const, 19, ""}, - {"IMAGE_SCN_LNK_COMDAT", Const, 19, ""}, - {"IMAGE_SCN_MEM_DISCARDABLE", Const, 19, ""}, - {"IMAGE_SCN_MEM_EXECUTE", Const, 19, ""}, - {"IMAGE_SCN_MEM_READ", Const, 19, ""}, - {"IMAGE_SCN_MEM_WRITE", Const, 19, ""}, - {"IMAGE_SUBSYSTEM_EFI_APPLICATION", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_EFI_ROM", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_NATIVE", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_NATIVE_WINDOWS", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_OS2_CUI", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_POSIX_CUI", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_UNKNOWN", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_WINDOWS_CE_GUI", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_WINDOWS_CUI", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_WINDOWS_GUI", Const, 15, ""}, - {"IMAGE_SUBSYSTEM_XBOX", Const, 15, ""}, - {"ImportDirectory", Type, 0, ""}, - {"ImportDirectory.FirstThunk", Field, 0, ""}, - {"ImportDirectory.ForwarderChain", Field, 0, ""}, - {"ImportDirectory.Name", Field, 0, ""}, - {"ImportDirectory.OriginalFirstThunk", Field, 0, ""}, - {"ImportDirectory.TimeDateStamp", Field, 0, ""}, - {"NewFile", Func, 0, "func(r io.ReaderAt) (*File, error)"}, - {"Open", Func, 0, "func(name string) (*File, error)"}, - {"OptionalHeader32", Type, 3, ""}, - {"OptionalHeader32.AddressOfEntryPoint", Field, 3, ""}, - {"OptionalHeader32.BaseOfCode", Field, 3, ""}, - {"OptionalHeader32.BaseOfData", Field, 3, ""}, - {"OptionalHeader32.CheckSum", Field, 3, ""}, - {"OptionalHeader32.DataDirectory", Field, 3, ""}, - {"OptionalHeader32.DllCharacteristics", Field, 3, ""}, - {"OptionalHeader32.FileAlignment", Field, 3, ""}, - {"OptionalHeader32.ImageBase", Field, 3, ""}, - {"OptionalHeader32.LoaderFlags", Field, 3, ""}, - {"OptionalHeader32.Magic", Field, 3, ""}, - {"OptionalHeader32.MajorImageVersion", Field, 3, ""}, - {"OptionalHeader32.MajorLinkerVersion", Field, 3, ""}, - {"OptionalHeader32.MajorOperatingSystemVersion", Field, 3, ""}, - {"OptionalHeader32.MajorSubsystemVersion", Field, 3, ""}, - {"OptionalHeader32.MinorImageVersion", Field, 3, ""}, - {"OptionalHeader32.MinorLinkerVersion", Field, 3, ""}, - {"OptionalHeader32.MinorOperatingSystemVersion", Field, 3, ""}, - {"OptionalHeader32.MinorSubsystemVersion", Field, 3, ""}, - {"OptionalHeader32.NumberOfRvaAndSizes", Field, 3, ""}, - {"OptionalHeader32.SectionAlignment", Field, 3, ""}, - {"OptionalHeader32.SizeOfCode", Field, 3, ""}, - {"OptionalHeader32.SizeOfHeaders", Field, 3, ""}, - {"OptionalHeader32.SizeOfHeapCommit", Field, 3, ""}, - {"OptionalHeader32.SizeOfHeapReserve", Field, 3, ""}, - {"OptionalHeader32.SizeOfImage", Field, 3, ""}, - {"OptionalHeader32.SizeOfInitializedData", Field, 3, ""}, - {"OptionalHeader32.SizeOfStackCommit", Field, 3, ""}, - {"OptionalHeader32.SizeOfStackReserve", Field, 3, ""}, - {"OptionalHeader32.SizeOfUninitializedData", Field, 3, ""}, - {"OptionalHeader32.Subsystem", Field, 3, ""}, - {"OptionalHeader32.Win32VersionValue", Field, 3, ""}, - {"OptionalHeader64", Type, 3, ""}, - {"OptionalHeader64.AddressOfEntryPoint", Field, 3, ""}, - {"OptionalHeader64.BaseOfCode", Field, 3, ""}, - {"OptionalHeader64.CheckSum", Field, 3, ""}, - {"OptionalHeader64.DataDirectory", Field, 3, ""}, - {"OptionalHeader64.DllCharacteristics", Field, 3, ""}, - {"OptionalHeader64.FileAlignment", Field, 3, ""}, - {"OptionalHeader64.ImageBase", Field, 3, ""}, - {"OptionalHeader64.LoaderFlags", Field, 3, ""}, - {"OptionalHeader64.Magic", Field, 3, ""}, - {"OptionalHeader64.MajorImageVersion", Field, 3, ""}, - {"OptionalHeader64.MajorLinkerVersion", Field, 3, ""}, - {"OptionalHeader64.MajorOperatingSystemVersion", Field, 3, ""}, - {"OptionalHeader64.MajorSubsystemVersion", Field, 3, ""}, - {"OptionalHeader64.MinorImageVersion", Field, 3, ""}, - {"OptionalHeader64.MinorLinkerVersion", Field, 3, ""}, - {"OptionalHeader64.MinorOperatingSystemVersion", Field, 3, ""}, - {"OptionalHeader64.MinorSubsystemVersion", Field, 3, ""}, - {"OptionalHeader64.NumberOfRvaAndSizes", Field, 3, ""}, - {"OptionalHeader64.SectionAlignment", Field, 3, ""}, - {"OptionalHeader64.SizeOfCode", Field, 3, ""}, - {"OptionalHeader64.SizeOfHeaders", Field, 3, ""}, - {"OptionalHeader64.SizeOfHeapCommit", Field, 3, ""}, - {"OptionalHeader64.SizeOfHeapReserve", Field, 3, ""}, - {"OptionalHeader64.SizeOfImage", Field, 3, ""}, - {"OptionalHeader64.SizeOfInitializedData", Field, 3, ""}, - {"OptionalHeader64.SizeOfStackCommit", Field, 3, ""}, - {"OptionalHeader64.SizeOfStackReserve", Field, 3, ""}, - {"OptionalHeader64.SizeOfUninitializedData", Field, 3, ""}, - {"OptionalHeader64.Subsystem", Field, 3, ""}, - {"OptionalHeader64.Win32VersionValue", Field, 3, ""}, - {"Reloc", Type, 8, ""}, - {"Reloc.SymbolTableIndex", Field, 8, ""}, - {"Reloc.Type", Field, 8, ""}, - {"Reloc.VirtualAddress", Field, 8, ""}, - {"Section", Type, 0, ""}, - {"Section.ReaderAt", Field, 0, ""}, - {"Section.Relocs", Field, 8, ""}, - {"Section.SectionHeader", Field, 0, ""}, - {"SectionHeader", Type, 0, ""}, - {"SectionHeader.Characteristics", Field, 0, ""}, - {"SectionHeader.Name", Field, 0, ""}, - {"SectionHeader.NumberOfLineNumbers", Field, 0, ""}, - {"SectionHeader.NumberOfRelocations", Field, 0, ""}, - {"SectionHeader.Offset", Field, 0, ""}, - {"SectionHeader.PointerToLineNumbers", Field, 0, ""}, - {"SectionHeader.PointerToRelocations", Field, 0, ""}, - {"SectionHeader.Size", Field, 0, ""}, - {"SectionHeader.VirtualAddress", Field, 0, ""}, - {"SectionHeader.VirtualSize", Field, 0, ""}, - {"SectionHeader32", Type, 0, ""}, - {"SectionHeader32.Characteristics", Field, 0, ""}, - {"SectionHeader32.Name", Field, 0, ""}, - {"SectionHeader32.NumberOfLineNumbers", Field, 0, ""}, - {"SectionHeader32.NumberOfRelocations", Field, 0, ""}, - {"SectionHeader32.PointerToLineNumbers", Field, 0, ""}, - {"SectionHeader32.PointerToRawData", Field, 0, ""}, - {"SectionHeader32.PointerToRelocations", Field, 0, ""}, - {"SectionHeader32.SizeOfRawData", Field, 0, ""}, - {"SectionHeader32.VirtualAddress", Field, 0, ""}, - {"SectionHeader32.VirtualSize", Field, 0, ""}, - {"StringTable", Type, 8, ""}, - {"Symbol", Type, 1, ""}, - {"Symbol.Name", Field, 1, ""}, - {"Symbol.SectionNumber", Field, 1, ""}, - {"Symbol.StorageClass", Field, 1, ""}, - {"Symbol.Type", Field, 1, ""}, - {"Symbol.Value", Field, 1, ""}, - }, - "debug/plan9obj": { - {"(*File).Close", Method, 3, ""}, - {"(*File).Section", Method, 3, ""}, - {"(*File).Symbols", Method, 3, ""}, - {"(*Section).Data", Method, 3, ""}, - {"(*Section).Open", Method, 3, ""}, - {"(Section).ReadAt", Method, 3, ""}, - {"ErrNoSymbols", Var, 18, ""}, - {"File", Type, 3, ""}, - {"File.FileHeader", Field, 3, ""}, - {"File.Sections", Field, 3, ""}, - {"FileHeader", Type, 3, ""}, - {"FileHeader.Bss", Field, 3, ""}, - {"FileHeader.Entry", Field, 3, ""}, - {"FileHeader.HdrSize", Field, 4, ""}, - {"FileHeader.LoadAddress", Field, 4, ""}, - {"FileHeader.Magic", Field, 3, ""}, - {"FileHeader.PtrSize", Field, 3, ""}, - {"Magic386", Const, 3, ""}, - {"Magic64", Const, 3, ""}, - {"MagicAMD64", Const, 3, ""}, - {"MagicARM", Const, 3, ""}, - {"NewFile", Func, 3, "func(r io.ReaderAt) (*File, error)"}, - {"Open", Func, 3, "func(name string) (*File, error)"}, - {"Section", Type, 3, ""}, - {"Section.ReaderAt", Field, 3, ""}, - {"Section.SectionHeader", Field, 3, ""}, - {"SectionHeader", Type, 3, ""}, - {"SectionHeader.Name", Field, 3, ""}, - {"SectionHeader.Offset", Field, 3, ""}, - {"SectionHeader.Size", Field, 3, ""}, - {"Sym", Type, 3, ""}, - {"Sym.Name", Field, 3, ""}, - {"Sym.Type", Field, 3, ""}, - {"Sym.Value", Field, 3, ""}, - }, - "embed": { - {"(FS).Open", Method, 16, ""}, - {"(FS).ReadDir", Method, 16, ""}, - {"(FS).ReadFile", Method, 16, ""}, - {"FS", Type, 16, ""}, - }, - "encoding": { - {"(BinaryAppender).AppendBinary", Method, 24, ""}, - {"(BinaryMarshaler).MarshalBinary", Method, 2, ""}, - {"(BinaryUnmarshaler).UnmarshalBinary", Method, 2, ""}, - {"(TextAppender).AppendText", Method, 24, ""}, - {"(TextMarshaler).MarshalText", Method, 2, ""}, - {"(TextUnmarshaler).UnmarshalText", Method, 2, ""}, - {"BinaryAppender", Type, 24, ""}, - {"BinaryMarshaler", Type, 2, ""}, - {"BinaryUnmarshaler", Type, 2, ""}, - {"TextAppender", Type, 24, ""}, - {"TextMarshaler", Type, 2, ""}, - {"TextUnmarshaler", Type, 2, ""}, - }, - "encoding/ascii85": { - {"(CorruptInputError).Error", Method, 0, ""}, - {"CorruptInputError", Type, 0, ""}, - {"Decode", Func, 0, "func(dst []byte, src []byte, flush bool) (ndst int, nsrc int, err error)"}, - {"Encode", Func, 0, "func(dst []byte, src []byte) int"}, - {"MaxEncodedLen", Func, 0, "func(n int) int"}, - {"NewDecoder", Func, 0, "func(r io.Reader) io.Reader"}, - {"NewEncoder", Func, 0, "func(w io.Writer) io.WriteCloser"}, - }, - "encoding/asn1": { - {"(BitString).At", Method, 0, ""}, - {"(BitString).RightAlign", Method, 0, ""}, - {"(ObjectIdentifier).Equal", Method, 0, ""}, - {"(ObjectIdentifier).String", Method, 3, ""}, - {"(StructuralError).Error", Method, 0, ""}, - {"(SyntaxError).Error", Method, 0, ""}, - {"BitString", Type, 0, ""}, - {"BitString.BitLength", Field, 0, ""}, - {"BitString.Bytes", Field, 0, ""}, - {"ClassApplication", Const, 6, ""}, - {"ClassContextSpecific", Const, 6, ""}, - {"ClassPrivate", Const, 6, ""}, - {"ClassUniversal", Const, 6, ""}, - {"Enumerated", Type, 0, ""}, - {"Flag", Type, 0, ""}, - {"Marshal", Func, 0, "func(val any) ([]byte, error)"}, - {"MarshalWithParams", Func, 10, "func(val any, params string) ([]byte, error)"}, - {"NullBytes", Var, 9, ""}, - {"NullRawValue", Var, 9, ""}, - {"ObjectIdentifier", Type, 0, ""}, - {"RawContent", Type, 0, ""}, - {"RawValue", Type, 0, ""}, - {"RawValue.Bytes", Field, 0, ""}, - {"RawValue.Class", Field, 0, ""}, - {"RawValue.FullBytes", Field, 0, ""}, - {"RawValue.IsCompound", Field, 0, ""}, - {"RawValue.Tag", Field, 0, ""}, - {"StructuralError", Type, 0, ""}, - {"StructuralError.Msg", Field, 0, ""}, - {"SyntaxError", Type, 0, ""}, - {"SyntaxError.Msg", Field, 0, ""}, - {"TagBMPString", Const, 14, ""}, - {"TagBitString", Const, 6, ""}, - {"TagBoolean", Const, 6, ""}, - {"TagEnum", Const, 6, ""}, - {"TagGeneralString", Const, 6, ""}, - {"TagGeneralizedTime", Const, 6, ""}, - {"TagIA5String", Const, 6, ""}, - {"TagInteger", Const, 6, ""}, - {"TagNull", Const, 9, ""}, - {"TagNumericString", Const, 10, ""}, - {"TagOID", Const, 6, ""}, - {"TagOctetString", Const, 6, ""}, - {"TagPrintableString", Const, 6, ""}, - {"TagSequence", Const, 6, ""}, - {"TagSet", Const, 6, ""}, - {"TagT61String", Const, 6, ""}, - {"TagUTCTime", Const, 6, ""}, - {"TagUTF8String", Const, 6, ""}, - {"Unmarshal", Func, 0, "func(b []byte, val any) (rest []byte, err error)"}, - {"UnmarshalWithParams", Func, 0, "func(b []byte, val any, params string) (rest []byte, err error)"}, - }, - "encoding/base32": { - {"(*Encoding).AppendDecode", Method, 22, ""}, - {"(*Encoding).AppendEncode", Method, 22, ""}, - {"(*Encoding).Decode", Method, 0, ""}, - {"(*Encoding).DecodeString", Method, 0, ""}, - {"(*Encoding).DecodedLen", Method, 0, ""}, - {"(*Encoding).Encode", Method, 0, ""}, - {"(*Encoding).EncodeToString", Method, 0, ""}, - {"(*Encoding).EncodedLen", Method, 0, ""}, - {"(CorruptInputError).Error", Method, 0, ""}, - {"(Encoding).WithPadding", Method, 9, ""}, - {"CorruptInputError", Type, 0, ""}, - {"Encoding", Type, 0, ""}, - {"HexEncoding", Var, 0, ""}, - {"NewDecoder", Func, 0, "func(enc *Encoding, r io.Reader) io.Reader"}, - {"NewEncoder", Func, 0, "func(enc *Encoding, w io.Writer) io.WriteCloser"}, - {"NewEncoding", Func, 0, "func(encoder string) *Encoding"}, - {"NoPadding", Const, 9, ""}, - {"StdEncoding", Var, 0, ""}, - {"StdPadding", Const, 9, ""}, - }, - "encoding/base64": { - {"(*Encoding).AppendDecode", Method, 22, ""}, - {"(*Encoding).AppendEncode", Method, 22, ""}, - {"(*Encoding).Decode", Method, 0, ""}, - {"(*Encoding).DecodeString", Method, 0, ""}, - {"(*Encoding).DecodedLen", Method, 0, ""}, - {"(*Encoding).Encode", Method, 0, ""}, - {"(*Encoding).EncodeToString", Method, 0, ""}, - {"(*Encoding).EncodedLen", Method, 0, ""}, - {"(CorruptInputError).Error", Method, 0, ""}, - {"(Encoding).Strict", Method, 8, ""}, - {"(Encoding).WithPadding", Method, 5, ""}, - {"CorruptInputError", Type, 0, ""}, - {"Encoding", Type, 0, ""}, - {"NewDecoder", Func, 0, "func(enc *Encoding, r io.Reader) io.Reader"}, - {"NewEncoder", Func, 0, "func(enc *Encoding, w io.Writer) io.WriteCloser"}, - {"NewEncoding", Func, 0, "func(encoder string) *Encoding"}, - {"NoPadding", Const, 5, ""}, - {"RawStdEncoding", Var, 5, ""}, - {"RawURLEncoding", Var, 5, ""}, - {"StdEncoding", Var, 0, ""}, - {"StdPadding", Const, 5, ""}, - {"URLEncoding", Var, 0, ""}, - }, - "encoding/binary": { - {"(AppendByteOrder).AppendUint16", Method, 19, ""}, - {"(AppendByteOrder).AppendUint32", Method, 19, ""}, - {"(AppendByteOrder).AppendUint64", Method, 19, ""}, - {"(AppendByteOrder).String", Method, 19, ""}, - {"(ByteOrder).PutUint16", Method, 0, ""}, - {"(ByteOrder).PutUint32", Method, 0, ""}, - {"(ByteOrder).PutUint64", Method, 0, ""}, - {"(ByteOrder).String", Method, 0, ""}, - {"(ByteOrder).Uint16", Method, 0, ""}, - {"(ByteOrder).Uint32", Method, 0, ""}, - {"(ByteOrder).Uint64", Method, 0, ""}, - {"Append", Func, 23, "func(buf []byte, order ByteOrder, data any) ([]byte, error)"}, - {"AppendByteOrder", Type, 19, ""}, - {"AppendUvarint", Func, 19, "func(buf []byte, x uint64) []byte"}, - {"AppendVarint", Func, 19, "func(buf []byte, x int64) []byte"}, - {"BigEndian", Var, 0, ""}, - {"ByteOrder", Type, 0, ""}, - {"Decode", Func, 23, "func(buf []byte, order ByteOrder, data any) (int, error)"}, - {"Encode", Func, 23, "func(buf []byte, order ByteOrder, data any) (int, error)"}, - {"LittleEndian", Var, 0, ""}, - {"MaxVarintLen16", Const, 0, ""}, - {"MaxVarintLen32", Const, 0, ""}, - {"MaxVarintLen64", Const, 0, ""}, - {"NativeEndian", Var, 21, ""}, - {"PutUvarint", Func, 0, "func(buf []byte, x uint64) int"}, - {"PutVarint", Func, 0, "func(buf []byte, x int64) int"}, - {"Read", Func, 0, "func(r io.Reader, order ByteOrder, data any) error"}, - {"ReadUvarint", Func, 0, "func(r io.ByteReader) (uint64, error)"}, - {"ReadVarint", Func, 0, "func(r io.ByteReader) (int64, error)"}, - {"Size", Func, 0, "func(v any) int"}, - {"Uvarint", Func, 0, "func(buf []byte) (uint64, int)"}, - {"Varint", Func, 0, "func(buf []byte) (int64, int)"}, - {"Write", Func, 0, "func(w io.Writer, order ByteOrder, data any) error"}, - }, - "encoding/csv": { - {"(*ParseError).Error", Method, 0, ""}, - {"(*ParseError).Unwrap", Method, 13, ""}, - {"(*Reader).FieldPos", Method, 17, ""}, - {"(*Reader).InputOffset", Method, 19, ""}, - {"(*Reader).Read", Method, 0, ""}, - {"(*Reader).ReadAll", Method, 0, ""}, - {"(*Writer).Error", Method, 1, ""}, - {"(*Writer).Flush", Method, 0, ""}, - {"(*Writer).Write", Method, 0, ""}, - {"(*Writer).WriteAll", Method, 0, ""}, - {"ErrBareQuote", Var, 0, ""}, - {"ErrFieldCount", Var, 0, ""}, - {"ErrQuote", Var, 0, ""}, - {"ErrTrailingComma", Var, 0, ""}, - {"NewReader", Func, 0, "func(r io.Reader) *Reader"}, - {"NewWriter", Func, 0, "func(w io.Writer) *Writer"}, - {"ParseError", Type, 0, ""}, - {"ParseError.Column", Field, 0, ""}, - {"ParseError.Err", Field, 0, ""}, - {"ParseError.Line", Field, 0, ""}, - {"ParseError.StartLine", Field, 10, ""}, - {"Reader", Type, 0, ""}, - {"Reader.Comma", Field, 0, ""}, - {"Reader.Comment", Field, 0, ""}, - {"Reader.FieldsPerRecord", Field, 0, ""}, - {"Reader.LazyQuotes", Field, 0, ""}, - {"Reader.ReuseRecord", Field, 9, ""}, - {"Reader.TrailingComma", Field, 0, ""}, - {"Reader.TrimLeadingSpace", Field, 0, ""}, - {"Writer", Type, 0, ""}, - {"Writer.Comma", Field, 0, ""}, - {"Writer.UseCRLF", Field, 0, ""}, - }, - "encoding/gob": { - {"(*Decoder).Decode", Method, 0, ""}, - {"(*Decoder).DecodeValue", Method, 0, ""}, - {"(*Encoder).Encode", Method, 0, ""}, - {"(*Encoder).EncodeValue", Method, 0, ""}, - {"(GobDecoder).GobDecode", Method, 0, ""}, - {"(GobEncoder).GobEncode", Method, 0, ""}, - {"CommonType", Type, 0, ""}, - {"CommonType.Id", Field, 0, ""}, - {"CommonType.Name", Field, 0, ""}, - {"Decoder", Type, 0, ""}, - {"Encoder", Type, 0, ""}, - {"GobDecoder", Type, 0, ""}, - {"GobEncoder", Type, 0, ""}, - {"NewDecoder", Func, 0, "func(r io.Reader) *Decoder"}, - {"NewEncoder", Func, 0, "func(w io.Writer) *Encoder"}, - {"Register", Func, 0, "func(value any)"}, - {"RegisterName", Func, 0, "func(name string, value any)"}, - }, - "encoding/hex": { - {"(InvalidByteError).Error", Method, 0, ""}, - {"AppendDecode", Func, 22, "func(dst []byte, src []byte) ([]byte, error)"}, - {"AppendEncode", Func, 22, "func(dst []byte, src []byte) []byte"}, - {"Decode", Func, 0, "func(dst []byte, src []byte) (int, error)"}, - {"DecodeString", Func, 0, "func(s string) ([]byte, error)"}, - {"DecodedLen", Func, 0, "func(x int) int"}, - {"Dump", Func, 0, "func(data []byte) string"}, - {"Dumper", Func, 0, "func(w io.Writer) io.WriteCloser"}, - {"Encode", Func, 0, "func(dst []byte, src []byte) int"}, - {"EncodeToString", Func, 0, "func(src []byte) string"}, - {"EncodedLen", Func, 0, "func(n int) int"}, - {"ErrLength", Var, 0, ""}, - {"InvalidByteError", Type, 0, ""}, - {"NewDecoder", Func, 10, "func(r io.Reader) io.Reader"}, - {"NewEncoder", Func, 10, "func(w io.Writer) io.Writer"}, - }, - "encoding/json": { - {"(*Decoder).Buffered", Method, 1, ""}, - {"(*Decoder).Decode", Method, 0, ""}, - {"(*Decoder).DisallowUnknownFields", Method, 10, ""}, - {"(*Decoder).InputOffset", Method, 14, ""}, - {"(*Decoder).More", Method, 5, ""}, - {"(*Decoder).Token", Method, 5, ""}, - {"(*Decoder).UseNumber", Method, 1, ""}, - {"(*Encoder).Encode", Method, 0, ""}, - {"(*Encoder).SetEscapeHTML", Method, 7, ""}, - {"(*Encoder).SetIndent", Method, 7, ""}, - {"(*InvalidUTF8Error).Error", Method, 0, ""}, - {"(*InvalidUnmarshalError).Error", Method, 0, ""}, - {"(*MarshalerError).Error", Method, 0, ""}, - {"(*MarshalerError).Unwrap", Method, 13, ""}, - {"(*RawMessage).MarshalJSON", Method, 0, ""}, - {"(*RawMessage).UnmarshalJSON", Method, 0, ""}, - {"(*SyntaxError).Error", Method, 0, ""}, - {"(*UnmarshalFieldError).Error", Method, 0, ""}, - {"(*UnmarshalTypeError).Error", Method, 0, ""}, - {"(*UnsupportedTypeError).Error", Method, 0, ""}, - {"(*UnsupportedValueError).Error", Method, 0, ""}, - {"(Delim).String", Method, 5, ""}, - {"(Marshaler).MarshalJSON", Method, 0, ""}, - {"(Number).Float64", Method, 1, ""}, - {"(Number).Int64", Method, 1, ""}, - {"(Number).String", Method, 1, ""}, - {"(RawMessage).MarshalJSON", Method, 8, ""}, - {"(Unmarshaler).UnmarshalJSON", Method, 0, ""}, - {"Compact", Func, 0, "func(dst *bytes.Buffer, src []byte) error"}, - {"Decoder", Type, 0, ""}, - {"Delim", Type, 5, ""}, - {"Encoder", Type, 0, ""}, - {"HTMLEscape", Func, 0, "func(dst *bytes.Buffer, src []byte)"}, - {"Indent", Func, 0, "func(dst *bytes.Buffer, src []byte, prefix string, indent string) error"}, - {"InvalidUTF8Error", Type, 0, ""}, - {"InvalidUTF8Error.S", Field, 0, ""}, - {"InvalidUnmarshalError", Type, 0, ""}, - {"InvalidUnmarshalError.Type", Field, 0, ""}, - {"Marshal", Func, 0, "func(v any) ([]byte, error)"}, - {"MarshalIndent", Func, 0, "func(v any, prefix string, indent string) ([]byte, error)"}, - {"Marshaler", Type, 0, ""}, - {"MarshalerError", Type, 0, ""}, - {"MarshalerError.Err", Field, 0, ""}, - {"MarshalerError.Type", Field, 0, ""}, - {"NewDecoder", Func, 0, "func(r io.Reader) *Decoder"}, - {"NewEncoder", Func, 0, "func(w io.Writer) *Encoder"}, - {"Number", Type, 1, ""}, - {"RawMessage", Type, 0, ""}, - {"SyntaxError", Type, 0, ""}, - {"SyntaxError.Offset", Field, 0, ""}, - {"Token", Type, 5, ""}, - {"Unmarshal", Func, 0, "func(data []byte, v any) error"}, - {"UnmarshalFieldError", Type, 0, ""}, - {"UnmarshalFieldError.Field", Field, 0, ""}, - {"UnmarshalFieldError.Key", Field, 0, ""}, - {"UnmarshalFieldError.Type", Field, 0, ""}, - {"UnmarshalTypeError", Type, 0, ""}, - {"UnmarshalTypeError.Field", Field, 8, ""}, - {"UnmarshalTypeError.Offset", Field, 5, ""}, - {"UnmarshalTypeError.Struct", Field, 8, ""}, - {"UnmarshalTypeError.Type", Field, 0, ""}, - {"UnmarshalTypeError.Value", Field, 0, ""}, - {"Unmarshaler", Type, 0, ""}, - {"UnsupportedTypeError", Type, 0, ""}, - {"UnsupportedTypeError.Type", Field, 0, ""}, - {"UnsupportedValueError", Type, 0, ""}, - {"UnsupportedValueError.Str", Field, 0, ""}, - {"UnsupportedValueError.Value", Field, 0, ""}, - {"Valid", Func, 9, "func(data []byte) bool"}, - }, - "encoding/pem": { - {"Block", Type, 0, ""}, - {"Block.Bytes", Field, 0, ""}, - {"Block.Headers", Field, 0, ""}, - {"Block.Type", Field, 0, ""}, - {"Decode", Func, 0, "func(data []byte) (p *Block, rest []byte)"}, - {"Encode", Func, 0, "func(out io.Writer, b *Block) error"}, - {"EncodeToMemory", Func, 0, "func(b *Block) []byte"}, - }, - "encoding/xml": { - {"(*Decoder).Decode", Method, 0, ""}, - {"(*Decoder).DecodeElement", Method, 0, ""}, - {"(*Decoder).InputOffset", Method, 4, ""}, - {"(*Decoder).InputPos", Method, 19, ""}, - {"(*Decoder).RawToken", Method, 0, ""}, - {"(*Decoder).Skip", Method, 0, ""}, - {"(*Decoder).Token", Method, 0, ""}, - {"(*Encoder).Close", Method, 20, ""}, - {"(*Encoder).Encode", Method, 0, ""}, - {"(*Encoder).EncodeElement", Method, 2, ""}, - {"(*Encoder).EncodeToken", Method, 2, ""}, - {"(*Encoder).Flush", Method, 2, ""}, - {"(*Encoder).Indent", Method, 1, ""}, - {"(*SyntaxError).Error", Method, 0, ""}, - {"(*TagPathError).Error", Method, 0, ""}, - {"(*UnsupportedTypeError).Error", Method, 0, ""}, - {"(CharData).Copy", Method, 0, ""}, - {"(Comment).Copy", Method, 0, ""}, - {"(Directive).Copy", Method, 0, ""}, - {"(Marshaler).MarshalXML", Method, 2, ""}, - {"(MarshalerAttr).MarshalXMLAttr", Method, 2, ""}, - {"(ProcInst).Copy", Method, 0, ""}, - {"(StartElement).Copy", Method, 0, ""}, - {"(StartElement).End", Method, 2, ""}, - {"(TokenReader).Token", Method, 10, ""}, - {"(UnmarshalError).Error", Method, 0, ""}, - {"(Unmarshaler).UnmarshalXML", Method, 2, ""}, - {"(UnmarshalerAttr).UnmarshalXMLAttr", Method, 2, ""}, - {"Attr", Type, 0, ""}, - {"Attr.Name", Field, 0, ""}, - {"Attr.Value", Field, 0, ""}, - {"CharData", Type, 0, ""}, - {"Comment", Type, 0, ""}, - {"CopyToken", Func, 0, "func(t Token) Token"}, - {"Decoder", Type, 0, ""}, - {"Decoder.AutoClose", Field, 0, ""}, - {"Decoder.CharsetReader", Field, 0, ""}, - {"Decoder.DefaultSpace", Field, 1, ""}, - {"Decoder.Entity", Field, 0, ""}, - {"Decoder.Strict", Field, 0, ""}, - {"Directive", Type, 0, ""}, - {"Encoder", Type, 0, ""}, - {"EndElement", Type, 0, ""}, - {"EndElement.Name", Field, 0, ""}, - {"Escape", Func, 0, "func(w io.Writer, s []byte)"}, - {"EscapeText", Func, 1, "func(w io.Writer, s []byte) error"}, - {"HTMLAutoClose", Var, 0, ""}, - {"HTMLEntity", Var, 0, ""}, - {"Header", Const, 0, ""}, - {"Marshal", Func, 0, "func(v any) ([]byte, error)"}, - {"MarshalIndent", Func, 0, "func(v any, prefix string, indent string) ([]byte, error)"}, - {"Marshaler", Type, 2, ""}, - {"MarshalerAttr", Type, 2, ""}, - {"Name", Type, 0, ""}, - {"Name.Local", Field, 0, ""}, - {"Name.Space", Field, 0, ""}, - {"NewDecoder", Func, 0, "func(r io.Reader) *Decoder"}, - {"NewEncoder", Func, 0, "func(w io.Writer) *Encoder"}, - {"NewTokenDecoder", Func, 10, "func(t TokenReader) *Decoder"}, - {"ProcInst", Type, 0, ""}, - {"ProcInst.Inst", Field, 0, ""}, - {"ProcInst.Target", Field, 0, ""}, - {"StartElement", Type, 0, ""}, - {"StartElement.Attr", Field, 0, ""}, - {"StartElement.Name", Field, 0, ""}, - {"SyntaxError", Type, 0, ""}, - {"SyntaxError.Line", Field, 0, ""}, - {"SyntaxError.Msg", Field, 0, ""}, - {"TagPathError", Type, 0, ""}, - {"TagPathError.Field1", Field, 0, ""}, - {"TagPathError.Field2", Field, 0, ""}, - {"TagPathError.Struct", Field, 0, ""}, - {"TagPathError.Tag1", Field, 0, ""}, - {"TagPathError.Tag2", Field, 0, ""}, - {"Token", Type, 0, ""}, - {"TokenReader", Type, 10, ""}, - {"Unmarshal", Func, 0, "func(data []byte, v any) error"}, - {"UnmarshalError", Type, 0, ""}, - {"Unmarshaler", Type, 2, ""}, - {"UnmarshalerAttr", Type, 2, ""}, - {"UnsupportedTypeError", Type, 0, ""}, - {"UnsupportedTypeError.Type", Field, 0, ""}, - }, - "errors": { - {"As", Func, 13, "func(err error, target any) bool"}, - {"AsType", Func, 26, "func[E error](err error) (E, bool)"}, - {"ErrUnsupported", Var, 21, ""}, - {"Is", Func, 13, "func(err error, target error) bool"}, - {"Join", Func, 20, "func(errs ...error) error"}, - {"New", Func, 0, "func(text string) error"}, - {"Unwrap", Func, 13, "func(err error) error"}, - }, - "expvar": { - {"(*Float).Add", Method, 0, ""}, - {"(*Float).Set", Method, 0, ""}, - {"(*Float).String", Method, 0, ""}, - {"(*Float).Value", Method, 8, ""}, - {"(*Int).Add", Method, 0, ""}, - {"(*Int).Set", Method, 0, ""}, - {"(*Int).String", Method, 0, ""}, - {"(*Int).Value", Method, 8, ""}, - {"(*Map).Add", Method, 0, ""}, - {"(*Map).AddFloat", Method, 0, ""}, - {"(*Map).Delete", Method, 12, ""}, - {"(*Map).Do", Method, 0, ""}, - {"(*Map).Get", Method, 0, ""}, - {"(*Map).Init", Method, 0, ""}, - {"(*Map).Set", Method, 0, ""}, - {"(*Map).String", Method, 0, ""}, - {"(*String).Set", Method, 0, ""}, - {"(*String).String", Method, 0, ""}, - {"(*String).Value", Method, 8, ""}, - {"(Func).String", Method, 0, ""}, - {"(Func).Value", Method, 8, ""}, - {"(Var).String", Method, 0, ""}, - {"Do", Func, 0, "func(f func(KeyValue))"}, - {"Float", Type, 0, ""}, - {"Func", Type, 0, ""}, - {"Get", Func, 0, "func(name string) Var"}, - {"Handler", Func, 8, "func() http.Handler"}, - {"Int", Type, 0, ""}, - {"KeyValue", Type, 0, ""}, - {"KeyValue.Key", Field, 0, ""}, - {"KeyValue.Value", Field, 0, ""}, - {"Map", Type, 0, ""}, - {"NewFloat", Func, 0, "func(name string) *Float"}, - {"NewInt", Func, 0, "func(name string) *Int"}, - {"NewMap", Func, 0, "func(name string) *Map"}, - {"NewString", Func, 0, "func(name string) *String"}, - {"Publish", Func, 0, "func(name string, v Var)"}, - {"String", Type, 0, ""}, - {"Var", Type, 0, ""}, - }, - "flag": { - {"(*FlagSet).Arg", Method, 0, ""}, - {"(*FlagSet).Args", Method, 0, ""}, - {"(*FlagSet).Bool", Method, 0, ""}, - {"(*FlagSet).BoolFunc", Method, 21, ""}, - {"(*FlagSet).BoolVar", Method, 0, ""}, - {"(*FlagSet).Duration", Method, 0, ""}, - {"(*FlagSet).DurationVar", Method, 0, ""}, - {"(*FlagSet).ErrorHandling", Method, 10, ""}, - {"(*FlagSet).Float64", Method, 0, ""}, - {"(*FlagSet).Float64Var", Method, 0, ""}, - {"(*FlagSet).Func", Method, 16, ""}, - {"(*FlagSet).Init", Method, 0, ""}, - {"(*FlagSet).Int", Method, 0, ""}, - {"(*FlagSet).Int64", Method, 0, ""}, - {"(*FlagSet).Int64Var", Method, 0, ""}, - {"(*FlagSet).IntVar", Method, 0, ""}, - {"(*FlagSet).Lookup", Method, 0, ""}, - {"(*FlagSet).NArg", Method, 0, ""}, - {"(*FlagSet).NFlag", Method, 0, ""}, - {"(*FlagSet).Name", Method, 10, ""}, - {"(*FlagSet).Output", Method, 10, ""}, - {"(*FlagSet).Parse", Method, 0, ""}, - {"(*FlagSet).Parsed", Method, 0, ""}, - {"(*FlagSet).PrintDefaults", Method, 0, ""}, - {"(*FlagSet).Set", Method, 0, ""}, - {"(*FlagSet).SetOutput", Method, 0, ""}, - {"(*FlagSet).String", Method, 0, ""}, - {"(*FlagSet).StringVar", Method, 0, ""}, - {"(*FlagSet).TextVar", Method, 19, ""}, - {"(*FlagSet).Uint", Method, 0, ""}, - {"(*FlagSet).Uint64", Method, 0, ""}, - {"(*FlagSet).Uint64Var", Method, 0, ""}, - {"(*FlagSet).UintVar", Method, 0, ""}, - {"(*FlagSet).Var", Method, 0, ""}, - {"(*FlagSet).Visit", Method, 0, ""}, - {"(*FlagSet).VisitAll", Method, 0, ""}, - {"(Getter).Get", Method, 2, ""}, - {"(Getter).Set", Method, 2, ""}, - {"(Getter).String", Method, 2, ""}, - {"(Value).Set", Method, 0, ""}, - {"(Value).String", Method, 0, ""}, - {"Arg", Func, 0, "func(i int) string"}, - {"Args", Func, 0, "func() []string"}, - {"Bool", Func, 0, "func(name string, value bool, usage string) *bool"}, - {"BoolFunc", Func, 21, "func(name string, usage string, fn func(string) error)"}, - {"BoolVar", Func, 0, "func(p *bool, name string, value bool, usage string)"}, - {"CommandLine", Var, 2, ""}, - {"ContinueOnError", Const, 0, ""}, - {"Duration", Func, 0, "func(name string, value time.Duration, usage string) *time.Duration"}, - {"DurationVar", Func, 0, "func(p *time.Duration, name string, value time.Duration, usage string)"}, - {"ErrHelp", Var, 0, ""}, - {"ErrorHandling", Type, 0, ""}, - {"ExitOnError", Const, 0, ""}, - {"Flag", Type, 0, ""}, - {"Flag.DefValue", Field, 0, ""}, - {"Flag.Name", Field, 0, ""}, - {"Flag.Usage", Field, 0, ""}, - {"Flag.Value", Field, 0, ""}, - {"FlagSet", Type, 0, ""}, - {"FlagSet.Usage", Field, 0, ""}, - {"Float64", Func, 0, "func(name string, value float64, usage string) *float64"}, - {"Float64Var", Func, 0, "func(p *float64, name string, value float64, usage string)"}, - {"Func", Func, 16, "func(name string, usage string, fn func(string) error)"}, - {"Getter", Type, 2, ""}, - {"Int", Func, 0, "func(name string, value int, usage string) *int"}, - {"Int64", Func, 0, "func(name string, value int64, usage string) *int64"}, - {"Int64Var", Func, 0, "func(p *int64, name string, value int64, usage string)"}, - {"IntVar", Func, 0, "func(p *int, name string, value int, usage string)"}, - {"Lookup", Func, 0, "func(name string) *Flag"}, - {"NArg", Func, 0, "func() int"}, - {"NFlag", Func, 0, "func() int"}, - {"NewFlagSet", Func, 0, "func(name string, errorHandling ErrorHandling) *FlagSet"}, - {"PanicOnError", Const, 0, ""}, - {"Parse", Func, 0, "func()"}, - {"Parsed", Func, 0, "func() bool"}, - {"PrintDefaults", Func, 0, "func()"}, - {"Set", Func, 0, "func(name string, value string) error"}, - {"String", Func, 0, "func(name string, value string, usage string) *string"}, - {"StringVar", Func, 0, "func(p *string, name string, value string, usage string)"}, - {"TextVar", Func, 19, "func(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string)"}, - {"Uint", Func, 0, "func(name string, value uint, usage string) *uint"}, - {"Uint64", Func, 0, "func(name string, value uint64, usage string) *uint64"}, - {"Uint64Var", Func, 0, "func(p *uint64, name string, value uint64, usage string)"}, - {"UintVar", Func, 0, "func(p *uint, name string, value uint, usage string)"}, - {"UnquoteUsage", Func, 5, "func(flag *Flag) (name string, usage string)"}, - {"Usage", Var, 0, ""}, - {"Value", Type, 0, ""}, - {"Var", Func, 0, "func(value Value, name string, usage string)"}, - {"Visit", Func, 0, "func(fn func(*Flag))"}, - {"VisitAll", Func, 0, "func(fn func(*Flag))"}, - }, - "fmt": { - {"(Formatter).Format", Method, 0, ""}, - {"(GoStringer).GoString", Method, 0, ""}, - {"(ScanState).Read", Method, 0, ""}, - {"(ScanState).ReadRune", Method, 0, ""}, - {"(ScanState).SkipSpace", Method, 0, ""}, - {"(ScanState).Token", Method, 0, ""}, - {"(ScanState).UnreadRune", Method, 0, ""}, - {"(ScanState).Width", Method, 0, ""}, - {"(Scanner).Scan", Method, 0, ""}, - {"(State).Flag", Method, 0, ""}, - {"(State).Precision", Method, 0, ""}, - {"(State).Width", Method, 0, ""}, - {"(State).Write", Method, 0, ""}, - {"(Stringer).String", Method, 0, ""}, - {"Append", Func, 19, "func(b []byte, a ...any) []byte"}, - {"Appendf", Func, 19, "func(b []byte, format string, a ...any) []byte"}, - {"Appendln", Func, 19, "func(b []byte, a ...any) []byte"}, - {"Errorf", Func, 0, "func(format string, a ...any) (err error)"}, - {"FormatString", Func, 20, "func(state State, verb rune) string"}, - {"Formatter", Type, 0, ""}, - {"Fprint", Func, 0, "func(w io.Writer, a ...any) (n int, err error)"}, - {"Fprintf", Func, 0, "func(w io.Writer, format string, a ...any) (n int, err error)"}, - {"Fprintln", Func, 0, "func(w io.Writer, a ...any) (n int, err error)"}, - {"Fscan", Func, 0, "func(r io.Reader, a ...any) (n int, err error)"}, - {"Fscanf", Func, 0, "func(r io.Reader, format string, a ...any) (n int, err error)"}, - {"Fscanln", Func, 0, "func(r io.Reader, a ...any) (n int, err error)"}, - {"GoStringer", Type, 0, ""}, - {"Print", Func, 0, "func(a ...any) (n int, err error)"}, - {"Printf", Func, 0, "func(format string, a ...any) (n int, err error)"}, - {"Println", Func, 0, "func(a ...any) (n int, err error)"}, - {"Scan", Func, 0, "func(a ...any) (n int, err error)"}, - {"ScanState", Type, 0, ""}, - {"Scanf", Func, 0, "func(format string, a ...any) (n int, err error)"}, - {"Scanln", Func, 0, "func(a ...any) (n int, err error)"}, - {"Scanner", Type, 0, ""}, - {"Sprint", Func, 0, "func(a ...any) string"}, - {"Sprintf", Func, 0, "func(format string, a ...any) string"}, - {"Sprintln", Func, 0, "func(a ...any) string"}, - {"Sscan", Func, 0, "func(str string, a ...any) (n int, err error)"}, - {"Sscanf", Func, 0, "func(str string, format string, a ...any) (n int, err error)"}, - {"Sscanln", Func, 0, "func(str string, a ...any) (n int, err error)"}, - {"State", Type, 0, ""}, - {"Stringer", Type, 0, ""}, - }, - "go/ast": { - {"(*ArrayType).End", Method, 0, ""}, - {"(*ArrayType).Pos", Method, 0, ""}, - {"(*AssignStmt).End", Method, 0, ""}, - {"(*AssignStmt).Pos", Method, 0, ""}, - {"(*BadDecl).End", Method, 0, ""}, - {"(*BadDecl).Pos", Method, 0, ""}, - {"(*BadExpr).End", Method, 0, ""}, - {"(*BadExpr).Pos", Method, 0, ""}, - {"(*BadStmt).End", Method, 0, ""}, - {"(*BadStmt).Pos", Method, 0, ""}, - {"(*BasicLit).End", Method, 0, ""}, - {"(*BasicLit).Pos", Method, 0, ""}, - {"(*BinaryExpr).End", Method, 0, ""}, - {"(*BinaryExpr).Pos", Method, 0, ""}, - {"(*BlockStmt).End", Method, 0, ""}, - {"(*BlockStmt).Pos", Method, 0, ""}, - {"(*BranchStmt).End", Method, 0, ""}, - {"(*BranchStmt).Pos", Method, 0, ""}, - {"(*CallExpr).End", Method, 0, ""}, - {"(*CallExpr).Pos", Method, 0, ""}, - {"(*CaseClause).End", Method, 0, ""}, - {"(*CaseClause).Pos", Method, 0, ""}, - {"(*ChanType).End", Method, 0, ""}, - {"(*ChanType).Pos", Method, 0, ""}, - {"(*CommClause).End", Method, 0, ""}, - {"(*CommClause).Pos", Method, 0, ""}, - {"(*Comment).End", Method, 0, ""}, - {"(*Comment).Pos", Method, 0, ""}, - {"(*CommentGroup).End", Method, 0, ""}, - {"(*CommentGroup).Pos", Method, 0, ""}, - {"(*CommentGroup).Text", Method, 0, ""}, - {"(*CompositeLit).End", Method, 0, ""}, - {"(*CompositeLit).Pos", Method, 0, ""}, - {"(*DeclStmt).End", Method, 0, ""}, - {"(*DeclStmt).Pos", Method, 0, ""}, - {"(*DeferStmt).End", Method, 0, ""}, - {"(*DeferStmt).Pos", Method, 0, ""}, - {"(*Directive).End", Method, 26, ""}, - {"(*Directive).ParseArgs", Method, 26, ""}, - {"(*Directive).Pos", Method, 26, ""}, - {"(*Ellipsis).End", Method, 0, ""}, - {"(*Ellipsis).Pos", Method, 0, ""}, - {"(*EmptyStmt).End", Method, 0, ""}, - {"(*EmptyStmt).Pos", Method, 0, ""}, - {"(*ExprStmt).End", Method, 0, ""}, - {"(*ExprStmt).Pos", Method, 0, ""}, - {"(*Field).End", Method, 0, ""}, - {"(*Field).Pos", Method, 0, ""}, - {"(*FieldList).End", Method, 0, ""}, - {"(*FieldList).NumFields", Method, 0, ""}, - {"(*FieldList).Pos", Method, 0, ""}, - {"(*File).End", Method, 0, ""}, - {"(*File).Pos", Method, 0, ""}, - {"(*ForStmt).End", Method, 0, ""}, - {"(*ForStmt).Pos", Method, 0, ""}, - {"(*FuncDecl).End", Method, 0, ""}, - {"(*FuncDecl).Pos", Method, 0, ""}, - {"(*FuncLit).End", Method, 0, ""}, - {"(*FuncLit).Pos", Method, 0, ""}, - {"(*FuncType).End", Method, 0, ""}, - {"(*FuncType).Pos", Method, 0, ""}, - {"(*GenDecl).End", Method, 0, ""}, - {"(*GenDecl).Pos", Method, 0, ""}, - {"(*GoStmt).End", Method, 0, ""}, - {"(*GoStmt).Pos", Method, 0, ""}, - {"(*Ident).End", Method, 0, ""}, - {"(*Ident).IsExported", Method, 0, ""}, - {"(*Ident).Pos", Method, 0, ""}, - {"(*Ident).String", Method, 0, ""}, - {"(*IfStmt).End", Method, 0, ""}, - {"(*IfStmt).Pos", Method, 0, ""}, - {"(*ImportSpec).End", Method, 0, ""}, - {"(*ImportSpec).Pos", Method, 0, ""}, - {"(*IncDecStmt).End", Method, 0, ""}, - {"(*IncDecStmt).Pos", Method, 0, ""}, - {"(*IndexExpr).End", Method, 0, ""}, - {"(*IndexExpr).Pos", Method, 0, ""}, - {"(*IndexListExpr).End", Method, 18, ""}, - {"(*IndexListExpr).Pos", Method, 18, ""}, - {"(*InterfaceType).End", Method, 0, ""}, - {"(*InterfaceType).Pos", Method, 0, ""}, - {"(*KeyValueExpr).End", Method, 0, ""}, - {"(*KeyValueExpr).Pos", Method, 0, ""}, - {"(*LabeledStmt).End", Method, 0, ""}, - {"(*LabeledStmt).Pos", Method, 0, ""}, - {"(*MapType).End", Method, 0, ""}, - {"(*MapType).Pos", Method, 0, ""}, - {"(*Object).Pos", Method, 0, ""}, - {"(*Package).End", Method, 0, ""}, - {"(*Package).Pos", Method, 0, ""}, - {"(*ParenExpr).End", Method, 0, ""}, - {"(*ParenExpr).Pos", Method, 0, ""}, - {"(*RangeStmt).End", Method, 0, ""}, - {"(*RangeStmt).Pos", Method, 0, ""}, - {"(*ReturnStmt).End", Method, 0, ""}, - {"(*ReturnStmt).Pos", Method, 0, ""}, - {"(*Scope).Insert", Method, 0, ""}, - {"(*Scope).Lookup", Method, 0, ""}, - {"(*Scope).String", Method, 0, ""}, - {"(*SelectStmt).End", Method, 0, ""}, - {"(*SelectStmt).Pos", Method, 0, ""}, - {"(*SelectorExpr).End", Method, 0, ""}, - {"(*SelectorExpr).Pos", Method, 0, ""}, - {"(*SendStmt).End", Method, 0, ""}, - {"(*SendStmt).Pos", Method, 0, ""}, - {"(*SliceExpr).End", Method, 0, ""}, - {"(*SliceExpr).Pos", Method, 0, ""}, - {"(*StarExpr).End", Method, 0, ""}, - {"(*StarExpr).Pos", Method, 0, ""}, - {"(*StructType).End", Method, 0, ""}, - {"(*StructType).Pos", Method, 0, ""}, - {"(*SwitchStmt).End", Method, 0, ""}, - {"(*SwitchStmt).Pos", Method, 0, ""}, - {"(*TypeAssertExpr).End", Method, 0, ""}, - {"(*TypeAssertExpr).Pos", Method, 0, ""}, - {"(*TypeSpec).End", Method, 0, ""}, - {"(*TypeSpec).Pos", Method, 0, ""}, - {"(*TypeSwitchStmt).End", Method, 0, ""}, - {"(*TypeSwitchStmt).Pos", Method, 0, ""}, - {"(*UnaryExpr).End", Method, 0, ""}, - {"(*UnaryExpr).Pos", Method, 0, ""}, - {"(*ValueSpec).End", Method, 0, ""}, - {"(*ValueSpec).Pos", Method, 0, ""}, - {"(CommentMap).Comments", Method, 1, ""}, - {"(CommentMap).Filter", Method, 1, ""}, - {"(CommentMap).String", Method, 1, ""}, - {"(CommentMap).Update", Method, 1, ""}, - {"(Decl).End", Method, 0, ""}, - {"(Decl).Pos", Method, 0, ""}, - {"(Expr).End", Method, 0, ""}, - {"(Expr).Pos", Method, 0, ""}, - {"(Node).End", Method, 0, ""}, - {"(Node).Pos", Method, 0, ""}, - {"(ObjKind).String", Method, 0, ""}, - {"(Spec).End", Method, 0, ""}, - {"(Spec).Pos", Method, 0, ""}, - {"(Stmt).End", Method, 0, ""}, - {"(Stmt).Pos", Method, 0, ""}, - {"(Visitor).Visit", Method, 0, ""}, - {"ArrayType", Type, 0, ""}, - {"ArrayType.Elt", Field, 0, ""}, - {"ArrayType.Lbrack", Field, 0, ""}, - {"ArrayType.Len", Field, 0, ""}, - {"AssignStmt", Type, 0, ""}, - {"AssignStmt.Lhs", Field, 0, ""}, - {"AssignStmt.Rhs", Field, 0, ""}, - {"AssignStmt.Tok", Field, 0, ""}, - {"AssignStmt.TokPos", Field, 0, ""}, - {"Bad", Const, 0, ""}, - {"BadDecl", Type, 0, ""}, - {"BadDecl.From", Field, 0, ""}, - {"BadDecl.To", Field, 0, ""}, - {"BadExpr", Type, 0, ""}, - {"BadExpr.From", Field, 0, ""}, - {"BadExpr.To", Field, 0, ""}, - {"BadStmt", Type, 0, ""}, - {"BadStmt.From", Field, 0, ""}, - {"BadStmt.To", Field, 0, ""}, - {"BasicLit", Type, 0, ""}, - {"BasicLit.Kind", Field, 0, ""}, - {"BasicLit.Value", Field, 0, ""}, - {"BasicLit.ValueEnd", Field, 26, ""}, - {"BasicLit.ValuePos", Field, 0, ""}, - {"BinaryExpr", Type, 0, ""}, - {"BinaryExpr.Op", Field, 0, ""}, - {"BinaryExpr.OpPos", Field, 0, ""}, - {"BinaryExpr.X", Field, 0, ""}, - {"BinaryExpr.Y", Field, 0, ""}, - {"BlockStmt", Type, 0, ""}, - {"BlockStmt.Lbrace", Field, 0, ""}, - {"BlockStmt.List", Field, 0, ""}, - {"BlockStmt.Rbrace", Field, 0, ""}, - {"BranchStmt", Type, 0, ""}, - {"BranchStmt.Label", Field, 0, ""}, - {"BranchStmt.Tok", Field, 0, ""}, - {"BranchStmt.TokPos", Field, 0, ""}, - {"CallExpr", Type, 0, ""}, - {"CallExpr.Args", Field, 0, ""}, - {"CallExpr.Ellipsis", Field, 0, ""}, - {"CallExpr.Fun", Field, 0, ""}, - {"CallExpr.Lparen", Field, 0, ""}, - {"CallExpr.Rparen", Field, 0, ""}, - {"CaseClause", Type, 0, ""}, - {"CaseClause.Body", Field, 0, ""}, - {"CaseClause.Case", Field, 0, ""}, - {"CaseClause.Colon", Field, 0, ""}, - {"CaseClause.List", Field, 0, ""}, - {"ChanDir", Type, 0, ""}, - {"ChanType", Type, 0, ""}, - {"ChanType.Arrow", Field, 1, ""}, - {"ChanType.Begin", Field, 0, ""}, - {"ChanType.Dir", Field, 0, ""}, - {"ChanType.Value", Field, 0, ""}, - {"CommClause", Type, 0, ""}, - {"CommClause.Body", Field, 0, ""}, - {"CommClause.Case", Field, 0, ""}, - {"CommClause.Colon", Field, 0, ""}, - {"CommClause.Comm", Field, 0, ""}, - {"Comment", Type, 0, ""}, - {"Comment.Slash", Field, 0, ""}, - {"Comment.Text", Field, 0, ""}, - {"CommentGroup", Type, 0, ""}, - {"CommentGroup.List", Field, 0, ""}, - {"CommentMap", Type, 1, ""}, - {"CompositeLit", Type, 0, ""}, - {"CompositeLit.Elts", Field, 0, ""}, - {"CompositeLit.Incomplete", Field, 11, ""}, - {"CompositeLit.Lbrace", Field, 0, ""}, - {"CompositeLit.Rbrace", Field, 0, ""}, - {"CompositeLit.Type", Field, 0, ""}, - {"Con", Const, 0, ""}, - {"DeclStmt", Type, 0, ""}, - {"DeclStmt.Decl", Field, 0, ""}, - {"DeferStmt", Type, 0, ""}, - {"DeferStmt.Call", Field, 0, ""}, - {"DeferStmt.Defer", Field, 0, ""}, - {"Directive", Type, 26, ""}, - {"Directive.Args", Field, 26, ""}, - {"Directive.ArgsPos", Field, 26, ""}, - {"Directive.Name", Field, 26, ""}, - {"Directive.Slash", Field, 26, ""}, - {"Directive.Tool", Field, 26, ""}, - {"DirectiveArg", Type, 26, ""}, - {"DirectiveArg.Arg", Field, 26, ""}, - {"DirectiveArg.Pos", Field, 26, ""}, - {"Ellipsis", Type, 0, ""}, - {"Ellipsis.Ellipsis", Field, 0, ""}, - {"Ellipsis.Elt", Field, 0, ""}, - {"EmptyStmt", Type, 0, ""}, - {"EmptyStmt.Implicit", Field, 5, ""}, - {"EmptyStmt.Semicolon", Field, 0, ""}, - {"ExprStmt", Type, 0, ""}, - {"ExprStmt.X", Field, 0, ""}, - {"Field", Type, 0, ""}, - {"Field.Comment", Field, 0, ""}, - {"Field.Doc", Field, 0, ""}, - {"Field.Names", Field, 0, ""}, - {"Field.Tag", Field, 0, ""}, - {"Field.Type", Field, 0, ""}, - {"FieldFilter", Type, 0, ""}, - {"FieldList", Type, 0, ""}, - {"FieldList.Closing", Field, 0, ""}, - {"FieldList.List", Field, 0, ""}, - {"FieldList.Opening", Field, 0, ""}, - {"File", Type, 0, ""}, - {"File.Comments", Field, 0, ""}, - {"File.Decls", Field, 0, ""}, - {"File.Doc", Field, 0, ""}, - {"File.FileEnd", Field, 20, ""}, - {"File.FileStart", Field, 20, ""}, - {"File.GoVersion", Field, 21, ""}, - {"File.Imports", Field, 0, ""}, - {"File.Name", Field, 0, ""}, - {"File.Package", Field, 0, ""}, - {"File.Scope", Field, 0, ""}, - {"File.Unresolved", Field, 0, ""}, - {"FileExports", Func, 0, "func(src *File) bool"}, - {"Filter", Type, 0, ""}, - {"FilterDecl", Func, 0, "func(decl Decl, f Filter) bool"}, - {"FilterFile", Func, 0, "func(src *File, f Filter) bool"}, - {"FilterFuncDuplicates", Const, 0, ""}, - {"FilterImportDuplicates", Const, 0, ""}, - {"FilterPackage", Func, 0, "func(pkg *Package, f Filter) bool"}, - {"FilterUnassociatedComments", Const, 0, ""}, - {"ForStmt", Type, 0, ""}, - {"ForStmt.Body", Field, 0, ""}, - {"ForStmt.Cond", Field, 0, ""}, - {"ForStmt.For", Field, 0, ""}, - {"ForStmt.Init", Field, 0, ""}, - {"ForStmt.Post", Field, 0, ""}, - {"Fprint", Func, 0, "func(w io.Writer, fset *token.FileSet, x any, f FieldFilter) error"}, - {"Fun", Const, 0, ""}, - {"FuncDecl", Type, 0, ""}, - {"FuncDecl.Body", Field, 0, ""}, - {"FuncDecl.Doc", Field, 0, ""}, - {"FuncDecl.Name", Field, 0, ""}, - {"FuncDecl.Recv", Field, 0, ""}, - {"FuncDecl.Type", Field, 0, ""}, - {"FuncLit", Type, 0, ""}, - {"FuncLit.Body", Field, 0, ""}, - {"FuncLit.Type", Field, 0, ""}, - {"FuncType", Type, 0, ""}, - {"FuncType.Func", Field, 0, ""}, - {"FuncType.Params", Field, 0, ""}, - {"FuncType.Results", Field, 0, ""}, - {"FuncType.TypeParams", Field, 18, ""}, - {"GenDecl", Type, 0, ""}, - {"GenDecl.Doc", Field, 0, ""}, - {"GenDecl.Lparen", Field, 0, ""}, - {"GenDecl.Rparen", Field, 0, ""}, - {"GenDecl.Specs", Field, 0, ""}, - {"GenDecl.Tok", Field, 0, ""}, - {"GenDecl.TokPos", Field, 0, ""}, - {"GoStmt", Type, 0, ""}, - {"GoStmt.Call", Field, 0, ""}, - {"GoStmt.Go", Field, 0, ""}, - {"Ident", Type, 0, ""}, - {"Ident.Name", Field, 0, ""}, - {"Ident.NamePos", Field, 0, ""}, - {"Ident.Obj", Field, 0, ""}, - {"IfStmt", Type, 0, ""}, - {"IfStmt.Body", Field, 0, ""}, - {"IfStmt.Cond", Field, 0, ""}, - {"IfStmt.Else", Field, 0, ""}, - {"IfStmt.If", Field, 0, ""}, - {"IfStmt.Init", Field, 0, ""}, - {"ImportSpec", Type, 0, ""}, - {"ImportSpec.Comment", Field, 0, ""}, - {"ImportSpec.Doc", Field, 0, ""}, - {"ImportSpec.EndPos", Field, 0, ""}, - {"ImportSpec.Name", Field, 0, ""}, - {"ImportSpec.Path", Field, 0, ""}, - {"Importer", Type, 0, ""}, - {"IncDecStmt", Type, 0, ""}, - {"IncDecStmt.Tok", Field, 0, ""}, - {"IncDecStmt.TokPos", Field, 0, ""}, - {"IncDecStmt.X", Field, 0, ""}, - {"IndexExpr", Type, 0, ""}, - {"IndexExpr.Index", Field, 0, ""}, - {"IndexExpr.Lbrack", Field, 0, ""}, - {"IndexExpr.Rbrack", Field, 0, ""}, - {"IndexExpr.X", Field, 0, ""}, - {"IndexListExpr", Type, 18, ""}, - {"IndexListExpr.Indices", Field, 18, ""}, - {"IndexListExpr.Lbrack", Field, 18, ""}, - {"IndexListExpr.Rbrack", Field, 18, ""}, - {"IndexListExpr.X", Field, 18, ""}, - {"Inspect", Func, 0, "func(node Node, f func(Node) bool)"}, - {"InterfaceType", Type, 0, ""}, - {"InterfaceType.Incomplete", Field, 0, ""}, - {"InterfaceType.Interface", Field, 0, ""}, - {"InterfaceType.Methods", Field, 0, ""}, - {"IsExported", Func, 0, "func(name string) bool"}, - {"IsGenerated", Func, 21, "func(file *File) bool"}, - {"KeyValueExpr", Type, 0, ""}, - {"KeyValueExpr.Colon", Field, 0, ""}, - {"KeyValueExpr.Key", Field, 0, ""}, - {"KeyValueExpr.Value", Field, 0, ""}, - {"LabeledStmt", Type, 0, ""}, - {"LabeledStmt.Colon", Field, 0, ""}, - {"LabeledStmt.Label", Field, 0, ""}, - {"LabeledStmt.Stmt", Field, 0, ""}, - {"Lbl", Const, 0, ""}, - {"MapType", Type, 0, ""}, - {"MapType.Key", Field, 0, ""}, - {"MapType.Map", Field, 0, ""}, - {"MapType.Value", Field, 0, ""}, - {"MergeMode", Type, 0, ""}, - {"MergePackageFiles", Func, 0, "func(pkg *Package, mode MergeMode) *File"}, - {"NewCommentMap", Func, 1, "func(fset *token.FileSet, node Node, comments []*CommentGroup) CommentMap"}, - {"NewIdent", Func, 0, "func(name string) *Ident"}, - {"NewObj", Func, 0, "func(kind ObjKind, name string) *Object"}, - {"NewPackage", Func, 0, "func(fset *token.FileSet, files map[string]*File, importer Importer, universe *Scope) (*Package, error)"}, - {"NewScope", Func, 0, "func(outer *Scope) *Scope"}, - {"Node", Type, 0, ""}, - {"NotNilFilter", Func, 0, "func(_ string, v reflect.Value) bool"}, - {"ObjKind", Type, 0, ""}, - {"Object", Type, 0, ""}, - {"Object.Data", Field, 0, ""}, - {"Object.Decl", Field, 0, ""}, - {"Object.Kind", Field, 0, ""}, - {"Object.Name", Field, 0, ""}, - {"Object.Type", Field, 0, ""}, - {"Package", Type, 0, ""}, - {"Package.Files", Field, 0, ""}, - {"Package.Imports", Field, 0, ""}, - {"Package.Name", Field, 0, ""}, - {"Package.Scope", Field, 0, ""}, - {"PackageExports", Func, 0, "func(pkg *Package) bool"}, - {"ParenExpr", Type, 0, ""}, - {"ParenExpr.Lparen", Field, 0, ""}, - {"ParenExpr.Rparen", Field, 0, ""}, - {"ParenExpr.X", Field, 0, ""}, - {"ParseDirective", Func, 26, "func(pos token.Pos, c string) (Directive, bool)"}, - {"Pkg", Const, 0, ""}, - {"Preorder", Func, 23, "func(root Node) iter.Seq[Node]"}, - {"PreorderStack", Func, 25, "func(root Node, stack []Node, f func(n Node, stack []Node) bool)"}, - {"Print", Func, 0, "func(fset *token.FileSet, x any) error"}, - {"RECV", Const, 0, ""}, - {"RangeStmt", Type, 0, ""}, - {"RangeStmt.Body", Field, 0, ""}, - {"RangeStmt.For", Field, 0, ""}, - {"RangeStmt.Key", Field, 0, ""}, - {"RangeStmt.Range", Field, 20, ""}, - {"RangeStmt.Tok", Field, 0, ""}, - {"RangeStmt.TokPos", Field, 0, ""}, - {"RangeStmt.Value", Field, 0, ""}, - {"RangeStmt.X", Field, 0, ""}, - {"ReturnStmt", Type, 0, ""}, - {"ReturnStmt.Results", Field, 0, ""}, - {"ReturnStmt.Return", Field, 0, ""}, - {"SEND", Const, 0, ""}, - {"Scope", Type, 0, ""}, - {"Scope.Objects", Field, 0, ""}, - {"Scope.Outer", Field, 0, ""}, - {"SelectStmt", Type, 0, ""}, - {"SelectStmt.Body", Field, 0, ""}, - {"SelectStmt.Select", Field, 0, ""}, - {"SelectorExpr", Type, 0, ""}, - {"SelectorExpr.Sel", Field, 0, ""}, - {"SelectorExpr.X", Field, 0, ""}, - {"SendStmt", Type, 0, ""}, - {"SendStmt.Arrow", Field, 0, ""}, - {"SendStmt.Chan", Field, 0, ""}, - {"SendStmt.Value", Field, 0, ""}, - {"SliceExpr", Type, 0, ""}, - {"SliceExpr.High", Field, 0, ""}, - {"SliceExpr.Lbrack", Field, 0, ""}, - {"SliceExpr.Low", Field, 0, ""}, - {"SliceExpr.Max", Field, 2, ""}, - {"SliceExpr.Rbrack", Field, 0, ""}, - {"SliceExpr.Slice3", Field, 2, ""}, - {"SliceExpr.X", Field, 0, ""}, - {"SortImports", Func, 0, "func(fset *token.FileSet, f *File)"}, - {"StarExpr", Type, 0, ""}, - {"StarExpr.Star", Field, 0, ""}, - {"StarExpr.X", Field, 0, ""}, - {"StructType", Type, 0, ""}, - {"StructType.Fields", Field, 0, ""}, - {"StructType.Incomplete", Field, 0, ""}, - {"StructType.Struct", Field, 0, ""}, - {"SwitchStmt", Type, 0, ""}, - {"SwitchStmt.Body", Field, 0, ""}, - {"SwitchStmt.Init", Field, 0, ""}, - {"SwitchStmt.Switch", Field, 0, ""}, - {"SwitchStmt.Tag", Field, 0, ""}, - {"Typ", Const, 0, ""}, - {"TypeAssertExpr", Type, 0, ""}, - {"TypeAssertExpr.Lparen", Field, 2, ""}, - {"TypeAssertExpr.Rparen", Field, 2, ""}, - {"TypeAssertExpr.Type", Field, 0, ""}, - {"TypeAssertExpr.X", Field, 0, ""}, - {"TypeSpec", Type, 0, ""}, - {"TypeSpec.Assign", Field, 9, ""}, - {"TypeSpec.Comment", Field, 0, ""}, - {"TypeSpec.Doc", Field, 0, ""}, - {"TypeSpec.Name", Field, 0, ""}, - {"TypeSpec.Type", Field, 0, ""}, - {"TypeSpec.TypeParams", Field, 18, ""}, - {"TypeSwitchStmt", Type, 0, ""}, - {"TypeSwitchStmt.Assign", Field, 0, ""}, - {"TypeSwitchStmt.Body", Field, 0, ""}, - {"TypeSwitchStmt.Init", Field, 0, ""}, - {"TypeSwitchStmt.Switch", Field, 0, ""}, - {"UnaryExpr", Type, 0, ""}, - {"UnaryExpr.Op", Field, 0, ""}, - {"UnaryExpr.OpPos", Field, 0, ""}, - {"UnaryExpr.X", Field, 0, ""}, - {"Unparen", Func, 22, "func(e Expr) Expr"}, - {"ValueSpec", Type, 0, ""}, - {"ValueSpec.Comment", Field, 0, ""}, - {"ValueSpec.Doc", Field, 0, ""}, - {"ValueSpec.Names", Field, 0, ""}, - {"ValueSpec.Type", Field, 0, ""}, - {"ValueSpec.Values", Field, 0, ""}, - {"Var", Const, 0, ""}, - {"Visitor", Type, 0, ""}, - {"Walk", Func, 0, "func(v Visitor, node Node)"}, - }, - "go/build": { - {"(*Context).Import", Method, 0, ""}, - {"(*Context).ImportDir", Method, 0, ""}, - {"(*Context).MatchFile", Method, 2, ""}, - {"(*Context).SrcDirs", Method, 0, ""}, - {"(*MultiplePackageError).Error", Method, 4, ""}, - {"(*NoGoError).Error", Method, 0, ""}, - {"(*Package).IsCommand", Method, 0, ""}, - {"AllowBinary", Const, 0, ""}, - {"ArchChar", Func, 0, "func(goarch string) (string, error)"}, - {"Context", Type, 0, ""}, - {"Context.BuildTags", Field, 0, ""}, - {"Context.CgoEnabled", Field, 0, ""}, - {"Context.Compiler", Field, 0, ""}, - {"Context.Dir", Field, 14, ""}, - {"Context.GOARCH", Field, 0, ""}, - {"Context.GOOS", Field, 0, ""}, - {"Context.GOPATH", Field, 0, ""}, - {"Context.GOROOT", Field, 0, ""}, - {"Context.HasSubdir", Field, 0, ""}, - {"Context.InstallSuffix", Field, 1, ""}, - {"Context.IsAbsPath", Field, 0, ""}, - {"Context.IsDir", Field, 0, ""}, - {"Context.JoinPath", Field, 0, ""}, - {"Context.OpenFile", Field, 0, ""}, - {"Context.ReadDir", Field, 0, ""}, - {"Context.ReleaseTags", Field, 1, ""}, - {"Context.SplitPathList", Field, 0, ""}, - {"Context.ToolTags", Field, 17, ""}, - {"Context.UseAllFiles", Field, 0, ""}, - {"Default", Var, 0, ""}, - {"Directive", Type, 21, ""}, - {"Directive.Pos", Field, 21, ""}, - {"Directive.Text", Field, 21, ""}, - {"FindOnly", Const, 0, ""}, - {"IgnoreVendor", Const, 6, ""}, - {"Import", Func, 0, "func(path string, srcDir string, mode ImportMode) (*Package, error)"}, - {"ImportComment", Const, 4, ""}, - {"ImportDir", Func, 0, "func(dir string, mode ImportMode) (*Package, error)"}, - {"ImportMode", Type, 0, ""}, - {"IsLocalImport", Func, 0, "func(path string) bool"}, - {"MultiplePackageError", Type, 4, ""}, - {"MultiplePackageError.Dir", Field, 4, ""}, - {"MultiplePackageError.Files", Field, 4, ""}, - {"MultiplePackageError.Packages", Field, 4, ""}, - {"NoGoError", Type, 0, ""}, - {"NoGoError.Dir", Field, 0, ""}, - {"Package", Type, 0, ""}, - {"Package.AllTags", Field, 2, ""}, - {"Package.BinDir", Field, 0, ""}, - {"Package.BinaryOnly", Field, 7, ""}, - {"Package.CFiles", Field, 0, ""}, - {"Package.CXXFiles", Field, 2, ""}, - {"Package.CgoCFLAGS", Field, 0, ""}, - {"Package.CgoCPPFLAGS", Field, 2, ""}, - {"Package.CgoCXXFLAGS", Field, 2, ""}, - {"Package.CgoFFLAGS", Field, 7, ""}, - {"Package.CgoFiles", Field, 0, ""}, - {"Package.CgoLDFLAGS", Field, 0, ""}, - {"Package.CgoPkgConfig", Field, 0, ""}, - {"Package.ConflictDir", Field, 2, ""}, - {"Package.Dir", Field, 0, ""}, - {"Package.Directives", Field, 21, ""}, - {"Package.Doc", Field, 0, ""}, - {"Package.EmbedPatternPos", Field, 16, ""}, - {"Package.EmbedPatterns", Field, 16, ""}, - {"Package.FFiles", Field, 7, ""}, - {"Package.GoFiles", Field, 0, ""}, - {"Package.Goroot", Field, 0, ""}, - {"Package.HFiles", Field, 0, ""}, - {"Package.IgnoredGoFiles", Field, 1, ""}, - {"Package.IgnoredOtherFiles", Field, 16, ""}, - {"Package.ImportComment", Field, 4, ""}, - {"Package.ImportPath", Field, 0, ""}, - {"Package.ImportPos", Field, 0, ""}, - {"Package.Imports", Field, 0, ""}, - {"Package.InvalidGoFiles", Field, 6, ""}, - {"Package.MFiles", Field, 3, ""}, - {"Package.Name", Field, 0, ""}, - {"Package.PkgObj", Field, 0, ""}, - {"Package.PkgRoot", Field, 0, ""}, - {"Package.PkgTargetRoot", Field, 5, ""}, - {"Package.Root", Field, 0, ""}, - {"Package.SFiles", Field, 0, ""}, - {"Package.SrcRoot", Field, 0, ""}, - {"Package.SwigCXXFiles", Field, 1, ""}, - {"Package.SwigFiles", Field, 1, ""}, - {"Package.SysoFiles", Field, 0, ""}, - {"Package.TestDirectives", Field, 21, ""}, - {"Package.TestEmbedPatternPos", Field, 16, ""}, - {"Package.TestEmbedPatterns", Field, 16, ""}, - {"Package.TestGoFiles", Field, 0, ""}, - {"Package.TestImportPos", Field, 0, ""}, - {"Package.TestImports", Field, 0, ""}, - {"Package.XTestDirectives", Field, 21, ""}, - {"Package.XTestEmbedPatternPos", Field, 16, ""}, - {"Package.XTestEmbedPatterns", Field, 16, ""}, - {"Package.XTestGoFiles", Field, 0, ""}, - {"Package.XTestImportPos", Field, 0, ""}, - {"Package.XTestImports", Field, 0, ""}, - {"ToolDir", Var, 0, ""}, - }, - "go/build/constraint": { - {"(*AndExpr).Eval", Method, 16, ""}, - {"(*AndExpr).String", Method, 16, ""}, - {"(*NotExpr).Eval", Method, 16, ""}, - {"(*NotExpr).String", Method, 16, ""}, - {"(*OrExpr).Eval", Method, 16, ""}, - {"(*OrExpr).String", Method, 16, ""}, - {"(*SyntaxError).Error", Method, 16, ""}, - {"(*TagExpr).Eval", Method, 16, ""}, - {"(*TagExpr).String", Method, 16, ""}, - {"(Expr).Eval", Method, 16, ""}, - {"(Expr).String", Method, 16, ""}, - {"AndExpr", Type, 16, ""}, - {"AndExpr.X", Field, 16, ""}, - {"AndExpr.Y", Field, 16, ""}, - {"GoVersion", Func, 21, "func(x Expr) string"}, - {"IsGoBuild", Func, 16, "func(line string) bool"}, - {"IsPlusBuild", Func, 16, "func(line string) bool"}, - {"NotExpr", Type, 16, ""}, - {"NotExpr.X", Field, 16, ""}, - {"OrExpr", Type, 16, ""}, - {"OrExpr.X", Field, 16, ""}, - {"OrExpr.Y", Field, 16, ""}, - {"Parse", Func, 16, "func(line string) (Expr, error)"}, - {"PlusBuildLines", Func, 16, "func(x Expr) ([]string, error)"}, - {"SyntaxError", Type, 16, ""}, - {"SyntaxError.Err", Field, 16, ""}, - {"SyntaxError.Offset", Field, 16, ""}, - {"TagExpr", Type, 16, ""}, - {"TagExpr.Tag", Field, 16, ""}, - }, - "go/constant": { - {"(Kind).String", Method, 18, ""}, - {"(Value).ExactString", Method, 6, ""}, - {"(Value).Kind", Method, 5, ""}, - {"(Value).String", Method, 5, ""}, - {"BinaryOp", Func, 5, "func(x_ Value, op token.Token, y_ Value) Value"}, - {"BitLen", Func, 5, "func(x Value) int"}, - {"Bool", Const, 5, ""}, - {"BoolVal", Func, 5, "func(x Value) bool"}, - {"Bytes", Func, 5, "func(x Value) []byte"}, - {"Compare", Func, 5, "func(x_ Value, op token.Token, y_ Value) bool"}, - {"Complex", Const, 5, ""}, - {"Denom", Func, 5, "func(x Value) Value"}, - {"Float", Const, 5, ""}, - {"Float32Val", Func, 5, "func(x Value) (float32, bool)"}, - {"Float64Val", Func, 5, "func(x Value) (float64, bool)"}, - {"Imag", Func, 5, "func(x Value) Value"}, - {"Int", Const, 5, ""}, - {"Int64Val", Func, 5, "func(x Value) (int64, bool)"}, - {"Kind", Type, 5, ""}, - {"Make", Func, 13, "func(x any) Value"}, - {"MakeBool", Func, 5, "func(b bool) Value"}, - {"MakeFloat64", Func, 5, "func(x float64) Value"}, - {"MakeFromBytes", Func, 5, "func(bytes []byte) Value"}, - {"MakeFromLiteral", Func, 5, "func(lit string, tok token.Token, zero uint) Value"}, - {"MakeImag", Func, 5, "func(x Value) Value"}, - {"MakeInt64", Func, 5, "func(x int64) Value"}, - {"MakeString", Func, 5, "func(s string) Value"}, - {"MakeUint64", Func, 5, "func(x uint64) Value"}, - {"MakeUnknown", Func, 5, "func() Value"}, - {"Num", Func, 5, "func(x Value) Value"}, - {"Real", Func, 5, "func(x Value) Value"}, - {"Shift", Func, 5, "func(x Value, op token.Token, s uint) Value"}, - {"Sign", Func, 5, "func(x Value) int"}, - {"String", Const, 5, ""}, - {"StringVal", Func, 5, "func(x Value) string"}, - {"ToComplex", Func, 6, "func(x Value) Value"}, - {"ToFloat", Func, 6, "func(x Value) Value"}, - {"ToInt", Func, 6, "func(x Value) Value"}, - {"Uint64Val", Func, 5, "func(x Value) (uint64, bool)"}, - {"UnaryOp", Func, 5, "func(op token.Token, y Value, prec uint) Value"}, - {"Unknown", Const, 5, ""}, - {"Val", Func, 13, "func(x Value) any"}, - }, - "go/doc": { - {"(*Package).Filter", Method, 0, ""}, - {"(*Package).HTML", Method, 19, ""}, - {"(*Package).Markdown", Method, 19, ""}, - {"(*Package).Parser", Method, 19, ""}, - {"(*Package).Printer", Method, 19, ""}, - {"(*Package).Synopsis", Method, 19, ""}, - {"(*Package).Text", Method, 19, ""}, - {"AllDecls", Const, 0, ""}, - {"AllMethods", Const, 0, ""}, - {"Example", Type, 0, ""}, - {"Example.Code", Field, 0, ""}, - {"Example.Comments", Field, 0, ""}, - {"Example.Doc", Field, 0, ""}, - {"Example.EmptyOutput", Field, 1, ""}, - {"Example.Name", Field, 0, ""}, - {"Example.Order", Field, 1, ""}, - {"Example.Output", Field, 0, ""}, - {"Example.Play", Field, 1, ""}, - {"Example.Suffix", Field, 14, ""}, - {"Example.Unordered", Field, 7, ""}, - {"Examples", Func, 0, "func(testFiles ...*ast.File) []*Example"}, - {"Filter", Type, 0, ""}, - {"Func", Type, 0, ""}, - {"Func.Decl", Field, 0, ""}, - {"Func.Doc", Field, 0, ""}, - {"Func.Examples", Field, 14, ""}, - {"Func.Level", Field, 0, ""}, - {"Func.Name", Field, 0, ""}, - {"Func.Orig", Field, 0, ""}, - {"Func.Recv", Field, 0, ""}, - {"IllegalPrefixes", Var, 1, ""}, - {"IsPredeclared", Func, 8, "func(s string) bool"}, - {"Mode", Type, 0, ""}, - {"New", Func, 0, "func(pkg *ast.Package, importPath string, mode Mode) *Package"}, - {"NewFromFiles", Func, 14, "func(fset *token.FileSet, files []*ast.File, importPath string, opts ...any) (*Package, error)"}, - {"Note", Type, 1, ""}, - {"Note.Body", Field, 1, ""}, - {"Note.End", Field, 1, ""}, - {"Note.Pos", Field, 1, ""}, - {"Note.UID", Field, 1, ""}, - {"Package", Type, 0, ""}, - {"Package.Bugs", Field, 0, ""}, - {"Package.Consts", Field, 0, ""}, - {"Package.Doc", Field, 0, ""}, - {"Package.Examples", Field, 14, ""}, - {"Package.Filenames", Field, 0, ""}, - {"Package.Funcs", Field, 0, ""}, - {"Package.ImportPath", Field, 0, ""}, - {"Package.Imports", Field, 0, ""}, - {"Package.Name", Field, 0, ""}, - {"Package.Notes", Field, 1, ""}, - {"Package.Types", Field, 0, ""}, - {"Package.Vars", Field, 0, ""}, - {"PreserveAST", Const, 12, ""}, - {"Synopsis", Func, 0, "func(text string) string"}, - {"ToHTML", Func, 0, "func(w io.Writer, text string, words map[string]string)"}, - {"ToText", Func, 0, "func(w io.Writer, text string, prefix string, codePrefix string, width int)"}, - {"Type", Type, 0, ""}, - {"Type.Consts", Field, 0, ""}, - {"Type.Decl", Field, 0, ""}, - {"Type.Doc", Field, 0, ""}, - {"Type.Examples", Field, 14, ""}, - {"Type.Funcs", Field, 0, ""}, - {"Type.Methods", Field, 0, ""}, - {"Type.Name", Field, 0, ""}, - {"Type.Vars", Field, 0, ""}, - {"Value", Type, 0, ""}, - {"Value.Decl", Field, 0, ""}, - {"Value.Doc", Field, 0, ""}, - {"Value.Names", Field, 0, ""}, - }, - "go/doc/comment": { - {"(*DocLink).DefaultURL", Method, 19, ""}, - {"(*Heading).DefaultID", Method, 19, ""}, - {"(*List).BlankBefore", Method, 19, ""}, - {"(*List).BlankBetween", Method, 19, ""}, - {"(*Parser).Parse", Method, 19, ""}, - {"(*Printer).Comment", Method, 19, ""}, - {"(*Printer).HTML", Method, 19, ""}, - {"(*Printer).Markdown", Method, 19, ""}, - {"(*Printer).Text", Method, 19, ""}, - {"Code", Type, 19, ""}, - {"Code.Text", Field, 19, ""}, - {"DefaultLookupPackage", Func, 19, "func(name string) (importPath string, ok bool)"}, - {"Doc", Type, 19, ""}, - {"Doc.Content", Field, 19, ""}, - {"Doc.Links", Field, 19, ""}, - {"DocLink", Type, 19, ""}, - {"DocLink.ImportPath", Field, 19, ""}, - {"DocLink.Name", Field, 19, ""}, - {"DocLink.Recv", Field, 19, ""}, - {"DocLink.Text", Field, 19, ""}, - {"Heading", Type, 19, ""}, - {"Heading.Text", Field, 19, ""}, - {"Italic", Type, 19, ""}, - {"Link", Type, 19, ""}, - {"Link.Auto", Field, 19, ""}, - {"Link.Text", Field, 19, ""}, - {"Link.URL", Field, 19, ""}, - {"LinkDef", Type, 19, ""}, - {"LinkDef.Text", Field, 19, ""}, - {"LinkDef.URL", Field, 19, ""}, - {"LinkDef.Used", Field, 19, ""}, - {"List", Type, 19, ""}, - {"List.ForceBlankBefore", Field, 19, ""}, - {"List.ForceBlankBetween", Field, 19, ""}, - {"List.Items", Field, 19, ""}, - {"ListItem", Type, 19, ""}, - {"ListItem.Content", Field, 19, ""}, - {"ListItem.Number", Field, 19, ""}, - {"Paragraph", Type, 19, ""}, - {"Paragraph.Text", Field, 19, ""}, - {"Parser", Type, 19, ""}, - {"Parser.LookupPackage", Field, 19, ""}, - {"Parser.LookupSym", Field, 19, ""}, - {"Parser.Words", Field, 19, ""}, - {"Plain", Type, 19, ""}, - {"Printer", Type, 19, ""}, - {"Printer.DocLinkBaseURL", Field, 19, ""}, - {"Printer.DocLinkURL", Field, 19, ""}, - {"Printer.HeadingID", Field, 19, ""}, - {"Printer.HeadingLevel", Field, 19, ""}, - {"Printer.TextCodePrefix", Field, 19, ""}, - {"Printer.TextPrefix", Field, 19, ""}, - {"Printer.TextWidth", Field, 19, ""}, - }, - "go/format": { - {"Node", Func, 1, "func(dst io.Writer, fset *token.FileSet, node any) error"}, - {"Source", Func, 1, "func(src []byte) ([]byte, error)"}, - }, - "go/importer": { - {"Default", Func, 5, "func() types.Importer"}, - {"For", Func, 5, "func(compiler string, lookup Lookup) types.Importer"}, - {"ForCompiler", Func, 12, "func(fset *token.FileSet, compiler string, lookup Lookup) types.Importer"}, - {"Lookup", Type, 5, ""}, - }, - "go/parser": { - {"AllErrors", Const, 1, ""}, - {"DeclarationErrors", Const, 0, ""}, - {"ImportsOnly", Const, 0, ""}, - {"Mode", Type, 0, ""}, - {"PackageClauseOnly", Const, 0, ""}, - {"ParseComments", Const, 0, ""}, - {"ParseDir", Func, 0, "func(fset *token.FileSet, path string, filter func(fs.FileInfo) bool, mode Mode) (pkgs map[string]*ast.Package, first error)"}, - {"ParseExpr", Func, 0, "func(x string) (ast.Expr, error)"}, - {"ParseExprFrom", Func, 5, "func(fset *token.FileSet, filename string, src any, mode Mode) (expr ast.Expr, err error)"}, - {"ParseFile", Func, 0, "func(fset *token.FileSet, filename string, src any, mode Mode) (f *ast.File, err error)"}, - {"SkipObjectResolution", Const, 17, ""}, - {"SpuriousErrors", Const, 0, ""}, - {"Trace", Const, 0, ""}, - }, - "go/printer": { - {"(*Config).Fprint", Method, 0, ""}, - {"CommentedNode", Type, 0, ""}, - {"CommentedNode.Comments", Field, 0, ""}, - {"CommentedNode.Node", Field, 0, ""}, - {"Config", Type, 0, ""}, - {"Config.Indent", Field, 1, ""}, - {"Config.Mode", Field, 0, ""}, - {"Config.Tabwidth", Field, 0, ""}, - {"Fprint", Func, 0, "func(output io.Writer, fset *token.FileSet, node any) error"}, - {"Mode", Type, 0, ""}, - {"RawFormat", Const, 0, ""}, - {"SourcePos", Const, 0, ""}, - {"TabIndent", Const, 0, ""}, - {"UseSpaces", Const, 0, ""}, - }, - "go/scanner": { - {"(*ErrorList).Add", Method, 0, ""}, - {"(*ErrorList).RemoveMultiples", Method, 0, ""}, - {"(*ErrorList).Reset", Method, 0, ""}, - {"(*Scanner).Init", Method, 0, ""}, - {"(*Scanner).Scan", Method, 0, ""}, - {"(Error).Error", Method, 0, ""}, - {"(ErrorList).Err", Method, 0, ""}, - {"(ErrorList).Error", Method, 0, ""}, - {"(ErrorList).Len", Method, 0, ""}, - {"(ErrorList).Less", Method, 0, ""}, - {"(ErrorList).Sort", Method, 0, ""}, - {"(ErrorList).Swap", Method, 0, ""}, - {"Error", Type, 0, ""}, - {"Error.Msg", Field, 0, ""}, - {"Error.Pos", Field, 0, ""}, - {"ErrorHandler", Type, 0, ""}, - {"ErrorList", Type, 0, ""}, - {"Mode", Type, 0, ""}, - {"PrintError", Func, 0, "func(w io.Writer, err error)"}, - {"ScanComments", Const, 0, ""}, - {"Scanner", Type, 0, ""}, - {"Scanner.ErrorCount", Field, 0, ""}, - }, - "go/token": { - {"(*File).AddLine", Method, 0, ""}, - {"(*File).AddLineColumnInfo", Method, 11, ""}, - {"(*File).AddLineInfo", Method, 0, ""}, - {"(*File).Base", Method, 0, ""}, - {"(*File).End", Method, 26, ""}, - {"(*File).Line", Method, 0, ""}, - {"(*File).LineCount", Method, 0, ""}, - {"(*File).LineStart", Method, 12, ""}, - {"(*File).Lines", Method, 21, ""}, - {"(*File).MergeLine", Method, 2, ""}, - {"(*File).Name", Method, 0, ""}, - {"(*File).Offset", Method, 0, ""}, - {"(*File).Pos", Method, 0, ""}, - {"(*File).Position", Method, 0, ""}, - {"(*File).PositionFor", Method, 4, ""}, - {"(*File).SetLines", Method, 0, ""}, - {"(*File).SetLinesForContent", Method, 0, ""}, - {"(*File).Size", Method, 0, ""}, - {"(*FileSet).AddExistingFiles", Method, 25, ""}, - {"(*FileSet).AddFile", Method, 0, ""}, - {"(*FileSet).Base", Method, 0, ""}, - {"(*FileSet).File", Method, 0, ""}, - {"(*FileSet).Iterate", Method, 0, ""}, - {"(*FileSet).Position", Method, 0, ""}, - {"(*FileSet).PositionFor", Method, 4, ""}, - {"(*FileSet).Read", Method, 0, ""}, - {"(*FileSet).RemoveFile", Method, 20, ""}, - {"(*FileSet).Write", Method, 0, ""}, - {"(*Position).IsValid", Method, 0, ""}, - {"(Pos).IsValid", Method, 0, ""}, - {"(Position).String", Method, 0, ""}, - {"(Token).IsKeyword", Method, 0, ""}, - {"(Token).IsLiteral", Method, 0, ""}, - {"(Token).IsOperator", Method, 0, ""}, - {"(Token).Precedence", Method, 0, ""}, - {"(Token).String", Method, 0, ""}, - {"ADD", Const, 0, ""}, - {"ADD_ASSIGN", Const, 0, ""}, - {"AND", Const, 0, ""}, - {"AND_ASSIGN", Const, 0, ""}, - {"AND_NOT", Const, 0, ""}, - {"AND_NOT_ASSIGN", Const, 0, ""}, - {"ARROW", Const, 0, ""}, - {"ASSIGN", Const, 0, ""}, - {"BREAK", Const, 0, ""}, - {"CASE", Const, 0, ""}, - {"CHAN", Const, 0, ""}, - {"CHAR", Const, 0, ""}, - {"COLON", Const, 0, ""}, - {"COMMA", Const, 0, ""}, - {"COMMENT", Const, 0, ""}, - {"CONST", Const, 0, ""}, - {"CONTINUE", Const, 0, ""}, - {"DEC", Const, 0, ""}, - {"DEFAULT", Const, 0, ""}, - {"DEFER", Const, 0, ""}, - {"DEFINE", Const, 0, ""}, - {"ELLIPSIS", Const, 0, ""}, - {"ELSE", Const, 0, ""}, - {"EOF", Const, 0, ""}, - {"EQL", Const, 0, ""}, - {"FALLTHROUGH", Const, 0, ""}, - {"FLOAT", Const, 0, ""}, - {"FOR", Const, 0, ""}, - {"FUNC", Const, 0, ""}, - {"File", Type, 0, ""}, - {"FileSet", Type, 0, ""}, - {"GEQ", Const, 0, ""}, - {"GO", Const, 0, ""}, - {"GOTO", Const, 0, ""}, - {"GTR", Const, 0, ""}, - {"HighestPrec", Const, 0, ""}, - {"IDENT", Const, 0, ""}, - {"IF", Const, 0, ""}, - {"ILLEGAL", Const, 0, ""}, - {"IMAG", Const, 0, ""}, - {"IMPORT", Const, 0, ""}, - {"INC", Const, 0, ""}, - {"INT", Const, 0, ""}, - {"INTERFACE", Const, 0, ""}, - {"IsExported", Func, 13, "func(name string) bool"}, - {"IsIdentifier", Func, 13, "func(name string) bool"}, - {"IsKeyword", Func, 13, "func(name string) bool"}, - {"LAND", Const, 0, ""}, - {"LBRACE", Const, 0, ""}, - {"LBRACK", Const, 0, ""}, - {"LEQ", Const, 0, ""}, - {"LOR", Const, 0, ""}, - {"LPAREN", Const, 0, ""}, - {"LSS", Const, 0, ""}, - {"Lookup", Func, 0, "func(ident string) Token"}, - {"LowestPrec", Const, 0, ""}, - {"MAP", Const, 0, ""}, - {"MUL", Const, 0, ""}, - {"MUL_ASSIGN", Const, 0, ""}, - {"NEQ", Const, 0, ""}, - {"NOT", Const, 0, ""}, - {"NewFileSet", Func, 0, "func() *FileSet"}, - {"NoPos", Const, 0, ""}, - {"OR", Const, 0, ""}, - {"OR_ASSIGN", Const, 0, ""}, - {"PACKAGE", Const, 0, ""}, - {"PERIOD", Const, 0, ""}, - {"Pos", Type, 0, ""}, - {"Position", Type, 0, ""}, - {"Position.Column", Field, 0, ""}, - {"Position.Filename", Field, 0, ""}, - {"Position.Line", Field, 0, ""}, - {"Position.Offset", Field, 0, ""}, - {"QUO", Const, 0, ""}, - {"QUO_ASSIGN", Const, 0, ""}, - {"RANGE", Const, 0, ""}, - {"RBRACE", Const, 0, ""}, - {"RBRACK", Const, 0, ""}, - {"REM", Const, 0, ""}, - {"REM_ASSIGN", Const, 0, ""}, - {"RETURN", Const, 0, ""}, - {"RPAREN", Const, 0, ""}, - {"SELECT", Const, 0, ""}, - {"SEMICOLON", Const, 0, ""}, - {"SHL", Const, 0, ""}, - {"SHL_ASSIGN", Const, 0, ""}, - {"SHR", Const, 0, ""}, - {"SHR_ASSIGN", Const, 0, ""}, - {"STRING", Const, 0, ""}, - {"STRUCT", Const, 0, ""}, - {"SUB", Const, 0, ""}, - {"SUB_ASSIGN", Const, 0, ""}, - {"SWITCH", Const, 0, ""}, - {"TILDE", Const, 18, ""}, - {"TYPE", Const, 0, ""}, - {"Token", Type, 0, ""}, - {"UnaryPrec", Const, 0, ""}, - {"VAR", Const, 0, ""}, - {"XOR", Const, 0, ""}, - {"XOR_ASSIGN", Const, 0, ""}, - }, - "go/types": { - {"(*Alias).Obj", Method, 22, ""}, - {"(*Alias).Origin", Method, 23, ""}, - {"(*Alias).Rhs", Method, 23, ""}, - {"(*Alias).SetTypeParams", Method, 23, ""}, - {"(*Alias).String", Method, 22, ""}, - {"(*Alias).TypeArgs", Method, 23, ""}, - {"(*Alias).TypeParams", Method, 23, ""}, - {"(*Alias).Underlying", Method, 22, ""}, - {"(*ArgumentError).Error", Method, 18, ""}, - {"(*ArgumentError).Unwrap", Method, 18, ""}, - {"(*Array).Elem", Method, 5, ""}, - {"(*Array).Len", Method, 5, ""}, - {"(*Array).String", Method, 5, ""}, - {"(*Array).Underlying", Method, 5, ""}, - {"(*Basic).Info", Method, 5, ""}, - {"(*Basic).Kind", Method, 5, ""}, - {"(*Basic).Name", Method, 5, ""}, - {"(*Basic).String", Method, 5, ""}, - {"(*Basic).Underlying", Method, 5, ""}, - {"(*Builtin).Exported", Method, 5, ""}, - {"(*Builtin).Id", Method, 5, ""}, - {"(*Builtin).Name", Method, 5, ""}, - {"(*Builtin).Parent", Method, 5, ""}, - {"(*Builtin).Pkg", Method, 5, ""}, - {"(*Builtin).Pos", Method, 5, ""}, - {"(*Builtin).String", Method, 5, ""}, - {"(*Builtin).Type", Method, 5, ""}, - {"(*Chan).Dir", Method, 5, ""}, - {"(*Chan).Elem", Method, 5, ""}, - {"(*Chan).String", Method, 5, ""}, - {"(*Chan).Underlying", Method, 5, ""}, - {"(*Checker).Files", Method, 5, ""}, - {"(*Config).Check", Method, 5, ""}, - {"(*Const).Exported", Method, 5, ""}, - {"(*Const).Id", Method, 5, ""}, - {"(*Const).Name", Method, 5, ""}, - {"(*Const).Parent", Method, 5, ""}, - {"(*Const).Pkg", Method, 5, ""}, - {"(*Const).Pos", Method, 5, ""}, - {"(*Const).String", Method, 5, ""}, - {"(*Const).Type", Method, 5, ""}, - {"(*Const).Val", Method, 5, ""}, - {"(*Func).Exported", Method, 5, ""}, - {"(*Func).FullName", Method, 5, ""}, - {"(*Func).Id", Method, 5, ""}, - {"(*Func).Name", Method, 5, ""}, - {"(*Func).Origin", Method, 19, ""}, - {"(*Func).Parent", Method, 5, ""}, - {"(*Func).Pkg", Method, 5, ""}, - {"(*Func).Pos", Method, 5, ""}, - {"(*Func).Scope", Method, 5, ""}, - {"(*Func).Signature", Method, 23, ""}, - {"(*Func).String", Method, 5, ""}, - {"(*Func).Type", Method, 5, ""}, - {"(*Info).ObjectOf", Method, 5, ""}, - {"(*Info).PkgNameOf", Method, 22, ""}, - {"(*Info).TypeOf", Method, 5, ""}, - {"(*Initializer).String", Method, 5, ""}, - {"(*Interface).Complete", Method, 5, ""}, - {"(*Interface).Embedded", Method, 5, ""}, - {"(*Interface).EmbeddedType", Method, 11, ""}, - {"(*Interface).EmbeddedTypes", Method, 24, ""}, - {"(*Interface).Empty", Method, 5, ""}, - {"(*Interface).ExplicitMethod", Method, 5, ""}, - {"(*Interface).ExplicitMethods", Method, 24, ""}, - {"(*Interface).IsComparable", Method, 18, ""}, - {"(*Interface).IsImplicit", Method, 18, ""}, - {"(*Interface).IsMethodSet", Method, 18, ""}, - {"(*Interface).MarkImplicit", Method, 18, ""}, - {"(*Interface).Method", Method, 5, ""}, - {"(*Interface).Methods", Method, 24, ""}, - {"(*Interface).NumEmbeddeds", Method, 5, ""}, - {"(*Interface).NumExplicitMethods", Method, 5, ""}, - {"(*Interface).NumMethods", Method, 5, ""}, - {"(*Interface).String", Method, 5, ""}, - {"(*Interface).Underlying", Method, 5, ""}, - {"(*Label).Exported", Method, 5, ""}, - {"(*Label).Id", Method, 5, ""}, - {"(*Label).Name", Method, 5, ""}, - {"(*Label).Parent", Method, 5, ""}, - {"(*Label).Pkg", Method, 5, ""}, - {"(*Label).Pos", Method, 5, ""}, - {"(*Label).String", Method, 5, ""}, - {"(*Label).Type", Method, 5, ""}, - {"(*Map).Elem", Method, 5, ""}, - {"(*Map).Key", Method, 5, ""}, - {"(*Map).String", Method, 5, ""}, - {"(*Map).Underlying", Method, 5, ""}, - {"(*MethodSet).At", Method, 5, ""}, - {"(*MethodSet).Len", Method, 5, ""}, - {"(*MethodSet).Lookup", Method, 5, ""}, - {"(*MethodSet).Methods", Method, 24, ""}, - {"(*MethodSet).String", Method, 5, ""}, - {"(*Named).AddMethod", Method, 5, ""}, - {"(*Named).Method", Method, 5, ""}, - {"(*Named).Methods", Method, 24, ""}, - {"(*Named).NumMethods", Method, 5, ""}, - {"(*Named).Obj", Method, 5, ""}, - {"(*Named).Origin", Method, 18, ""}, - {"(*Named).SetTypeParams", Method, 18, ""}, - {"(*Named).SetUnderlying", Method, 5, ""}, - {"(*Named).String", Method, 5, ""}, - {"(*Named).TypeArgs", Method, 18, ""}, - {"(*Named).TypeParams", Method, 18, ""}, - {"(*Named).Underlying", Method, 5, ""}, - {"(*Nil).Exported", Method, 5, ""}, - {"(*Nil).Id", Method, 5, ""}, - {"(*Nil).Name", Method, 5, ""}, - {"(*Nil).Parent", Method, 5, ""}, - {"(*Nil).Pkg", Method, 5, ""}, - {"(*Nil).Pos", Method, 5, ""}, - {"(*Nil).String", Method, 5, ""}, - {"(*Nil).Type", Method, 5, ""}, - {"(*Package).Complete", Method, 5, ""}, - {"(*Package).GoVersion", Method, 21, ""}, - {"(*Package).Imports", Method, 5, ""}, - {"(*Package).MarkComplete", Method, 5, ""}, - {"(*Package).Name", Method, 5, ""}, - {"(*Package).Path", Method, 5, ""}, - {"(*Package).Scope", Method, 5, ""}, - {"(*Package).SetImports", Method, 5, ""}, - {"(*Package).SetName", Method, 6, ""}, - {"(*Package).String", Method, 5, ""}, - {"(*PkgName).Exported", Method, 5, ""}, - {"(*PkgName).Id", Method, 5, ""}, - {"(*PkgName).Imported", Method, 5, ""}, - {"(*PkgName).Name", Method, 5, ""}, - {"(*PkgName).Parent", Method, 5, ""}, - {"(*PkgName).Pkg", Method, 5, ""}, - {"(*PkgName).Pos", Method, 5, ""}, - {"(*PkgName).String", Method, 5, ""}, - {"(*PkgName).Type", Method, 5, ""}, - {"(*Pointer).Elem", Method, 5, ""}, - {"(*Pointer).String", Method, 5, ""}, - {"(*Pointer).Underlying", Method, 5, ""}, - {"(*Scope).Child", Method, 5, ""}, - {"(*Scope).Children", Method, 24, ""}, - {"(*Scope).Contains", Method, 5, ""}, - {"(*Scope).End", Method, 5, ""}, - {"(*Scope).Innermost", Method, 5, ""}, - {"(*Scope).Insert", Method, 5, ""}, - {"(*Scope).Len", Method, 5, ""}, - {"(*Scope).Lookup", Method, 5, ""}, - {"(*Scope).LookupParent", Method, 5, ""}, - {"(*Scope).Names", Method, 5, ""}, - {"(*Scope).NumChildren", Method, 5, ""}, - {"(*Scope).Parent", Method, 5, ""}, - {"(*Scope).Pos", Method, 5, ""}, - {"(*Scope).String", Method, 5, ""}, - {"(*Scope).WriteTo", Method, 5, ""}, - {"(*Selection).Index", Method, 5, ""}, - {"(*Selection).Indirect", Method, 5, ""}, - {"(*Selection).Kind", Method, 5, ""}, - {"(*Selection).Obj", Method, 5, ""}, - {"(*Selection).Recv", Method, 5, ""}, - {"(*Selection).String", Method, 5, ""}, - {"(*Selection).Type", Method, 5, ""}, - {"(*Signature).Params", Method, 5, ""}, - {"(*Signature).Recv", Method, 5, ""}, - {"(*Signature).RecvTypeParams", Method, 18, ""}, - {"(*Signature).Results", Method, 5, ""}, - {"(*Signature).String", Method, 5, ""}, - {"(*Signature).TypeParams", Method, 18, ""}, - {"(*Signature).Underlying", Method, 5, ""}, - {"(*Signature).Variadic", Method, 5, ""}, - {"(*Slice).Elem", Method, 5, ""}, - {"(*Slice).String", Method, 5, ""}, - {"(*Slice).Underlying", Method, 5, ""}, - {"(*StdSizes).Alignof", Method, 5, ""}, - {"(*StdSizes).Offsetsof", Method, 5, ""}, - {"(*StdSizes).Sizeof", Method, 5, ""}, - {"(*Struct).Field", Method, 5, ""}, - {"(*Struct).Fields", Method, 24, ""}, - {"(*Struct).NumFields", Method, 5, ""}, - {"(*Struct).String", Method, 5, ""}, - {"(*Struct).Tag", Method, 5, ""}, - {"(*Struct).Underlying", Method, 5, ""}, - {"(*Term).String", Method, 18, ""}, - {"(*Term).Tilde", Method, 18, ""}, - {"(*Term).Type", Method, 18, ""}, - {"(*Tuple).At", Method, 5, ""}, - {"(*Tuple).Len", Method, 5, ""}, - {"(*Tuple).String", Method, 5, ""}, - {"(*Tuple).Underlying", Method, 5, ""}, - {"(*Tuple).Variables", Method, 24, ""}, - {"(*TypeList).At", Method, 18, ""}, - {"(*TypeList).Len", Method, 18, ""}, - {"(*TypeList).Types", Method, 24, ""}, - {"(*TypeName).Exported", Method, 5, ""}, - {"(*TypeName).Id", Method, 5, ""}, - {"(*TypeName).IsAlias", Method, 9, ""}, - {"(*TypeName).Name", Method, 5, ""}, - {"(*TypeName).Parent", Method, 5, ""}, - {"(*TypeName).Pkg", Method, 5, ""}, - {"(*TypeName).Pos", Method, 5, ""}, - {"(*TypeName).String", Method, 5, ""}, - {"(*TypeName).Type", Method, 5, ""}, - {"(*TypeParam).Constraint", Method, 18, ""}, - {"(*TypeParam).Index", Method, 18, ""}, - {"(*TypeParam).Obj", Method, 18, ""}, - {"(*TypeParam).SetConstraint", Method, 18, ""}, - {"(*TypeParam).String", Method, 18, ""}, - {"(*TypeParam).Underlying", Method, 18, ""}, - {"(*TypeParamList).At", Method, 18, ""}, - {"(*TypeParamList).Len", Method, 18, ""}, - {"(*TypeParamList).TypeParams", Method, 24, ""}, - {"(*Union).Len", Method, 18, ""}, - {"(*Union).String", Method, 18, ""}, - {"(*Union).Term", Method, 18, ""}, - {"(*Union).Terms", Method, 24, ""}, - {"(*Union).Underlying", Method, 18, ""}, - {"(*Var).Anonymous", Method, 5, ""}, - {"(*Var).Embedded", Method, 11, ""}, - {"(*Var).Exported", Method, 5, ""}, - {"(*Var).Id", Method, 5, ""}, - {"(*Var).IsField", Method, 5, ""}, - {"(*Var).Kind", Method, 25, ""}, - {"(*Var).Name", Method, 5, ""}, - {"(*Var).Origin", Method, 19, ""}, - {"(*Var).Parent", Method, 5, ""}, - {"(*Var).Pkg", Method, 5, ""}, - {"(*Var).Pos", Method, 5, ""}, - {"(*Var).SetKind", Method, 25, ""}, - {"(*Var).String", Method, 5, ""}, - {"(*Var).Type", Method, 5, ""}, - {"(Checker).ObjectOf", Method, 5, ""}, - {"(Checker).PkgNameOf", Method, 22, ""}, - {"(Checker).TypeOf", Method, 5, ""}, - {"(Error).Error", Method, 5, ""}, - {"(Importer).Import", Method, 5, ""}, - {"(ImporterFrom).Import", Method, 6, ""}, - {"(ImporterFrom).ImportFrom", Method, 6, ""}, - {"(Object).Exported", Method, 5, ""}, - {"(Object).Id", Method, 5, ""}, - {"(Object).Name", Method, 5, ""}, - {"(Object).Parent", Method, 5, ""}, - {"(Object).Pkg", Method, 5, ""}, - {"(Object).Pos", Method, 5, ""}, - {"(Object).String", Method, 5, ""}, - {"(Object).Type", Method, 5, ""}, - {"(Sizes).Alignof", Method, 5, ""}, - {"(Sizes).Offsetsof", Method, 5, ""}, - {"(Sizes).Sizeof", Method, 5, ""}, - {"(Type).String", Method, 5, ""}, - {"(Type).Underlying", Method, 5, ""}, - {"(TypeAndValue).Addressable", Method, 5, ""}, - {"(TypeAndValue).Assignable", Method, 5, ""}, - {"(TypeAndValue).HasOk", Method, 5, ""}, - {"(TypeAndValue).IsBuiltin", Method, 5, ""}, - {"(TypeAndValue).IsNil", Method, 5, ""}, - {"(TypeAndValue).IsType", Method, 5, ""}, - {"(TypeAndValue).IsValue", Method, 5, ""}, - {"(TypeAndValue).IsVoid", Method, 5, ""}, - {"(VarKind).String", Method, 25, ""}, - {"Alias", Type, 22, ""}, - {"ArgumentError", Type, 18, ""}, - {"ArgumentError.Err", Field, 18, ""}, - {"ArgumentError.Index", Field, 18, ""}, - {"Array", Type, 5, ""}, - {"AssertableTo", Func, 5, "func(V *Interface, T Type) bool"}, - {"AssignableTo", Func, 5, "func(V Type, T Type) bool"}, - {"Basic", Type, 5, ""}, - {"BasicInfo", Type, 5, ""}, - {"BasicKind", Type, 5, ""}, - {"Bool", Const, 5, ""}, - {"Builtin", Type, 5, ""}, - {"Byte", Const, 5, ""}, - {"Chan", Type, 5, ""}, - {"ChanDir", Type, 5, ""}, - {"CheckExpr", Func, 13, "func(fset *token.FileSet, pkg *Package, pos token.Pos, expr ast.Expr, info *Info) (err error)"}, - {"Checker", Type, 5, ""}, - {"Checker.Info", Field, 5, ""}, - {"Comparable", Func, 5, "func(T Type) bool"}, - {"Complex128", Const, 5, ""}, - {"Complex64", Const, 5, ""}, - {"Config", Type, 5, ""}, - {"Config.Context", Field, 18, ""}, - {"Config.DisableUnusedImportCheck", Field, 5, ""}, - {"Config.Error", Field, 5, ""}, - {"Config.FakeImportC", Field, 5, ""}, - {"Config.GoVersion", Field, 18, ""}, - {"Config.IgnoreFuncBodies", Field, 5, ""}, - {"Config.Importer", Field, 5, ""}, - {"Config.Sizes", Field, 5, ""}, - {"Const", Type, 5, ""}, - {"Context", Type, 18, ""}, - {"ConvertibleTo", Func, 5, "func(V Type, T Type) bool"}, - {"DefPredeclaredTestFuncs", Func, 5, "func()"}, - {"Default", Func, 8, "func(t Type) Type"}, - {"Error", Type, 5, ""}, - {"Error.Fset", Field, 5, ""}, - {"Error.Msg", Field, 5, ""}, - {"Error.Pos", Field, 5, ""}, - {"Error.Soft", Field, 5, ""}, - {"Eval", Func, 5, "func(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (_ TypeAndValue, err error)"}, - {"ExprString", Func, 5, "func(x ast.Expr) string"}, - {"FieldVal", Const, 5, ""}, - {"FieldVar", Const, 25, ""}, - {"Float32", Const, 5, ""}, - {"Float64", Const, 5, ""}, - {"Func", Type, 5, ""}, - {"Id", Func, 5, "func(pkg *Package, name string) string"}, - {"Identical", Func, 5, "func(x Type, y Type) bool"}, - {"IdenticalIgnoreTags", Func, 8, "func(x Type, y Type) bool"}, - {"Implements", Func, 5, "func(V Type, T *Interface) bool"}, - {"ImportMode", Type, 6, ""}, - {"Importer", Type, 5, ""}, - {"ImporterFrom", Type, 6, ""}, - {"Info", Type, 5, ""}, - {"Info.Defs", Field, 5, ""}, - {"Info.FileVersions", Field, 22, ""}, - {"Info.Implicits", Field, 5, ""}, - {"Info.InitOrder", Field, 5, ""}, - {"Info.Instances", Field, 18, ""}, - {"Info.Scopes", Field, 5, ""}, - {"Info.Selections", Field, 5, ""}, - {"Info.Types", Field, 5, ""}, - {"Info.Uses", Field, 5, ""}, - {"Initializer", Type, 5, ""}, - {"Initializer.Lhs", Field, 5, ""}, - {"Initializer.Rhs", Field, 5, ""}, - {"Instance", Type, 18, ""}, - {"Instance.Type", Field, 18, ""}, - {"Instance.TypeArgs", Field, 18, ""}, - {"Instantiate", Func, 18, "func(ctxt *Context, orig Type, targs []Type, validate bool) (Type, error)"}, - {"Int", Const, 5, ""}, - {"Int16", Const, 5, ""}, - {"Int32", Const, 5, ""}, - {"Int64", Const, 5, ""}, - {"Int8", Const, 5, ""}, - {"Interface", Type, 5, ""}, - {"Invalid", Const, 5, ""}, - {"IsBoolean", Const, 5, ""}, - {"IsComplex", Const, 5, ""}, - {"IsConstType", Const, 5, ""}, - {"IsFloat", Const, 5, ""}, - {"IsInteger", Const, 5, ""}, - {"IsInterface", Func, 5, "func(t Type) bool"}, - {"IsNumeric", Const, 5, ""}, - {"IsOrdered", Const, 5, ""}, - {"IsString", Const, 5, ""}, - {"IsUnsigned", Const, 5, ""}, - {"IsUntyped", Const, 5, ""}, - {"Label", Type, 5, ""}, - {"LocalVar", Const, 25, ""}, - {"LookupFieldOrMethod", Func, 5, "func(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool)"}, - {"LookupSelection", Func, 25, "func(T Type, addressable bool, pkg *Package, name string) (Selection, bool)"}, - {"Map", Type, 5, ""}, - {"MethodExpr", Const, 5, ""}, - {"MethodSet", Type, 5, ""}, - {"MethodVal", Const, 5, ""}, - {"MissingMethod", Func, 5, "func(V Type, T *Interface, static bool) (method *Func, wrongType bool)"}, - {"Named", Type, 5, ""}, - {"NewAlias", Func, 22, "func(obj *TypeName, rhs Type) *Alias"}, - {"NewArray", Func, 5, "func(elem Type, len int64) *Array"}, - {"NewChan", Func, 5, "func(dir ChanDir, elem Type) *Chan"}, - {"NewChecker", Func, 5, "func(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Checker"}, - {"NewConst", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const"}, - {"NewContext", Func, 18, "func() *Context"}, - {"NewField", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type, embedded bool) *Var"}, - {"NewFunc", Func, 5, "func(pos token.Pos, pkg *Package, name string, sig *Signature) *Func"}, - {"NewInterface", Func, 5, "func(methods []*Func, embeddeds []*Named) *Interface"}, - {"NewInterfaceType", Func, 11, "func(methods []*Func, embeddeds []Type) *Interface"}, - {"NewLabel", Func, 5, "func(pos token.Pos, pkg *Package, name string) *Label"}, - {"NewMap", Func, 5, "func(key Type, elem Type) *Map"}, - {"NewMethodSet", Func, 5, "func(T Type) *MethodSet"}, - {"NewNamed", Func, 5, "func(obj *TypeName, underlying Type, methods []*Func) *Named"}, - {"NewPackage", Func, 5, "func(path string, name string) *Package"}, - {"NewParam", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type) *Var"}, - {"NewPkgName", Func, 5, "func(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName"}, - {"NewPointer", Func, 5, "func(elem Type) *Pointer"}, - {"NewScope", Func, 5, "func(parent *Scope, pos token.Pos, end token.Pos, comment string) *Scope"}, - {"NewSignature", Func, 5, "func(recv *Var, params *Tuple, results *Tuple, variadic bool) *Signature"}, - {"NewSignatureType", Func, 18, "func(recv *Var, recvTypeParams []*TypeParam, typeParams []*TypeParam, params *Tuple, results *Tuple, variadic bool) *Signature"}, - {"NewSlice", Func, 5, "func(elem Type) *Slice"}, - {"NewStruct", Func, 5, "func(fields []*Var, tags []string) *Struct"}, - {"NewTerm", Func, 18, "func(tilde bool, typ Type) *Term"}, - {"NewTuple", Func, 5, "func(x ...*Var) *Tuple"}, - {"NewTypeName", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type) *TypeName"}, - {"NewTypeParam", Func, 18, "func(obj *TypeName, constraint Type) *TypeParam"}, - {"NewUnion", Func, 18, "func(terms []*Term) *Union"}, - {"NewVar", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type) *Var"}, - {"Nil", Type, 5, ""}, - {"ObjectString", Func, 5, "func(obj Object, qf Qualifier) string"}, - {"Package", Type, 5, ""}, - {"PackageVar", Const, 25, ""}, - {"ParamVar", Const, 25, ""}, - {"PkgName", Type, 5, ""}, - {"Pointer", Type, 5, ""}, - {"Qualifier", Type, 5, ""}, - {"RecvOnly", Const, 5, ""}, - {"RecvVar", Const, 25, ""}, - {"RelativeTo", Func, 5, "func(pkg *Package) Qualifier"}, - {"ResultVar", Const, 25, ""}, - {"Rune", Const, 5, ""}, - {"Satisfies", Func, 20, "func(V Type, T *Interface) bool"}, - {"Scope", Type, 5, ""}, - {"Selection", Type, 5, ""}, - {"SelectionKind", Type, 5, ""}, - {"SelectionString", Func, 5, "func(s *Selection, qf Qualifier) string"}, - {"SendOnly", Const, 5, ""}, - {"SendRecv", Const, 5, ""}, - {"Signature", Type, 5, ""}, - {"Sizes", Type, 5, ""}, - {"SizesFor", Func, 9, "func(compiler string, arch string) Sizes"}, - {"Slice", Type, 5, ""}, - {"StdSizes", Type, 5, ""}, - {"StdSizes.MaxAlign", Field, 5, ""}, - {"StdSizes.WordSize", Field, 5, ""}, - {"String", Const, 5, ""}, - {"Struct", Type, 5, ""}, - {"Term", Type, 18, ""}, - {"Tuple", Type, 5, ""}, - {"Typ", Var, 5, ""}, - {"Type", Type, 5, ""}, - {"TypeAndValue", Type, 5, ""}, - {"TypeAndValue.Type", Field, 5, ""}, - {"TypeAndValue.Value", Field, 5, ""}, - {"TypeList", Type, 18, ""}, - {"TypeName", Type, 5, ""}, - {"TypeParam", Type, 18, ""}, - {"TypeParamList", Type, 18, ""}, - {"TypeString", Func, 5, "func(typ Type, qf Qualifier) string"}, - {"Uint", Const, 5, ""}, - {"Uint16", Const, 5, ""}, - {"Uint32", Const, 5, ""}, - {"Uint64", Const, 5, ""}, - {"Uint8", Const, 5, ""}, - {"Uintptr", Const, 5, ""}, - {"Unalias", Func, 22, "func(t Type) Type"}, - {"Union", Type, 18, ""}, - {"Universe", Var, 5, ""}, - {"Unsafe", Var, 5, ""}, - {"UnsafePointer", Const, 5, ""}, - {"UntypedBool", Const, 5, ""}, - {"UntypedComplex", Const, 5, ""}, - {"UntypedFloat", Const, 5, ""}, - {"UntypedInt", Const, 5, ""}, - {"UntypedNil", Const, 5, ""}, - {"UntypedRune", Const, 5, ""}, - {"UntypedString", Const, 5, ""}, - {"Var", Type, 5, ""}, - {"VarKind", Type, 25, ""}, - {"WriteExpr", Func, 5, "func(buf *bytes.Buffer, x ast.Expr)"}, - {"WriteSignature", Func, 5, "func(buf *bytes.Buffer, sig *Signature, qf Qualifier)"}, - {"WriteType", Func, 5, "func(buf *bytes.Buffer, typ Type, qf Qualifier)"}, - }, - "go/version": { - {"Compare", Func, 22, "func(x string, y string) int"}, - {"IsValid", Func, 22, "func(x string) bool"}, - {"Lang", Func, 22, "func(x string) string"}, - }, - "hash": { - {"(Cloner).BlockSize", Method, 25, ""}, - {"(Cloner).Clone", Method, 25, ""}, - {"(Cloner).Reset", Method, 25, ""}, - {"(Cloner).Size", Method, 25, ""}, - {"(Cloner).Sum", Method, 25, ""}, - {"(Cloner).Write", Method, 25, ""}, - {"(Hash).BlockSize", Method, 0, ""}, - {"(Hash).Reset", Method, 0, ""}, - {"(Hash).Size", Method, 0, ""}, - {"(Hash).Sum", Method, 0, ""}, - {"(Hash).Write", Method, 0, ""}, - {"(Hash32).BlockSize", Method, 0, ""}, - {"(Hash32).Reset", Method, 0, ""}, - {"(Hash32).Size", Method, 0, ""}, - {"(Hash32).Sum", Method, 0, ""}, - {"(Hash32).Sum32", Method, 0, ""}, - {"(Hash32).Write", Method, 0, ""}, - {"(Hash64).BlockSize", Method, 0, ""}, - {"(Hash64).Reset", Method, 0, ""}, - {"(Hash64).Size", Method, 0, ""}, - {"(Hash64).Sum", Method, 0, ""}, - {"(Hash64).Sum64", Method, 0, ""}, - {"(Hash64).Write", Method, 0, ""}, - {"(XOF).BlockSize", Method, 25, ""}, - {"(XOF).Read", Method, 25, ""}, - {"(XOF).Reset", Method, 25, ""}, - {"(XOF).Write", Method, 25, ""}, - {"Cloner", Type, 25, ""}, - {"Hash", Type, 0, ""}, - {"Hash32", Type, 0, ""}, - {"Hash64", Type, 0, ""}, - {"XOF", Type, 25, ""}, - }, - "hash/adler32": { - {"Checksum", Func, 0, "func(data []byte) uint32"}, - {"New", Func, 0, "func() hash.Hash32"}, - {"Size", Const, 0, ""}, - }, - "hash/crc32": { - {"Castagnoli", Const, 0, ""}, - {"Checksum", Func, 0, "func(data []byte, tab *Table) uint32"}, - {"ChecksumIEEE", Func, 0, "func(data []byte) uint32"}, - {"IEEE", Const, 0, ""}, - {"IEEETable", Var, 0, ""}, - {"Koopman", Const, 0, ""}, - {"MakeTable", Func, 0, "func(poly uint32) *Table"}, - {"New", Func, 0, "func(tab *Table) hash.Hash32"}, - {"NewIEEE", Func, 0, "func() hash.Hash32"}, - {"Size", Const, 0, ""}, - {"Table", Type, 0, ""}, - {"Update", Func, 0, "func(crc uint32, tab *Table, p []byte) uint32"}, - }, - "hash/crc64": { - {"Checksum", Func, 0, "func(data []byte, tab *Table) uint64"}, - {"ECMA", Const, 0, ""}, - {"ISO", Const, 0, ""}, - {"MakeTable", Func, 0, "func(poly uint64) *Table"}, - {"New", Func, 0, "func(tab *Table) hash.Hash64"}, - {"Size", Const, 0, ""}, - {"Table", Type, 0, ""}, - {"Update", Func, 0, "func(crc uint64, tab *Table, p []byte) uint64"}, - }, - "hash/fnv": { - {"New128", Func, 9, "func() hash.Hash"}, - {"New128a", Func, 9, "func() hash.Hash"}, - {"New32", Func, 0, "func() hash.Hash32"}, - {"New32a", Func, 0, "func() hash.Hash32"}, - {"New64", Func, 0, "func() hash.Hash64"}, - {"New64a", Func, 0, "func() hash.Hash64"}, - }, - "hash/maphash": { - {"(*Hash).BlockSize", Method, 14, ""}, - {"(*Hash).Clone", Method, 25, ""}, - {"(*Hash).Reset", Method, 14, ""}, - {"(*Hash).Seed", Method, 14, ""}, - {"(*Hash).SetSeed", Method, 14, ""}, - {"(*Hash).Size", Method, 14, ""}, - {"(*Hash).Sum", Method, 14, ""}, - {"(*Hash).Sum64", Method, 14, ""}, - {"(*Hash).Write", Method, 14, ""}, - {"(*Hash).WriteByte", Method, 14, ""}, - {"(*Hash).WriteString", Method, 14, ""}, - {"Bytes", Func, 19, "func(seed Seed, b []byte) uint64"}, - {"Comparable", Func, 24, "func[T comparable](seed Seed, v T) uint64"}, - {"Hash", Type, 14, ""}, - {"MakeSeed", Func, 14, "func() Seed"}, - {"Seed", Type, 14, ""}, - {"String", Func, 19, "func(seed Seed, s string) uint64"}, - {"WriteComparable", Func, 24, "func[T comparable](h *Hash, x T)"}, - }, - "html": { - {"EscapeString", Func, 0, "func(s string) string"}, - {"UnescapeString", Func, 0, "func(s string) string"}, - }, - "html/template": { - {"(*Error).Error", Method, 0, ""}, - {"(*Template).AddParseTree", Method, 0, ""}, - {"(*Template).Clone", Method, 0, ""}, - {"(*Template).DefinedTemplates", Method, 6, ""}, - {"(*Template).Delims", Method, 0, ""}, - {"(*Template).Execute", Method, 0, ""}, - {"(*Template).ExecuteTemplate", Method, 0, ""}, - {"(*Template).Funcs", Method, 0, ""}, - {"(*Template).Lookup", Method, 0, ""}, - {"(*Template).Name", Method, 0, ""}, - {"(*Template).New", Method, 0, ""}, - {"(*Template).Option", Method, 5, ""}, - {"(*Template).Parse", Method, 0, ""}, - {"(*Template).ParseFS", Method, 16, ""}, - {"(*Template).ParseFiles", Method, 0, ""}, - {"(*Template).ParseGlob", Method, 0, ""}, - {"(*Template).Templates", Method, 0, ""}, - {"CSS", Type, 0, ""}, - {"ErrAmbigContext", Const, 0, ""}, - {"ErrBadHTML", Const, 0, ""}, - {"ErrBranchEnd", Const, 0, ""}, - {"ErrEndContext", Const, 0, ""}, - {"ErrJSTemplate", Const, 21, ""}, - {"ErrNoSuchTemplate", Const, 0, ""}, - {"ErrOutputContext", Const, 0, ""}, - {"ErrPartialCharset", Const, 0, ""}, - {"ErrPartialEscape", Const, 0, ""}, - {"ErrPredefinedEscaper", Const, 9, ""}, - {"ErrRangeLoopReentry", Const, 0, ""}, - {"ErrSlashAmbig", Const, 0, ""}, - {"Error", Type, 0, ""}, - {"Error.Description", Field, 0, ""}, - {"Error.ErrorCode", Field, 0, ""}, - {"Error.Line", Field, 0, ""}, - {"Error.Name", Field, 0, ""}, - {"Error.Node", Field, 4, ""}, - {"ErrorCode", Type, 0, ""}, - {"FuncMap", Type, 0, ""}, - {"HTML", Type, 0, ""}, - {"HTMLAttr", Type, 0, ""}, - {"HTMLEscape", Func, 0, "func(w io.Writer, b []byte)"}, - {"HTMLEscapeString", Func, 0, "func(s string) string"}, - {"HTMLEscaper", Func, 0, "func(args ...any) string"}, - {"IsTrue", Func, 6, "func(val any) (truth bool, ok bool)"}, - {"JS", Type, 0, ""}, - {"JSEscape", Func, 0, "func(w io.Writer, b []byte)"}, - {"JSEscapeString", Func, 0, "func(s string) string"}, - {"JSEscaper", Func, 0, "func(args ...any) string"}, - {"JSStr", Type, 0, ""}, - {"Must", Func, 0, "func(t *Template, err error) *Template"}, - {"New", Func, 0, "func(name string) *Template"}, - {"OK", Const, 0, ""}, - {"ParseFS", Func, 16, "func(fs fs.FS, patterns ...string) (*Template, error)"}, - {"ParseFiles", Func, 0, "func(filenames ...string) (*Template, error)"}, - {"ParseGlob", Func, 0, "func(pattern string) (*Template, error)"}, - {"Srcset", Type, 10, ""}, - {"Template", Type, 0, ""}, - {"Template.Tree", Field, 2, ""}, - {"URL", Type, 0, ""}, - {"URLQueryEscaper", Func, 0, "func(args ...any) string"}, - }, - "image": { - {"(*Alpha).AlphaAt", Method, 4, ""}, - {"(*Alpha).At", Method, 0, ""}, - {"(*Alpha).Bounds", Method, 0, ""}, - {"(*Alpha).ColorModel", Method, 0, ""}, - {"(*Alpha).Opaque", Method, 0, ""}, - {"(*Alpha).PixOffset", Method, 0, ""}, - {"(*Alpha).RGBA64At", Method, 17, ""}, - {"(*Alpha).Set", Method, 0, ""}, - {"(*Alpha).SetAlpha", Method, 0, ""}, - {"(*Alpha).SetRGBA64", Method, 17, ""}, - {"(*Alpha).SubImage", Method, 0, ""}, - {"(*Alpha16).Alpha16At", Method, 4, ""}, - {"(*Alpha16).At", Method, 0, ""}, - {"(*Alpha16).Bounds", Method, 0, ""}, - {"(*Alpha16).ColorModel", Method, 0, ""}, - {"(*Alpha16).Opaque", Method, 0, ""}, - {"(*Alpha16).PixOffset", Method, 0, ""}, - {"(*Alpha16).RGBA64At", Method, 17, ""}, - {"(*Alpha16).Set", Method, 0, ""}, - {"(*Alpha16).SetAlpha16", Method, 0, ""}, - {"(*Alpha16).SetRGBA64", Method, 17, ""}, - {"(*Alpha16).SubImage", Method, 0, ""}, - {"(*CMYK).At", Method, 5, ""}, - {"(*CMYK).Bounds", Method, 5, ""}, - {"(*CMYK).CMYKAt", Method, 5, ""}, - {"(*CMYK).ColorModel", Method, 5, ""}, - {"(*CMYK).Opaque", Method, 5, ""}, - {"(*CMYK).PixOffset", Method, 5, ""}, - {"(*CMYK).RGBA64At", Method, 17, ""}, - {"(*CMYK).Set", Method, 5, ""}, - {"(*CMYK).SetCMYK", Method, 5, ""}, - {"(*CMYK).SetRGBA64", Method, 17, ""}, - {"(*CMYK).SubImage", Method, 5, ""}, - {"(*Gray).At", Method, 0, ""}, - {"(*Gray).Bounds", Method, 0, ""}, - {"(*Gray).ColorModel", Method, 0, ""}, - {"(*Gray).GrayAt", Method, 4, ""}, - {"(*Gray).Opaque", Method, 0, ""}, - {"(*Gray).PixOffset", Method, 0, ""}, - {"(*Gray).RGBA64At", Method, 17, ""}, - {"(*Gray).Set", Method, 0, ""}, - {"(*Gray).SetGray", Method, 0, ""}, - {"(*Gray).SetRGBA64", Method, 17, ""}, - {"(*Gray).SubImage", Method, 0, ""}, - {"(*Gray16).At", Method, 0, ""}, - {"(*Gray16).Bounds", Method, 0, ""}, - {"(*Gray16).ColorModel", Method, 0, ""}, - {"(*Gray16).Gray16At", Method, 4, ""}, - {"(*Gray16).Opaque", Method, 0, ""}, - {"(*Gray16).PixOffset", Method, 0, ""}, - {"(*Gray16).RGBA64At", Method, 17, ""}, - {"(*Gray16).Set", Method, 0, ""}, - {"(*Gray16).SetGray16", Method, 0, ""}, - {"(*Gray16).SetRGBA64", Method, 17, ""}, - {"(*Gray16).SubImage", Method, 0, ""}, - {"(*NRGBA).At", Method, 0, ""}, - {"(*NRGBA).Bounds", Method, 0, ""}, - {"(*NRGBA).ColorModel", Method, 0, ""}, - {"(*NRGBA).NRGBAAt", Method, 4, ""}, - {"(*NRGBA).Opaque", Method, 0, ""}, - {"(*NRGBA).PixOffset", Method, 0, ""}, - {"(*NRGBA).RGBA64At", Method, 17, ""}, - {"(*NRGBA).Set", Method, 0, ""}, - {"(*NRGBA).SetNRGBA", Method, 0, ""}, - {"(*NRGBA).SetRGBA64", Method, 17, ""}, - {"(*NRGBA).SubImage", Method, 0, ""}, - {"(*NRGBA64).At", Method, 0, ""}, - {"(*NRGBA64).Bounds", Method, 0, ""}, - {"(*NRGBA64).ColorModel", Method, 0, ""}, - {"(*NRGBA64).NRGBA64At", Method, 4, ""}, - {"(*NRGBA64).Opaque", Method, 0, ""}, - {"(*NRGBA64).PixOffset", Method, 0, ""}, - {"(*NRGBA64).RGBA64At", Method, 17, ""}, - {"(*NRGBA64).Set", Method, 0, ""}, - {"(*NRGBA64).SetNRGBA64", Method, 0, ""}, - {"(*NRGBA64).SetRGBA64", Method, 17, ""}, - {"(*NRGBA64).SubImage", Method, 0, ""}, - {"(*NYCbCrA).AOffset", Method, 6, ""}, - {"(*NYCbCrA).At", Method, 6, ""}, - {"(*NYCbCrA).Bounds", Method, 6, ""}, - {"(*NYCbCrA).COffset", Method, 6, ""}, - {"(*NYCbCrA).ColorModel", Method, 6, ""}, - {"(*NYCbCrA).NYCbCrAAt", Method, 6, ""}, - {"(*NYCbCrA).Opaque", Method, 6, ""}, - {"(*NYCbCrA).RGBA64At", Method, 17, ""}, - {"(*NYCbCrA).SubImage", Method, 6, ""}, - {"(*NYCbCrA).YCbCrAt", Method, 6, ""}, - {"(*NYCbCrA).YOffset", Method, 6, ""}, - {"(*Paletted).At", Method, 0, ""}, - {"(*Paletted).Bounds", Method, 0, ""}, - {"(*Paletted).ColorIndexAt", Method, 0, ""}, - {"(*Paletted).ColorModel", Method, 0, ""}, - {"(*Paletted).Opaque", Method, 0, ""}, - {"(*Paletted).PixOffset", Method, 0, ""}, - {"(*Paletted).RGBA64At", Method, 17, ""}, - {"(*Paletted).Set", Method, 0, ""}, - {"(*Paletted).SetColorIndex", Method, 0, ""}, - {"(*Paletted).SetRGBA64", Method, 17, ""}, - {"(*Paletted).SubImage", Method, 0, ""}, - {"(*RGBA).At", Method, 0, ""}, - {"(*RGBA).Bounds", Method, 0, ""}, - {"(*RGBA).ColorModel", Method, 0, ""}, - {"(*RGBA).Opaque", Method, 0, ""}, - {"(*RGBA).PixOffset", Method, 0, ""}, - {"(*RGBA).RGBA64At", Method, 17, ""}, - {"(*RGBA).RGBAAt", Method, 4, ""}, - {"(*RGBA).Set", Method, 0, ""}, - {"(*RGBA).SetRGBA", Method, 0, ""}, - {"(*RGBA).SetRGBA64", Method, 17, ""}, - {"(*RGBA).SubImage", Method, 0, ""}, - {"(*RGBA64).At", Method, 0, ""}, - {"(*RGBA64).Bounds", Method, 0, ""}, - {"(*RGBA64).ColorModel", Method, 0, ""}, - {"(*RGBA64).Opaque", Method, 0, ""}, - {"(*RGBA64).PixOffset", Method, 0, ""}, - {"(*RGBA64).RGBA64At", Method, 4, ""}, - {"(*RGBA64).Set", Method, 0, ""}, - {"(*RGBA64).SetRGBA64", Method, 0, ""}, - {"(*RGBA64).SubImage", Method, 0, ""}, - {"(*Uniform).At", Method, 0, ""}, - {"(*Uniform).Bounds", Method, 0, ""}, - {"(*Uniform).ColorModel", Method, 0, ""}, - {"(*Uniform).Convert", Method, 0, ""}, - {"(*Uniform).Opaque", Method, 0, ""}, - {"(*Uniform).RGBA", Method, 0, ""}, - {"(*Uniform).RGBA64At", Method, 17, ""}, - {"(*YCbCr).At", Method, 0, ""}, - {"(*YCbCr).Bounds", Method, 0, ""}, - {"(*YCbCr).COffset", Method, 0, ""}, - {"(*YCbCr).ColorModel", Method, 0, ""}, - {"(*YCbCr).Opaque", Method, 0, ""}, - {"(*YCbCr).RGBA64At", Method, 17, ""}, - {"(*YCbCr).SubImage", Method, 0, ""}, - {"(*YCbCr).YCbCrAt", Method, 4, ""}, - {"(*YCbCr).YOffset", Method, 0, ""}, - {"(Image).At", Method, 0, ""}, - {"(Image).Bounds", Method, 0, ""}, - {"(Image).ColorModel", Method, 0, ""}, - {"(PalettedImage).At", Method, 0, ""}, - {"(PalettedImage).Bounds", Method, 0, ""}, - {"(PalettedImage).ColorIndexAt", Method, 0, ""}, - {"(PalettedImage).ColorModel", Method, 0, ""}, - {"(Point).Add", Method, 0, ""}, - {"(Point).Div", Method, 0, ""}, - {"(Point).Eq", Method, 0, ""}, - {"(Point).In", Method, 0, ""}, - {"(Point).Mod", Method, 0, ""}, - {"(Point).Mul", Method, 0, ""}, - {"(Point).String", Method, 0, ""}, - {"(Point).Sub", Method, 0, ""}, - {"(RGBA64Image).At", Method, 17, ""}, - {"(RGBA64Image).Bounds", Method, 17, ""}, - {"(RGBA64Image).ColorModel", Method, 17, ""}, - {"(RGBA64Image).RGBA64At", Method, 17, ""}, - {"(Rectangle).Add", Method, 0, ""}, - {"(Rectangle).At", Method, 5, ""}, - {"(Rectangle).Bounds", Method, 5, ""}, - {"(Rectangle).Canon", Method, 0, ""}, - {"(Rectangle).ColorModel", Method, 5, ""}, - {"(Rectangle).Dx", Method, 0, ""}, - {"(Rectangle).Dy", Method, 0, ""}, - {"(Rectangle).Empty", Method, 0, ""}, - {"(Rectangle).Eq", Method, 0, ""}, - {"(Rectangle).In", Method, 0, ""}, - {"(Rectangle).Inset", Method, 0, ""}, - {"(Rectangle).Intersect", Method, 0, ""}, - {"(Rectangle).Overlaps", Method, 0, ""}, - {"(Rectangle).RGBA64At", Method, 17, ""}, - {"(Rectangle).Size", Method, 0, ""}, - {"(Rectangle).String", Method, 0, ""}, - {"(Rectangle).Sub", Method, 0, ""}, - {"(Rectangle).Union", Method, 0, ""}, - {"(YCbCrSubsampleRatio).String", Method, 0, ""}, - {"Alpha", Type, 0, ""}, - {"Alpha.Pix", Field, 0, ""}, - {"Alpha.Rect", Field, 0, ""}, - {"Alpha.Stride", Field, 0, ""}, - {"Alpha16", Type, 0, ""}, - {"Alpha16.Pix", Field, 0, ""}, - {"Alpha16.Rect", Field, 0, ""}, - {"Alpha16.Stride", Field, 0, ""}, - {"Black", Var, 0, ""}, - {"CMYK", Type, 5, ""}, - {"CMYK.Pix", Field, 5, ""}, - {"CMYK.Rect", Field, 5, ""}, - {"CMYK.Stride", Field, 5, ""}, - {"Config", Type, 0, ""}, - {"Config.ColorModel", Field, 0, ""}, - {"Config.Height", Field, 0, ""}, - {"Config.Width", Field, 0, ""}, - {"Decode", Func, 0, "func(r io.Reader) (Image, string, error)"}, - {"DecodeConfig", Func, 0, "func(r io.Reader) (Config, string, error)"}, - {"ErrFormat", Var, 0, ""}, - {"Gray", Type, 0, ""}, - {"Gray.Pix", Field, 0, ""}, - {"Gray.Rect", Field, 0, ""}, - {"Gray.Stride", Field, 0, ""}, - {"Gray16", Type, 0, ""}, - {"Gray16.Pix", Field, 0, ""}, - {"Gray16.Rect", Field, 0, ""}, - {"Gray16.Stride", Field, 0, ""}, - {"Image", Type, 0, ""}, - {"NRGBA", Type, 0, ""}, - {"NRGBA.Pix", Field, 0, ""}, - {"NRGBA.Rect", Field, 0, ""}, - {"NRGBA.Stride", Field, 0, ""}, - {"NRGBA64", Type, 0, ""}, - {"NRGBA64.Pix", Field, 0, ""}, - {"NRGBA64.Rect", Field, 0, ""}, - {"NRGBA64.Stride", Field, 0, ""}, - {"NYCbCrA", Type, 6, ""}, - {"NYCbCrA.A", Field, 6, ""}, - {"NYCbCrA.AStride", Field, 6, ""}, - {"NYCbCrA.YCbCr", Field, 6, ""}, - {"NewAlpha", Func, 0, "func(r Rectangle) *Alpha"}, - {"NewAlpha16", Func, 0, "func(r Rectangle) *Alpha16"}, - {"NewCMYK", Func, 5, "func(r Rectangle) *CMYK"}, - {"NewGray", Func, 0, "func(r Rectangle) *Gray"}, - {"NewGray16", Func, 0, "func(r Rectangle) *Gray16"}, - {"NewNRGBA", Func, 0, "func(r Rectangle) *NRGBA"}, - {"NewNRGBA64", Func, 0, "func(r Rectangle) *NRGBA64"}, - {"NewNYCbCrA", Func, 6, "func(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *NYCbCrA"}, - {"NewPaletted", Func, 0, "func(r Rectangle, p color.Palette) *Paletted"}, - {"NewRGBA", Func, 0, "func(r Rectangle) *RGBA"}, - {"NewRGBA64", Func, 0, "func(r Rectangle) *RGBA64"}, - {"NewUniform", Func, 0, "func(c color.Color) *Uniform"}, - {"NewYCbCr", Func, 0, "func(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *YCbCr"}, - {"Opaque", Var, 0, ""}, - {"Paletted", Type, 0, ""}, - {"Paletted.Palette", Field, 0, ""}, - {"Paletted.Pix", Field, 0, ""}, - {"Paletted.Rect", Field, 0, ""}, - {"Paletted.Stride", Field, 0, ""}, - {"PalettedImage", Type, 0, ""}, - {"Point", Type, 0, ""}, - {"Point.X", Field, 0, ""}, - {"Point.Y", Field, 0, ""}, - {"Pt", Func, 0, "func(X int, Y int) Point"}, - {"RGBA", Type, 0, ""}, - {"RGBA.Pix", Field, 0, ""}, - {"RGBA.Rect", Field, 0, ""}, - {"RGBA.Stride", Field, 0, ""}, - {"RGBA64", Type, 0, ""}, - {"RGBA64.Pix", Field, 0, ""}, - {"RGBA64.Rect", Field, 0, ""}, - {"RGBA64.Stride", Field, 0, ""}, - {"RGBA64Image", Type, 17, ""}, - {"Rect", Func, 0, "func(x0 int, y0 int, x1 int, y1 int) Rectangle"}, - {"Rectangle", Type, 0, ""}, - {"Rectangle.Max", Field, 0, ""}, - {"Rectangle.Min", Field, 0, ""}, - {"RegisterFormat", Func, 0, "func(name string, magic string, decode func(io.Reader) (Image, error), decodeConfig func(io.Reader) (Config, error))"}, - {"Transparent", Var, 0, ""}, - {"Uniform", Type, 0, ""}, - {"Uniform.C", Field, 0, ""}, - {"White", Var, 0, ""}, - {"YCbCr", Type, 0, ""}, - {"YCbCr.CStride", Field, 0, ""}, - {"YCbCr.Cb", Field, 0, ""}, - {"YCbCr.Cr", Field, 0, ""}, - {"YCbCr.Rect", Field, 0, ""}, - {"YCbCr.SubsampleRatio", Field, 0, ""}, - {"YCbCr.Y", Field, 0, ""}, - {"YCbCr.YStride", Field, 0, ""}, - {"YCbCrSubsampleRatio", Type, 0, ""}, - {"YCbCrSubsampleRatio410", Const, 5, ""}, - {"YCbCrSubsampleRatio411", Const, 5, ""}, - {"YCbCrSubsampleRatio420", Const, 0, ""}, - {"YCbCrSubsampleRatio422", Const, 0, ""}, - {"YCbCrSubsampleRatio440", Const, 1, ""}, - {"YCbCrSubsampleRatio444", Const, 0, ""}, - {"ZP", Var, 0, ""}, - {"ZR", Var, 0, ""}, - }, - "image/color": { - {"(Alpha).RGBA", Method, 0, ""}, - {"(Alpha16).RGBA", Method, 0, ""}, - {"(CMYK).RGBA", Method, 5, ""}, - {"(Color).RGBA", Method, 0, ""}, - {"(Gray).RGBA", Method, 0, ""}, - {"(Gray16).RGBA", Method, 0, ""}, - {"(Model).Convert", Method, 0, ""}, - {"(NRGBA).RGBA", Method, 0, ""}, - {"(NRGBA64).RGBA", Method, 0, ""}, - {"(NYCbCrA).RGBA", Method, 6, ""}, - {"(Palette).Convert", Method, 0, ""}, - {"(Palette).Index", Method, 0, ""}, - {"(RGBA).RGBA", Method, 0, ""}, - {"(RGBA64).RGBA", Method, 0, ""}, - {"(YCbCr).RGBA", Method, 0, ""}, - {"Alpha", Type, 0, ""}, - {"Alpha.A", Field, 0, ""}, - {"Alpha16", Type, 0, ""}, - {"Alpha16.A", Field, 0, ""}, - {"Alpha16Model", Var, 0, ""}, - {"AlphaModel", Var, 0, ""}, - {"Black", Var, 0, ""}, - {"CMYK", Type, 5, ""}, - {"CMYK.C", Field, 5, ""}, - {"CMYK.K", Field, 5, ""}, - {"CMYK.M", Field, 5, ""}, - {"CMYK.Y", Field, 5, ""}, - {"CMYKModel", Var, 5, ""}, - {"CMYKToRGB", Func, 5, "func(c uint8, m uint8, y uint8, k uint8) (uint8, uint8, uint8)"}, - {"Color", Type, 0, ""}, - {"Gray", Type, 0, ""}, - {"Gray.Y", Field, 0, ""}, - {"Gray16", Type, 0, ""}, - {"Gray16.Y", Field, 0, ""}, - {"Gray16Model", Var, 0, ""}, - {"GrayModel", Var, 0, ""}, - {"Model", Type, 0, ""}, - {"ModelFunc", Func, 0, "func(f func(Color) Color) Model"}, - {"NRGBA", Type, 0, ""}, - {"NRGBA.A", Field, 0, ""}, - {"NRGBA.B", Field, 0, ""}, - {"NRGBA.G", Field, 0, ""}, - {"NRGBA.R", Field, 0, ""}, - {"NRGBA64", Type, 0, ""}, - {"NRGBA64.A", Field, 0, ""}, - {"NRGBA64.B", Field, 0, ""}, - {"NRGBA64.G", Field, 0, ""}, - {"NRGBA64.R", Field, 0, ""}, - {"NRGBA64Model", Var, 0, ""}, - {"NRGBAModel", Var, 0, ""}, - {"NYCbCrA", Type, 6, ""}, - {"NYCbCrA.A", Field, 6, ""}, - {"NYCbCrA.YCbCr", Field, 6, ""}, - {"NYCbCrAModel", Var, 6, ""}, - {"Opaque", Var, 0, ""}, - {"Palette", Type, 0, ""}, - {"RGBA", Type, 0, ""}, - {"RGBA.A", Field, 0, ""}, - {"RGBA.B", Field, 0, ""}, - {"RGBA.G", Field, 0, ""}, - {"RGBA.R", Field, 0, ""}, - {"RGBA64", Type, 0, ""}, - {"RGBA64.A", Field, 0, ""}, - {"RGBA64.B", Field, 0, ""}, - {"RGBA64.G", Field, 0, ""}, - {"RGBA64.R", Field, 0, ""}, - {"RGBA64Model", Var, 0, ""}, - {"RGBAModel", Var, 0, ""}, - {"RGBToCMYK", Func, 5, "func(r uint8, g uint8, b uint8) (uint8, uint8, uint8, uint8)"}, - {"RGBToYCbCr", Func, 0, "func(r uint8, g uint8, b uint8) (uint8, uint8, uint8)"}, - {"Transparent", Var, 0, ""}, - {"White", Var, 0, ""}, - {"YCbCr", Type, 0, ""}, - {"YCbCr.Cb", Field, 0, ""}, - {"YCbCr.Cr", Field, 0, ""}, - {"YCbCr.Y", Field, 0, ""}, - {"YCbCrModel", Var, 0, ""}, - {"YCbCrToRGB", Func, 0, "func(y uint8, cb uint8, cr uint8) (uint8, uint8, uint8)"}, - }, - "image/color/palette": { - {"Plan9", Var, 2, ""}, - {"WebSafe", Var, 2, ""}, - }, - "image/draw": { - {"(Drawer).Draw", Method, 2, ""}, - {"(Image).At", Method, 0, ""}, - {"(Image).Bounds", Method, 0, ""}, - {"(Image).ColorModel", Method, 0, ""}, - {"(Image).Set", Method, 0, ""}, - {"(Op).Draw", Method, 2, ""}, - {"(Quantizer).Quantize", Method, 2, ""}, - {"(RGBA64Image).At", Method, 17, ""}, - {"(RGBA64Image).Bounds", Method, 17, ""}, - {"(RGBA64Image).ColorModel", Method, 17, ""}, - {"(RGBA64Image).RGBA64At", Method, 17, ""}, - {"(RGBA64Image).Set", Method, 17, ""}, - {"(RGBA64Image).SetRGBA64", Method, 17, ""}, - {"Draw", Func, 0, "func(dst Image, r image.Rectangle, src image.Image, sp image.Point, op Op)"}, - {"DrawMask", Func, 0, "func(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op)"}, - {"Drawer", Type, 2, ""}, - {"FloydSteinberg", Var, 2, ""}, - {"Image", Type, 0, ""}, - {"Op", Type, 0, ""}, - {"Over", Const, 0, ""}, - {"Quantizer", Type, 2, ""}, - {"RGBA64Image", Type, 17, ""}, - {"Src", Const, 0, ""}, - }, - "image/gif": { - {"Decode", Func, 0, "func(r io.Reader) (image.Image, error)"}, - {"DecodeAll", Func, 0, "func(r io.Reader) (*GIF, error)"}, - {"DecodeConfig", Func, 0, "func(r io.Reader) (image.Config, error)"}, - {"DisposalBackground", Const, 5, ""}, - {"DisposalNone", Const, 5, ""}, - {"DisposalPrevious", Const, 5, ""}, - {"Encode", Func, 2, "func(w io.Writer, m image.Image, o *Options) error"}, - {"EncodeAll", Func, 2, "func(w io.Writer, g *GIF) error"}, - {"GIF", Type, 0, ""}, - {"GIF.BackgroundIndex", Field, 5, ""}, - {"GIF.Config", Field, 5, ""}, - {"GIF.Delay", Field, 0, ""}, - {"GIF.Disposal", Field, 5, ""}, - {"GIF.Image", Field, 0, ""}, - {"GIF.LoopCount", Field, 0, ""}, - {"Options", Type, 2, ""}, - {"Options.Drawer", Field, 2, ""}, - {"Options.NumColors", Field, 2, ""}, - {"Options.Quantizer", Field, 2, ""}, - }, - "image/jpeg": { - {"(FormatError).Error", Method, 0, ""}, - {"(Reader).Read", Method, 0, ""}, - {"(Reader).ReadByte", Method, 0, ""}, - {"(UnsupportedError).Error", Method, 0, ""}, - {"Decode", Func, 0, "func(r io.Reader) (image.Image, error)"}, - {"DecodeConfig", Func, 0, "func(r io.Reader) (image.Config, error)"}, - {"DefaultQuality", Const, 0, ""}, - {"Encode", Func, 0, "func(w io.Writer, m image.Image, o *Options) error"}, - {"FormatError", Type, 0, ""}, - {"Options", Type, 0, ""}, - {"Options.Quality", Field, 0, ""}, - {"Reader", Type, 0, ""}, - {"UnsupportedError", Type, 0, ""}, - }, - "image/png": { - {"(*Encoder).Encode", Method, 4, ""}, - {"(EncoderBufferPool).Get", Method, 9, ""}, - {"(EncoderBufferPool).Put", Method, 9, ""}, - {"(FormatError).Error", Method, 0, ""}, - {"(UnsupportedError).Error", Method, 0, ""}, - {"BestCompression", Const, 4, ""}, - {"BestSpeed", Const, 4, ""}, - {"CompressionLevel", Type, 4, ""}, - {"Decode", Func, 0, "func(r io.Reader) (image.Image, error)"}, - {"DecodeConfig", Func, 0, "func(r io.Reader) (image.Config, error)"}, - {"DefaultCompression", Const, 4, ""}, - {"Encode", Func, 0, "func(w io.Writer, m image.Image) error"}, - {"Encoder", Type, 4, ""}, - {"Encoder.BufferPool", Field, 9, ""}, - {"Encoder.CompressionLevel", Field, 4, ""}, - {"EncoderBuffer", Type, 9, ""}, - {"EncoderBufferPool", Type, 9, ""}, - {"FormatError", Type, 0, ""}, - {"NoCompression", Const, 4, ""}, - {"UnsupportedError", Type, 0, ""}, - }, - "index/suffixarray": { - {"(*Index).Bytes", Method, 0, ""}, - {"(*Index).FindAllIndex", Method, 0, ""}, - {"(*Index).Lookup", Method, 0, ""}, - {"(*Index).Read", Method, 0, ""}, - {"(*Index).Write", Method, 0, ""}, - {"Index", Type, 0, ""}, - {"New", Func, 0, "func(data []byte) *Index"}, - }, - "io": { - {"(*LimitedReader).Read", Method, 0, ""}, - {"(*OffsetWriter).Seek", Method, 20, ""}, - {"(*OffsetWriter).Write", Method, 20, ""}, - {"(*OffsetWriter).WriteAt", Method, 20, ""}, - {"(*PipeReader).Close", Method, 0, ""}, - {"(*PipeReader).CloseWithError", Method, 0, ""}, - {"(*PipeReader).Read", Method, 0, ""}, - {"(*PipeWriter).Close", Method, 0, ""}, - {"(*PipeWriter).CloseWithError", Method, 0, ""}, - {"(*PipeWriter).Write", Method, 0, ""}, - {"(*SectionReader).Outer", Method, 22, ""}, - {"(*SectionReader).Read", Method, 0, ""}, - {"(*SectionReader).ReadAt", Method, 0, ""}, - {"(*SectionReader).Seek", Method, 0, ""}, - {"(*SectionReader).Size", Method, 0, ""}, - {"(ByteReader).ReadByte", Method, 0, ""}, - {"(ByteScanner).ReadByte", Method, 0, ""}, - {"(ByteScanner).UnreadByte", Method, 0, ""}, - {"(ByteWriter).WriteByte", Method, 1, ""}, - {"(Closer).Close", Method, 0, ""}, - {"(ReadCloser).Close", Method, 0, ""}, - {"(ReadCloser).Read", Method, 0, ""}, - {"(ReadSeekCloser).Close", Method, 16, ""}, - {"(ReadSeekCloser).Read", Method, 16, ""}, - {"(ReadSeekCloser).Seek", Method, 16, ""}, - {"(ReadSeeker).Read", Method, 0, ""}, - {"(ReadSeeker).Seek", Method, 0, ""}, - {"(ReadWriteCloser).Close", Method, 0, ""}, - {"(ReadWriteCloser).Read", Method, 0, ""}, - {"(ReadWriteCloser).Write", Method, 0, ""}, - {"(ReadWriteSeeker).Read", Method, 0, ""}, - {"(ReadWriteSeeker).Seek", Method, 0, ""}, - {"(ReadWriteSeeker).Write", Method, 0, ""}, - {"(ReadWriter).Read", Method, 0, ""}, - {"(ReadWriter).Write", Method, 0, ""}, - {"(Reader).Read", Method, 0, ""}, - {"(ReaderAt).ReadAt", Method, 0, ""}, - {"(ReaderFrom).ReadFrom", Method, 0, ""}, - {"(RuneReader).ReadRune", Method, 0, ""}, - {"(RuneScanner).ReadRune", Method, 0, ""}, - {"(RuneScanner).UnreadRune", Method, 0, ""}, - {"(Seeker).Seek", Method, 0, ""}, - {"(StringWriter).WriteString", Method, 12, ""}, - {"(WriteCloser).Close", Method, 0, ""}, - {"(WriteCloser).Write", Method, 0, ""}, - {"(WriteSeeker).Seek", Method, 0, ""}, - {"(WriteSeeker).Write", Method, 0, ""}, - {"(Writer).Write", Method, 0, ""}, - {"(WriterAt).WriteAt", Method, 0, ""}, - {"(WriterTo).WriteTo", Method, 0, ""}, - {"ByteReader", Type, 0, ""}, - {"ByteScanner", Type, 0, ""}, - {"ByteWriter", Type, 1, ""}, - {"Closer", Type, 0, ""}, - {"Copy", Func, 0, "func(dst Writer, src Reader) (written int64, err error)"}, - {"CopyBuffer", Func, 5, "func(dst Writer, src Reader, buf []byte) (written int64, err error)"}, - {"CopyN", Func, 0, "func(dst Writer, src Reader, n int64) (written int64, err error)"}, - {"Discard", Var, 16, ""}, - {"EOF", Var, 0, ""}, - {"ErrClosedPipe", Var, 0, ""}, - {"ErrNoProgress", Var, 1, ""}, - {"ErrShortBuffer", Var, 0, ""}, - {"ErrShortWrite", Var, 0, ""}, - {"ErrUnexpectedEOF", Var, 0, ""}, - {"LimitReader", Func, 0, "func(r Reader, n int64) Reader"}, - {"LimitedReader", Type, 0, ""}, - {"LimitedReader.N", Field, 0, ""}, - {"LimitedReader.R", Field, 0, ""}, - {"MultiReader", Func, 0, "func(readers ...Reader) Reader"}, - {"MultiWriter", Func, 0, "func(writers ...Writer) Writer"}, - {"NewOffsetWriter", Func, 20, "func(w WriterAt, off int64) *OffsetWriter"}, - {"NewSectionReader", Func, 0, "func(r ReaderAt, off int64, n int64) *SectionReader"}, - {"NopCloser", Func, 16, "func(r Reader) ReadCloser"}, - {"OffsetWriter", Type, 20, ""}, - {"Pipe", Func, 0, "func() (*PipeReader, *PipeWriter)"}, - {"PipeReader", Type, 0, ""}, - {"PipeWriter", Type, 0, ""}, - {"ReadAll", Func, 16, "func(r Reader) ([]byte, error)"}, - {"ReadAtLeast", Func, 0, "func(r Reader, buf []byte, min int) (n int, err error)"}, - {"ReadCloser", Type, 0, ""}, - {"ReadFull", Func, 0, "func(r Reader, buf []byte) (n int, err error)"}, - {"ReadSeekCloser", Type, 16, ""}, - {"ReadSeeker", Type, 0, ""}, - {"ReadWriteCloser", Type, 0, ""}, - {"ReadWriteSeeker", Type, 0, ""}, - {"ReadWriter", Type, 0, ""}, - {"Reader", Type, 0, ""}, - {"ReaderAt", Type, 0, ""}, - {"ReaderFrom", Type, 0, ""}, - {"RuneReader", Type, 0, ""}, - {"RuneScanner", Type, 0, ""}, - {"SectionReader", Type, 0, ""}, - {"SeekCurrent", Const, 7, ""}, - {"SeekEnd", Const, 7, ""}, - {"SeekStart", Const, 7, ""}, - {"Seeker", Type, 0, ""}, - {"StringWriter", Type, 12, ""}, - {"TeeReader", Func, 0, "func(r Reader, w Writer) Reader"}, - {"WriteCloser", Type, 0, ""}, - {"WriteSeeker", Type, 0, ""}, - {"WriteString", Func, 0, "func(w Writer, s string) (n int, err error)"}, - {"Writer", Type, 0, ""}, - {"WriterAt", Type, 0, ""}, - {"WriterTo", Type, 0, ""}, - }, - "io/fs": { - {"(*PathError).Error", Method, 16, ""}, - {"(*PathError).Timeout", Method, 16, ""}, - {"(*PathError).Unwrap", Method, 16, ""}, - {"(DirEntry).Info", Method, 16, ""}, - {"(DirEntry).IsDir", Method, 16, ""}, - {"(DirEntry).Name", Method, 16, ""}, - {"(DirEntry).Type", Method, 16, ""}, - {"(FS).Open", Method, 16, ""}, - {"(File).Close", Method, 16, ""}, - {"(File).Read", Method, 16, ""}, - {"(File).Stat", Method, 16, ""}, - {"(FileInfo).IsDir", Method, 16, ""}, - {"(FileInfo).ModTime", Method, 16, ""}, - {"(FileInfo).Mode", Method, 16, ""}, - {"(FileInfo).Name", Method, 16, ""}, - {"(FileInfo).Size", Method, 16, ""}, - {"(FileInfo).Sys", Method, 16, ""}, - {"(FileMode).IsDir", Method, 16, ""}, - {"(FileMode).IsRegular", Method, 16, ""}, - {"(FileMode).Perm", Method, 16, ""}, - {"(FileMode).String", Method, 16, ""}, - {"(FileMode).Type", Method, 16, ""}, - {"(GlobFS).Glob", Method, 16, ""}, - {"(GlobFS).Open", Method, 16, ""}, - {"(ReadDirFS).Open", Method, 16, ""}, - {"(ReadDirFS).ReadDir", Method, 16, ""}, - {"(ReadDirFile).Close", Method, 16, ""}, - {"(ReadDirFile).Read", Method, 16, ""}, - {"(ReadDirFile).ReadDir", Method, 16, ""}, - {"(ReadDirFile).Stat", Method, 16, ""}, - {"(ReadFileFS).Open", Method, 16, ""}, - {"(ReadFileFS).ReadFile", Method, 16, ""}, - {"(ReadLinkFS).Lstat", Method, 25, ""}, - {"(ReadLinkFS).Open", Method, 25, ""}, - {"(ReadLinkFS).ReadLink", Method, 25, ""}, - {"(StatFS).Open", Method, 16, ""}, - {"(StatFS).Stat", Method, 16, ""}, - {"(SubFS).Open", Method, 16, ""}, - {"(SubFS).Sub", Method, 16, ""}, - {"DirEntry", Type, 16, ""}, - {"ErrClosed", Var, 16, ""}, - {"ErrExist", Var, 16, ""}, - {"ErrInvalid", Var, 16, ""}, - {"ErrNotExist", Var, 16, ""}, - {"ErrPermission", Var, 16, ""}, - {"FS", Type, 16, ""}, - {"File", Type, 16, ""}, - {"FileInfo", Type, 16, ""}, - {"FileInfoToDirEntry", Func, 17, "func(info FileInfo) DirEntry"}, - {"FileMode", Type, 16, ""}, - {"FormatDirEntry", Func, 21, "func(dir DirEntry) string"}, - {"FormatFileInfo", Func, 21, "func(info FileInfo) string"}, - {"Glob", Func, 16, "func(fsys FS, pattern string) (matches []string, err error)"}, - {"GlobFS", Type, 16, ""}, - {"Lstat", Func, 25, "func(fsys FS, name string) (FileInfo, error)"}, - {"ModeAppend", Const, 16, ""}, - {"ModeCharDevice", Const, 16, ""}, - {"ModeDevice", Const, 16, ""}, - {"ModeDir", Const, 16, ""}, - {"ModeExclusive", Const, 16, ""}, - {"ModeIrregular", Const, 16, ""}, - {"ModeNamedPipe", Const, 16, ""}, - {"ModePerm", Const, 16, ""}, - {"ModeSetgid", Const, 16, ""}, - {"ModeSetuid", Const, 16, ""}, - {"ModeSocket", Const, 16, ""}, - {"ModeSticky", Const, 16, ""}, - {"ModeSymlink", Const, 16, ""}, - {"ModeTemporary", Const, 16, ""}, - {"ModeType", Const, 16, ""}, - {"PathError", Type, 16, ""}, - {"PathError.Err", Field, 16, ""}, - {"PathError.Op", Field, 16, ""}, - {"PathError.Path", Field, 16, ""}, - {"ReadDir", Func, 16, "func(fsys FS, name string) ([]DirEntry, error)"}, - {"ReadDirFS", Type, 16, ""}, - {"ReadDirFile", Type, 16, ""}, - {"ReadFile", Func, 16, "func(fsys FS, name string) ([]byte, error)"}, - {"ReadFileFS", Type, 16, ""}, - {"ReadLink", Func, 25, "func(fsys FS, name string) (string, error)"}, - {"ReadLinkFS", Type, 25, ""}, - {"SkipAll", Var, 20, ""}, - {"SkipDir", Var, 16, ""}, - {"Stat", Func, 16, "func(fsys FS, name string) (FileInfo, error)"}, - {"StatFS", Type, 16, ""}, - {"Sub", Func, 16, "func(fsys FS, dir string) (FS, error)"}, - {"SubFS", Type, 16, ""}, - {"ValidPath", Func, 16, "func(name string) bool"}, - {"WalkDir", Func, 16, "func(fsys FS, root string, fn WalkDirFunc) error"}, - {"WalkDirFunc", Type, 16, ""}, - }, - "io/ioutil": { - {"Discard", Var, 0, ""}, - {"NopCloser", Func, 0, "func(r io.Reader) io.ReadCloser"}, - {"ReadAll", Func, 0, "func(r io.Reader) ([]byte, error)"}, - {"ReadDir", Func, 0, "func(dirname string) ([]fs.FileInfo, error)"}, - {"ReadFile", Func, 0, "func(filename string) ([]byte, error)"}, - {"TempDir", Func, 0, "func(dir string, pattern string) (name string, err error)"}, - {"TempFile", Func, 0, "func(dir string, pattern string) (f *os.File, err error)"}, - {"WriteFile", Func, 0, "func(filename string, data []byte, perm fs.FileMode) error"}, - }, - "iter": { - {"Pull", Func, 23, "func[V any](seq Seq[V]) (next func() (V, bool), stop func())"}, - {"Pull2", Func, 23, "func[K, V any](seq Seq2[K, V]) (next func() (K, V, bool), stop func())"}, - {"Seq", Type, 23, ""}, - {"Seq2", Type, 23, ""}, - }, - "log": { - {"(*Logger).Fatal", Method, 0, ""}, - {"(*Logger).Fatalf", Method, 0, ""}, - {"(*Logger).Fatalln", Method, 0, ""}, - {"(*Logger).Flags", Method, 0, ""}, - {"(*Logger).Output", Method, 0, ""}, - {"(*Logger).Panic", Method, 0, ""}, - {"(*Logger).Panicf", Method, 0, ""}, - {"(*Logger).Panicln", Method, 0, ""}, - {"(*Logger).Prefix", Method, 0, ""}, - {"(*Logger).Print", Method, 0, ""}, - {"(*Logger).Printf", Method, 0, ""}, - {"(*Logger).Println", Method, 0, ""}, - {"(*Logger).SetFlags", Method, 0, ""}, - {"(*Logger).SetOutput", Method, 5, ""}, - {"(*Logger).SetPrefix", Method, 0, ""}, - {"(*Logger).Writer", Method, 12, ""}, - {"Default", Func, 16, "func() *Logger"}, - {"Fatal", Func, 0, "func(v ...any)"}, - {"Fatalf", Func, 0, "func(format string, v ...any)"}, - {"Fatalln", Func, 0, "func(v ...any)"}, - {"Flags", Func, 0, "func() int"}, - {"LUTC", Const, 5, ""}, - {"Ldate", Const, 0, ""}, - {"Llongfile", Const, 0, ""}, - {"Lmicroseconds", Const, 0, ""}, - {"Lmsgprefix", Const, 14, ""}, - {"Logger", Type, 0, ""}, - {"Lshortfile", Const, 0, ""}, - {"LstdFlags", Const, 0, ""}, - {"Ltime", Const, 0, ""}, - {"New", Func, 0, "func(out io.Writer, prefix string, flag int) *Logger"}, - {"Output", Func, 5, "func(calldepth int, s string) error"}, - {"Panic", Func, 0, "func(v ...any)"}, - {"Panicf", Func, 0, "func(format string, v ...any)"}, - {"Panicln", Func, 0, "func(v ...any)"}, - {"Prefix", Func, 0, "func() string"}, - {"Print", Func, 0, "func(v ...any)"}, - {"Printf", Func, 0, "func(format string, v ...any)"}, - {"Println", Func, 0, "func(v ...any)"}, - {"SetFlags", Func, 0, "func(flag int)"}, - {"SetOutput", Func, 0, "func(w io.Writer)"}, - {"SetPrefix", Func, 0, "func(prefix string)"}, - {"Writer", Func, 13, "func() io.Writer"}, - }, - "log/slog": { - {"(*JSONHandler).Enabled", Method, 21, ""}, - {"(*JSONHandler).Handle", Method, 21, ""}, - {"(*JSONHandler).WithAttrs", Method, 21, ""}, - {"(*JSONHandler).WithGroup", Method, 21, ""}, - {"(*Level).UnmarshalJSON", Method, 21, ""}, - {"(*Level).UnmarshalText", Method, 21, ""}, - {"(*LevelVar).AppendText", Method, 24, ""}, - {"(*LevelVar).Level", Method, 21, ""}, - {"(*LevelVar).MarshalText", Method, 21, ""}, - {"(*LevelVar).Set", Method, 21, ""}, - {"(*LevelVar).String", Method, 21, ""}, - {"(*LevelVar).UnmarshalText", Method, 21, ""}, - {"(*Logger).Debug", Method, 21, ""}, - {"(*Logger).DebugContext", Method, 21, ""}, - {"(*Logger).Enabled", Method, 21, ""}, - {"(*Logger).Error", Method, 21, ""}, - {"(*Logger).ErrorContext", Method, 21, ""}, - {"(*Logger).Handler", Method, 21, ""}, - {"(*Logger).Info", Method, 21, ""}, - {"(*Logger).InfoContext", Method, 21, ""}, - {"(*Logger).Log", Method, 21, ""}, - {"(*Logger).LogAttrs", Method, 21, ""}, - {"(*Logger).Warn", Method, 21, ""}, - {"(*Logger).WarnContext", Method, 21, ""}, - {"(*Logger).With", Method, 21, ""}, - {"(*Logger).WithGroup", Method, 21, ""}, - {"(*MultiHandler).Enabled", Method, 26, ""}, - {"(*MultiHandler).Handle", Method, 26, ""}, - {"(*MultiHandler).WithAttrs", Method, 26, ""}, - {"(*MultiHandler).WithGroup", Method, 26, ""}, - {"(*Record).Add", Method, 21, ""}, - {"(*Record).AddAttrs", Method, 21, ""}, - {"(*TextHandler).Enabled", Method, 21, ""}, - {"(*TextHandler).Handle", Method, 21, ""}, - {"(*TextHandler).WithAttrs", Method, 21, ""}, - {"(*TextHandler).WithGroup", Method, 21, ""}, - {"(Attr).Equal", Method, 21, ""}, - {"(Attr).String", Method, 21, ""}, - {"(Handler).Enabled", Method, 21, ""}, - {"(Handler).Handle", Method, 21, ""}, - {"(Handler).WithAttrs", Method, 21, ""}, - {"(Handler).WithGroup", Method, 21, ""}, - {"(Kind).String", Method, 21, ""}, - {"(Level).AppendText", Method, 24, ""}, - {"(Level).Level", Method, 21, ""}, - {"(Level).MarshalJSON", Method, 21, ""}, - {"(Level).MarshalText", Method, 21, ""}, - {"(Level).String", Method, 21, ""}, - {"(Leveler).Level", Method, 21, ""}, - {"(LogValuer).LogValue", Method, 21, ""}, - {"(Record).Attrs", Method, 21, ""}, - {"(Record).Clone", Method, 21, ""}, - {"(Record).NumAttrs", Method, 21, ""}, - {"(Record).Source", Method, 25, ""}, - {"(Value).Any", Method, 21, ""}, - {"(Value).Bool", Method, 21, ""}, - {"(Value).Duration", Method, 21, ""}, - {"(Value).Equal", Method, 21, ""}, - {"(Value).Float64", Method, 21, ""}, - {"(Value).Group", Method, 21, ""}, - {"(Value).Int64", Method, 21, ""}, - {"(Value).Kind", Method, 21, ""}, - {"(Value).LogValuer", Method, 21, ""}, - {"(Value).Resolve", Method, 21, ""}, - {"(Value).String", Method, 21, ""}, - {"(Value).Time", Method, 21, ""}, - {"(Value).Uint64", Method, 21, ""}, - {"Any", Func, 21, "func(key string, value any) Attr"}, - {"AnyValue", Func, 21, "func(v any) Value"}, - {"Attr", Type, 21, ""}, - {"Attr.Key", Field, 21, ""}, - {"Attr.Value", Field, 21, ""}, - {"Bool", Func, 21, "func(key string, v bool) Attr"}, - {"BoolValue", Func, 21, "func(v bool) Value"}, - {"Debug", Func, 21, "func(msg string, args ...any)"}, - {"DebugContext", Func, 21, "func(ctx context.Context, msg string, args ...any)"}, - {"Default", Func, 21, "func() *Logger"}, - {"DiscardHandler", Var, 24, ""}, - {"Duration", Func, 21, "func(key string, v time.Duration) Attr"}, - {"DurationValue", Func, 21, "func(v time.Duration) Value"}, - {"Error", Func, 21, "func(msg string, args ...any)"}, - {"ErrorContext", Func, 21, "func(ctx context.Context, msg string, args ...any)"}, - {"Float64", Func, 21, "func(key string, v float64) Attr"}, - {"Float64Value", Func, 21, "func(v float64) Value"}, - {"Group", Func, 21, "func(key string, args ...any) Attr"}, - {"GroupAttrs", Func, 25, "func(key string, attrs ...Attr) Attr"}, - {"GroupValue", Func, 21, "func(as ...Attr) Value"}, - {"Handler", Type, 21, ""}, - {"HandlerOptions", Type, 21, ""}, - {"HandlerOptions.AddSource", Field, 21, ""}, - {"HandlerOptions.Level", Field, 21, ""}, - {"HandlerOptions.ReplaceAttr", Field, 21, ""}, - {"Info", Func, 21, "func(msg string, args ...any)"}, - {"InfoContext", Func, 21, "func(ctx context.Context, msg string, args ...any)"}, - {"Int", Func, 21, "func(key string, value int) Attr"}, - {"Int64", Func, 21, "func(key string, value int64) Attr"}, - {"Int64Value", Func, 21, "func(v int64) Value"}, - {"IntValue", Func, 21, "func(v int) Value"}, - {"JSONHandler", Type, 21, ""}, - {"Kind", Type, 21, ""}, - {"KindAny", Const, 21, ""}, - {"KindBool", Const, 21, ""}, - {"KindDuration", Const, 21, ""}, - {"KindFloat64", Const, 21, ""}, - {"KindGroup", Const, 21, ""}, - {"KindInt64", Const, 21, ""}, - {"KindLogValuer", Const, 21, ""}, - {"KindString", Const, 21, ""}, - {"KindTime", Const, 21, ""}, - {"KindUint64", Const, 21, ""}, - {"Level", Type, 21, ""}, - {"LevelDebug", Const, 21, ""}, - {"LevelError", Const, 21, ""}, - {"LevelInfo", Const, 21, ""}, - {"LevelKey", Const, 21, ""}, - {"LevelVar", Type, 21, ""}, - {"LevelWarn", Const, 21, ""}, - {"Leveler", Type, 21, ""}, - {"Log", Func, 21, "func(ctx context.Context, level Level, msg string, args ...any)"}, - {"LogAttrs", Func, 21, "func(ctx context.Context, level Level, msg string, attrs ...Attr)"}, - {"LogValuer", Type, 21, ""}, - {"Logger", Type, 21, ""}, - {"MessageKey", Const, 21, ""}, - {"MultiHandler", Type, 26, ""}, - {"New", Func, 21, "func(h Handler) *Logger"}, - {"NewJSONHandler", Func, 21, "func(w io.Writer, opts *HandlerOptions) *JSONHandler"}, - {"NewLogLogger", Func, 21, "func(h Handler, level Level) *log.Logger"}, - {"NewMultiHandler", Func, 26, "func(handlers ...Handler) *MultiHandler"}, - {"NewRecord", Func, 21, "func(t time.Time, level Level, msg string, pc uintptr) Record"}, - {"NewTextHandler", Func, 21, "func(w io.Writer, opts *HandlerOptions) *TextHandler"}, - {"Record", Type, 21, ""}, - {"Record.Level", Field, 21, ""}, - {"Record.Message", Field, 21, ""}, - {"Record.PC", Field, 21, ""}, - {"Record.Time", Field, 21, ""}, - {"SetDefault", Func, 21, "func(l *Logger)"}, - {"SetLogLoggerLevel", Func, 22, "func(level Level) (oldLevel Level)"}, - {"Source", Type, 21, ""}, - {"Source.File", Field, 21, ""}, - {"Source.Function", Field, 21, ""}, - {"Source.Line", Field, 21, ""}, - {"SourceKey", Const, 21, ""}, - {"String", Func, 21, "func(key string, value string) Attr"}, - {"StringValue", Func, 21, "func(value string) Value"}, - {"TextHandler", Type, 21, ""}, - {"Time", Func, 21, "func(key string, v time.Time) Attr"}, - {"TimeKey", Const, 21, ""}, - {"TimeValue", Func, 21, "func(v time.Time) Value"}, - {"Uint64", Func, 21, "func(key string, v uint64) Attr"}, - {"Uint64Value", Func, 21, "func(v uint64) Value"}, - {"Value", Type, 21, ""}, - {"Warn", Func, 21, "func(msg string, args ...any)"}, - {"WarnContext", Func, 21, "func(ctx context.Context, msg string, args ...any)"}, - {"With", Func, 21, "func(args ...any) *Logger"}, - }, - "log/syslog": { - {"(*Writer).Alert", Method, 0, ""}, - {"(*Writer).Close", Method, 0, ""}, - {"(*Writer).Crit", Method, 0, ""}, - {"(*Writer).Debug", Method, 0, ""}, - {"(*Writer).Emerg", Method, 0, ""}, - {"(*Writer).Err", Method, 0, ""}, - {"(*Writer).Info", Method, 0, ""}, - {"(*Writer).Notice", Method, 0, ""}, - {"(*Writer).Warning", Method, 0, ""}, - {"(*Writer).Write", Method, 0, ""}, - {"Dial", Func, 0, "func(network string, raddr string, priority Priority, tag string) (*Writer, error)"}, - {"LOG_ALERT", Const, 0, ""}, - {"LOG_AUTH", Const, 1, ""}, - {"LOG_AUTHPRIV", Const, 1, ""}, - {"LOG_CRIT", Const, 0, ""}, - {"LOG_CRON", Const, 1, ""}, - {"LOG_DAEMON", Const, 1, ""}, - {"LOG_DEBUG", Const, 0, ""}, - {"LOG_EMERG", Const, 0, ""}, - {"LOG_ERR", Const, 0, ""}, - {"LOG_FTP", Const, 1, ""}, - {"LOG_INFO", Const, 0, ""}, - {"LOG_KERN", Const, 1, ""}, - {"LOG_LOCAL0", Const, 1, ""}, - {"LOG_LOCAL1", Const, 1, ""}, - {"LOG_LOCAL2", Const, 1, ""}, - {"LOG_LOCAL3", Const, 1, ""}, - {"LOG_LOCAL4", Const, 1, ""}, - {"LOG_LOCAL5", Const, 1, ""}, - {"LOG_LOCAL6", Const, 1, ""}, - {"LOG_LOCAL7", Const, 1, ""}, - {"LOG_LPR", Const, 1, ""}, - {"LOG_MAIL", Const, 1, ""}, - {"LOG_NEWS", Const, 1, ""}, - {"LOG_NOTICE", Const, 0, ""}, - {"LOG_SYSLOG", Const, 1, ""}, - {"LOG_USER", Const, 1, ""}, - {"LOG_UUCP", Const, 1, ""}, - {"LOG_WARNING", Const, 0, ""}, - {"New", Func, 0, "func(priority Priority, tag string) (*Writer, error)"}, - {"NewLogger", Func, 0, "func(p Priority, logFlag int) (*log.Logger, error)"}, - {"Priority", Type, 0, ""}, - {"Writer", Type, 0, ""}, - }, - "maps": { - {"All", Func, 23, "func[Map ~map[K]V, K comparable, V any](m Map) iter.Seq2[K, V]"}, - {"Clone", Func, 21, "func[M ~map[K]V, K comparable, V any](m M) M"}, - {"Collect", Func, 23, "func[K comparable, V any](seq iter.Seq2[K, V]) map[K]V"}, - {"Copy", Func, 21, "func[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2)"}, - {"DeleteFunc", Func, 21, "func[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool)"}, - {"Equal", Func, 21, "func[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool"}, - {"EqualFunc", Func, 21, "func[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool"}, - {"Insert", Func, 23, "func[Map ~map[K]V, K comparable, V any](m Map, seq iter.Seq2[K, V])"}, - {"Keys", Func, 23, "func[Map ~map[K]V, K comparable, V any](m Map) iter.Seq[K]"}, - {"Values", Func, 23, "func[Map ~map[K]V, K comparable, V any](m Map) iter.Seq[V]"}, - }, - "math": { - {"Abs", Func, 0, "func(x float64) float64"}, - {"Acos", Func, 0, "func(x float64) float64"}, - {"Acosh", Func, 0, "func(x float64) float64"}, - {"Asin", Func, 0, "func(x float64) float64"}, - {"Asinh", Func, 0, "func(x float64) float64"}, - {"Atan", Func, 0, "func(x float64) float64"}, - {"Atan2", Func, 0, "func(y float64, x float64) float64"}, - {"Atanh", Func, 0, "func(x float64) float64"}, - {"Cbrt", Func, 0, "func(x float64) float64"}, - {"Ceil", Func, 0, "func(x float64) float64"}, - {"Copysign", Func, 0, "func(f float64, sign float64) float64"}, - {"Cos", Func, 0, "func(x float64) float64"}, - {"Cosh", Func, 0, "func(x float64) float64"}, - {"Dim", Func, 0, "func(x float64, y float64) float64"}, - {"E", Const, 0, ""}, - {"Erf", Func, 0, "func(x float64) float64"}, - {"Erfc", Func, 0, "func(x float64) float64"}, - {"Erfcinv", Func, 10, "func(x float64) float64"}, - {"Erfinv", Func, 10, "func(x float64) float64"}, - {"Exp", Func, 0, "func(x float64) float64"}, - {"Exp2", Func, 0, "func(x float64) float64"}, - {"Expm1", Func, 0, "func(x float64) float64"}, - {"FMA", Func, 14, "func(x float64, y float64, z float64) float64"}, - {"Float32bits", Func, 0, "func(f float32) uint32"}, - {"Float32frombits", Func, 0, "func(b uint32) float32"}, - {"Float64bits", Func, 0, "func(f float64) uint64"}, - {"Float64frombits", Func, 0, "func(b uint64) float64"}, - {"Floor", Func, 0, "func(x float64) float64"}, - {"Frexp", Func, 0, "func(f float64) (frac float64, exp int)"}, - {"Gamma", Func, 0, "func(x float64) float64"}, - {"Hypot", Func, 0, "func(p float64, q float64) float64"}, - {"Ilogb", Func, 0, "func(x float64) int"}, - {"Inf", Func, 0, "func(sign int) float64"}, - {"IsInf", Func, 0, "func(f float64, sign int) bool"}, - {"IsNaN", Func, 0, "func(f float64) (is bool)"}, - {"J0", Func, 0, "func(x float64) float64"}, - {"J1", Func, 0, "func(x float64) float64"}, - {"Jn", Func, 0, "func(n int, x float64) float64"}, - {"Ldexp", Func, 0, "func(frac float64, exp int) float64"}, - {"Lgamma", Func, 0, "func(x float64) (lgamma float64, sign int)"}, - {"Ln10", Const, 0, ""}, - {"Ln2", Const, 0, ""}, - {"Log", Func, 0, "func(x float64) float64"}, - {"Log10", Func, 0, "func(x float64) float64"}, - {"Log10E", Const, 0, ""}, - {"Log1p", Func, 0, "func(x float64) float64"}, - {"Log2", Func, 0, "func(x float64) float64"}, - {"Log2E", Const, 0, ""}, - {"Logb", Func, 0, "func(x float64) float64"}, - {"Max", Func, 0, "func(x float64, y float64) float64"}, - {"MaxFloat32", Const, 0, ""}, - {"MaxFloat64", Const, 0, ""}, - {"MaxInt", Const, 17, ""}, - {"MaxInt16", Const, 0, ""}, - {"MaxInt32", Const, 0, ""}, - {"MaxInt64", Const, 0, ""}, - {"MaxInt8", Const, 0, ""}, - {"MaxUint", Const, 17, ""}, - {"MaxUint16", Const, 0, ""}, - {"MaxUint32", Const, 0, ""}, - {"MaxUint64", Const, 0, ""}, - {"MaxUint8", Const, 0, ""}, - {"Min", Func, 0, "func(x float64, y float64) float64"}, - {"MinInt", Const, 17, ""}, - {"MinInt16", Const, 0, ""}, - {"MinInt32", Const, 0, ""}, - {"MinInt64", Const, 0, ""}, - {"MinInt8", Const, 0, ""}, - {"Mod", Func, 0, "func(x float64, y float64) float64"}, - {"Modf", Func, 0, "func(f float64) (integer float64, fractional float64)"}, - {"NaN", Func, 0, "func() float64"}, - {"Nextafter", Func, 0, "func(x float64, y float64) (r float64)"}, - {"Nextafter32", Func, 4, "func(x float32, y float32) (r float32)"}, - {"Phi", Const, 0, ""}, - {"Pi", Const, 0, ""}, - {"Pow", Func, 0, "func(x float64, y float64) float64"}, - {"Pow10", Func, 0, "func(n int) float64"}, - {"Remainder", Func, 0, "func(x float64, y float64) float64"}, - {"Round", Func, 10, "func(x float64) float64"}, - {"RoundToEven", Func, 10, "func(x float64) float64"}, - {"Signbit", Func, 0, "func(x float64) bool"}, - {"Sin", Func, 0, "func(x float64) float64"}, - {"Sincos", Func, 0, "func(x float64) (sin float64, cos float64)"}, - {"Sinh", Func, 0, "func(x float64) float64"}, - {"SmallestNonzeroFloat32", Const, 0, ""}, - {"SmallestNonzeroFloat64", Const, 0, ""}, - {"Sqrt", Func, 0, "func(x float64) float64"}, - {"Sqrt2", Const, 0, ""}, - {"SqrtE", Const, 0, ""}, - {"SqrtPhi", Const, 0, ""}, - {"SqrtPi", Const, 0, ""}, - {"Tan", Func, 0, "func(x float64) float64"}, - {"Tanh", Func, 0, "func(x float64) float64"}, - {"Trunc", Func, 0, "func(x float64) float64"}, - {"Y0", Func, 0, "func(x float64) float64"}, - {"Y1", Func, 0, "func(x float64) float64"}, - {"Yn", Func, 0, "func(n int, x float64) float64"}, - }, - "math/big": { - {"(*Float).Abs", Method, 5, ""}, - {"(*Float).Acc", Method, 5, ""}, - {"(*Float).Add", Method, 5, ""}, - {"(*Float).Append", Method, 5, ""}, - {"(*Float).AppendText", Method, 24, ""}, - {"(*Float).Cmp", Method, 5, ""}, - {"(*Float).Copy", Method, 5, ""}, - {"(*Float).Float32", Method, 5, ""}, - {"(*Float).Float64", Method, 5, ""}, - {"(*Float).Format", Method, 5, ""}, - {"(*Float).GobDecode", Method, 7, ""}, - {"(*Float).GobEncode", Method, 7, ""}, - {"(*Float).Int", Method, 5, ""}, - {"(*Float).Int64", Method, 5, ""}, - {"(*Float).IsInf", Method, 5, ""}, - {"(*Float).IsInt", Method, 5, ""}, - {"(*Float).MantExp", Method, 5, ""}, - {"(*Float).MarshalText", Method, 6, ""}, - {"(*Float).MinPrec", Method, 5, ""}, - {"(*Float).Mode", Method, 5, ""}, - {"(*Float).Mul", Method, 5, ""}, - {"(*Float).Neg", Method, 5, ""}, - {"(*Float).Parse", Method, 5, ""}, - {"(*Float).Prec", Method, 5, ""}, - {"(*Float).Quo", Method, 5, ""}, - {"(*Float).Rat", Method, 5, ""}, - {"(*Float).Scan", Method, 8, ""}, - {"(*Float).Set", Method, 5, ""}, - {"(*Float).SetFloat64", Method, 5, ""}, - {"(*Float).SetInf", Method, 5, ""}, - {"(*Float).SetInt", Method, 5, ""}, - {"(*Float).SetInt64", Method, 5, ""}, - {"(*Float).SetMantExp", Method, 5, ""}, - {"(*Float).SetMode", Method, 5, ""}, - {"(*Float).SetPrec", Method, 5, ""}, - {"(*Float).SetRat", Method, 5, ""}, - {"(*Float).SetString", Method, 5, ""}, - {"(*Float).SetUint64", Method, 5, ""}, - {"(*Float).Sign", Method, 5, ""}, - {"(*Float).Signbit", Method, 5, ""}, - {"(*Float).Sqrt", Method, 10, ""}, - {"(*Float).String", Method, 5, ""}, - {"(*Float).Sub", Method, 5, ""}, - {"(*Float).Text", Method, 5, ""}, - {"(*Float).Uint64", Method, 5, ""}, - {"(*Float).UnmarshalText", Method, 6, ""}, - {"(*Int).Abs", Method, 0, ""}, - {"(*Int).Add", Method, 0, ""}, - {"(*Int).And", Method, 0, ""}, - {"(*Int).AndNot", Method, 0, ""}, - {"(*Int).Append", Method, 6, ""}, - {"(*Int).AppendText", Method, 24, ""}, - {"(*Int).Binomial", Method, 0, ""}, - {"(*Int).Bit", Method, 0, ""}, - {"(*Int).BitLen", Method, 0, ""}, - {"(*Int).Bits", Method, 0, ""}, - {"(*Int).Bytes", Method, 0, ""}, - {"(*Int).Cmp", Method, 0, ""}, - {"(*Int).CmpAbs", Method, 10, ""}, - {"(*Int).Div", Method, 0, ""}, - {"(*Int).DivMod", Method, 0, ""}, - {"(*Int).Exp", Method, 0, ""}, - {"(*Int).FillBytes", Method, 15, ""}, - {"(*Int).Float64", Method, 21, ""}, - {"(*Int).Format", Method, 0, ""}, - {"(*Int).GCD", Method, 0, ""}, - {"(*Int).GobDecode", Method, 0, ""}, - {"(*Int).GobEncode", Method, 0, ""}, - {"(*Int).Int64", Method, 0, ""}, - {"(*Int).IsInt64", Method, 9, ""}, - {"(*Int).IsUint64", Method, 9, ""}, - {"(*Int).Lsh", Method, 0, ""}, - {"(*Int).MarshalJSON", Method, 1, ""}, - {"(*Int).MarshalText", Method, 3, ""}, - {"(*Int).Mod", Method, 0, ""}, - {"(*Int).ModInverse", Method, 0, ""}, - {"(*Int).ModSqrt", Method, 5, ""}, - {"(*Int).Mul", Method, 0, ""}, - {"(*Int).MulRange", Method, 0, ""}, - {"(*Int).Neg", Method, 0, ""}, - {"(*Int).Not", Method, 0, ""}, - {"(*Int).Or", Method, 0, ""}, - {"(*Int).ProbablyPrime", Method, 0, ""}, - {"(*Int).Quo", Method, 0, ""}, - {"(*Int).QuoRem", Method, 0, ""}, - {"(*Int).Rand", Method, 0, ""}, - {"(*Int).Rem", Method, 0, ""}, - {"(*Int).Rsh", Method, 0, ""}, - {"(*Int).Scan", Method, 0, ""}, - {"(*Int).Set", Method, 0, ""}, - {"(*Int).SetBit", Method, 0, ""}, - {"(*Int).SetBits", Method, 0, ""}, - {"(*Int).SetBytes", Method, 0, ""}, - {"(*Int).SetInt64", Method, 0, ""}, - {"(*Int).SetString", Method, 0, ""}, - {"(*Int).SetUint64", Method, 1, ""}, - {"(*Int).Sign", Method, 0, ""}, - {"(*Int).Sqrt", Method, 8, ""}, - {"(*Int).String", Method, 0, ""}, - {"(*Int).Sub", Method, 0, ""}, - {"(*Int).Text", Method, 6, ""}, - {"(*Int).TrailingZeroBits", Method, 13, ""}, - {"(*Int).Uint64", Method, 1, ""}, - {"(*Int).UnmarshalJSON", Method, 1, ""}, - {"(*Int).UnmarshalText", Method, 3, ""}, - {"(*Int).Xor", Method, 0, ""}, - {"(*Rat).Abs", Method, 0, ""}, - {"(*Rat).Add", Method, 0, ""}, - {"(*Rat).AppendText", Method, 24, ""}, - {"(*Rat).Cmp", Method, 0, ""}, - {"(*Rat).Denom", Method, 0, ""}, - {"(*Rat).Float32", Method, 4, ""}, - {"(*Rat).Float64", Method, 1, ""}, - {"(*Rat).FloatPrec", Method, 22, ""}, - {"(*Rat).FloatString", Method, 0, ""}, - {"(*Rat).GobDecode", Method, 0, ""}, - {"(*Rat).GobEncode", Method, 0, ""}, - {"(*Rat).Inv", Method, 0, ""}, - {"(*Rat).IsInt", Method, 0, ""}, - {"(*Rat).MarshalText", Method, 3, ""}, - {"(*Rat).Mul", Method, 0, ""}, - {"(*Rat).Neg", Method, 0, ""}, - {"(*Rat).Num", Method, 0, ""}, - {"(*Rat).Quo", Method, 0, ""}, - {"(*Rat).RatString", Method, 0, ""}, - {"(*Rat).Scan", Method, 0, ""}, - {"(*Rat).Set", Method, 0, ""}, - {"(*Rat).SetFloat64", Method, 1, ""}, - {"(*Rat).SetFrac", Method, 0, ""}, - {"(*Rat).SetFrac64", Method, 0, ""}, - {"(*Rat).SetInt", Method, 0, ""}, - {"(*Rat).SetInt64", Method, 0, ""}, - {"(*Rat).SetString", Method, 0, ""}, - {"(*Rat).SetUint64", Method, 13, ""}, - {"(*Rat).Sign", Method, 0, ""}, - {"(*Rat).String", Method, 0, ""}, - {"(*Rat).Sub", Method, 0, ""}, - {"(*Rat).UnmarshalText", Method, 3, ""}, - {"(Accuracy).String", Method, 5, ""}, - {"(ErrNaN).Error", Method, 5, ""}, - {"(RoundingMode).String", Method, 5, ""}, - {"Above", Const, 5, ""}, - {"Accuracy", Type, 5, ""}, - {"AwayFromZero", Const, 5, ""}, - {"Below", Const, 5, ""}, - {"ErrNaN", Type, 5, ""}, - {"Exact", Const, 5, ""}, - {"Float", Type, 5, ""}, - {"Int", Type, 0, ""}, - {"Jacobi", Func, 5, "func(x *Int, y *Int) int"}, - {"MaxBase", Const, 0, ""}, - {"MaxExp", Const, 5, ""}, - {"MaxPrec", Const, 5, ""}, - {"MinExp", Const, 5, ""}, - {"NewFloat", Func, 5, "func(x float64) *Float"}, - {"NewInt", Func, 0, "func(x int64) *Int"}, - {"NewRat", Func, 0, "func(a int64, b int64) *Rat"}, - {"ParseFloat", Func, 5, "func(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error)"}, - {"Rat", Type, 0, ""}, - {"RoundingMode", Type, 5, ""}, - {"ToNearestAway", Const, 5, ""}, - {"ToNearestEven", Const, 5, ""}, - {"ToNegativeInf", Const, 5, ""}, - {"ToPositiveInf", Const, 5, ""}, - {"ToZero", Const, 5, ""}, - {"Word", Type, 0, ""}, - }, - "math/bits": { - {"Add", Func, 12, "func(x uint, y uint, carry uint) (sum uint, carryOut uint)"}, - {"Add32", Func, 12, "func(x uint32, y uint32, carry uint32) (sum uint32, carryOut uint32)"}, - {"Add64", Func, 12, "func(x uint64, y uint64, carry uint64) (sum uint64, carryOut uint64)"}, - {"Div", Func, 12, "func(hi uint, lo uint, y uint) (quo uint, rem uint)"}, - {"Div32", Func, 12, "func(hi uint32, lo uint32, y uint32) (quo uint32, rem uint32)"}, - {"Div64", Func, 12, "func(hi uint64, lo uint64, y uint64) (quo uint64, rem uint64)"}, - {"LeadingZeros", Func, 9, "func(x uint) int"}, - {"LeadingZeros16", Func, 9, "func(x uint16) int"}, - {"LeadingZeros32", Func, 9, "func(x uint32) int"}, - {"LeadingZeros64", Func, 9, "func(x uint64) int"}, - {"LeadingZeros8", Func, 9, "func(x uint8) int"}, - {"Len", Func, 9, "func(x uint) int"}, - {"Len16", Func, 9, "func(x uint16) (n int)"}, - {"Len32", Func, 9, "func(x uint32) (n int)"}, - {"Len64", Func, 9, "func(x uint64) (n int)"}, - {"Len8", Func, 9, "func(x uint8) int"}, - {"Mul", Func, 12, "func(x uint, y uint) (hi uint, lo uint)"}, - {"Mul32", Func, 12, "func(x uint32, y uint32) (hi uint32, lo uint32)"}, - {"Mul64", Func, 12, "func(x uint64, y uint64) (hi uint64, lo uint64)"}, - {"OnesCount", Func, 9, "func(x uint) int"}, - {"OnesCount16", Func, 9, "func(x uint16) int"}, - {"OnesCount32", Func, 9, "func(x uint32) int"}, - {"OnesCount64", Func, 9, "func(x uint64) int"}, - {"OnesCount8", Func, 9, "func(x uint8) int"}, - {"Rem", Func, 14, "func(hi uint, lo uint, y uint) uint"}, - {"Rem32", Func, 14, "func(hi uint32, lo uint32, y uint32) uint32"}, - {"Rem64", Func, 14, "func(hi uint64, lo uint64, y uint64) uint64"}, - {"Reverse", Func, 9, "func(x uint) uint"}, - {"Reverse16", Func, 9, "func(x uint16) uint16"}, - {"Reverse32", Func, 9, "func(x uint32) uint32"}, - {"Reverse64", Func, 9, "func(x uint64) uint64"}, - {"Reverse8", Func, 9, "func(x uint8) uint8"}, - {"ReverseBytes", Func, 9, "func(x uint) uint"}, - {"ReverseBytes16", Func, 9, "func(x uint16) uint16"}, - {"ReverseBytes32", Func, 9, "func(x uint32) uint32"}, - {"ReverseBytes64", Func, 9, "func(x uint64) uint64"}, - {"RotateLeft", Func, 9, "func(x uint, k int) uint"}, - {"RotateLeft16", Func, 9, "func(x uint16, k int) uint16"}, - {"RotateLeft32", Func, 9, "func(x uint32, k int) uint32"}, - {"RotateLeft64", Func, 9, "func(x uint64, k int) uint64"}, - {"RotateLeft8", Func, 9, "func(x uint8, k int) uint8"}, - {"Sub", Func, 12, "func(x uint, y uint, borrow uint) (diff uint, borrowOut uint)"}, - {"Sub32", Func, 12, "func(x uint32, y uint32, borrow uint32) (diff uint32, borrowOut uint32)"}, - {"Sub64", Func, 12, "func(x uint64, y uint64, borrow uint64) (diff uint64, borrowOut uint64)"}, - {"TrailingZeros", Func, 9, "func(x uint) int"}, - {"TrailingZeros16", Func, 9, "func(x uint16) int"}, - {"TrailingZeros32", Func, 9, "func(x uint32) int"}, - {"TrailingZeros64", Func, 9, "func(x uint64) int"}, - {"TrailingZeros8", Func, 9, "func(x uint8) int"}, - {"UintSize", Const, 9, ""}, - }, - "math/cmplx": { - {"Abs", Func, 0, "func(x complex128) float64"}, - {"Acos", Func, 0, "func(x complex128) complex128"}, - {"Acosh", Func, 0, "func(x complex128) complex128"}, - {"Asin", Func, 0, "func(x complex128) complex128"}, - {"Asinh", Func, 0, "func(x complex128) complex128"}, - {"Atan", Func, 0, "func(x complex128) complex128"}, - {"Atanh", Func, 0, "func(x complex128) complex128"}, - {"Conj", Func, 0, "func(x complex128) complex128"}, - {"Cos", Func, 0, "func(x complex128) complex128"}, - {"Cosh", Func, 0, "func(x complex128) complex128"}, - {"Cot", Func, 0, "func(x complex128) complex128"}, - {"Exp", Func, 0, "func(x complex128) complex128"}, - {"Inf", Func, 0, "func() complex128"}, - {"IsInf", Func, 0, "func(x complex128) bool"}, - {"IsNaN", Func, 0, "func(x complex128) bool"}, - {"Log", Func, 0, "func(x complex128) complex128"}, - {"Log10", Func, 0, "func(x complex128) complex128"}, - {"NaN", Func, 0, "func() complex128"}, - {"Phase", Func, 0, "func(x complex128) float64"}, - {"Polar", Func, 0, "func(x complex128) (r float64, θ float64)"}, - {"Pow", Func, 0, "func(x complex128, y complex128) complex128"}, - {"Rect", Func, 0, "func(r float64, θ float64) complex128"}, - {"Sin", Func, 0, "func(x complex128) complex128"}, - {"Sinh", Func, 0, "func(x complex128) complex128"}, - {"Sqrt", Func, 0, "func(x complex128) complex128"}, - {"Tan", Func, 0, "func(x complex128) complex128"}, - {"Tanh", Func, 0, "func(x complex128) complex128"}, - }, - "math/rand": { - {"(*Rand).ExpFloat64", Method, 0, ""}, - {"(*Rand).Float32", Method, 0, ""}, - {"(*Rand).Float64", Method, 0, ""}, - {"(*Rand).Int", Method, 0, ""}, - {"(*Rand).Int31", Method, 0, ""}, - {"(*Rand).Int31n", Method, 0, ""}, - {"(*Rand).Int63", Method, 0, ""}, - {"(*Rand).Int63n", Method, 0, ""}, - {"(*Rand).Intn", Method, 0, ""}, - {"(*Rand).NormFloat64", Method, 0, ""}, - {"(*Rand).Perm", Method, 0, ""}, - {"(*Rand).Read", Method, 6, ""}, - {"(*Rand).Seed", Method, 0, ""}, - {"(*Rand).Shuffle", Method, 10, ""}, - {"(*Rand).Uint32", Method, 0, ""}, - {"(*Rand).Uint64", Method, 8, ""}, - {"(*Zipf).Uint64", Method, 0, ""}, - {"(Source).Int63", Method, 0, ""}, - {"(Source).Seed", Method, 0, ""}, - {"(Source64).Int63", Method, 8, ""}, - {"(Source64).Seed", Method, 8, ""}, - {"(Source64).Uint64", Method, 8, ""}, - {"ExpFloat64", Func, 0, "func() float64"}, - {"Float32", Func, 0, "func() float32"}, - {"Float64", Func, 0, "func() float64"}, - {"Int", Func, 0, "func() int"}, - {"Int31", Func, 0, "func() int32"}, - {"Int31n", Func, 0, "func(n int32) int32"}, - {"Int63", Func, 0, "func() int64"}, - {"Int63n", Func, 0, "func(n int64) int64"}, - {"Intn", Func, 0, "func(n int) int"}, - {"New", Func, 0, "func(src Source) *Rand"}, - {"NewSource", Func, 0, "func(seed int64) Source"}, - {"NewZipf", Func, 0, "func(r *Rand, s float64, v float64, imax uint64) *Zipf"}, - {"NormFloat64", Func, 0, "func() float64"}, - {"Perm", Func, 0, "func(n int) []int"}, - {"Rand", Type, 0, ""}, - {"Read", Func, 6, "func(p []byte) (n int, err error)"}, - {"Seed", Func, 0, "func(seed int64)"}, - {"Shuffle", Func, 10, "func(n int, swap func(i int, j int))"}, - {"Source", Type, 0, ""}, - {"Source64", Type, 8, ""}, - {"Uint32", Func, 0, "func() uint32"}, - {"Uint64", Func, 8, "func() uint64"}, - {"Zipf", Type, 0, ""}, - }, - "math/rand/v2": { - {"(*ChaCha8).AppendBinary", Method, 24, ""}, - {"(*ChaCha8).MarshalBinary", Method, 22, ""}, - {"(*ChaCha8).Read", Method, 23, ""}, - {"(*ChaCha8).Seed", Method, 22, ""}, - {"(*ChaCha8).Uint64", Method, 22, ""}, - {"(*ChaCha8).UnmarshalBinary", Method, 22, ""}, - {"(*PCG).AppendBinary", Method, 24, ""}, - {"(*PCG).MarshalBinary", Method, 22, ""}, - {"(*PCG).Seed", Method, 22, ""}, - {"(*PCG).Uint64", Method, 22, ""}, - {"(*PCG).UnmarshalBinary", Method, 22, ""}, - {"(*Rand).ExpFloat64", Method, 22, ""}, - {"(*Rand).Float32", Method, 22, ""}, - {"(*Rand).Float64", Method, 22, ""}, - {"(*Rand).Int", Method, 22, ""}, - {"(*Rand).Int32", Method, 22, ""}, - {"(*Rand).Int32N", Method, 22, ""}, - {"(*Rand).Int64", Method, 22, ""}, - {"(*Rand).Int64N", Method, 22, ""}, - {"(*Rand).IntN", Method, 22, ""}, - {"(*Rand).NormFloat64", Method, 22, ""}, - {"(*Rand).Perm", Method, 22, ""}, - {"(*Rand).Shuffle", Method, 22, ""}, - {"(*Rand).Uint", Method, 23, ""}, - {"(*Rand).Uint32", Method, 22, ""}, - {"(*Rand).Uint32N", Method, 22, ""}, - {"(*Rand).Uint64", Method, 22, ""}, - {"(*Rand).Uint64N", Method, 22, ""}, - {"(*Rand).UintN", Method, 22, ""}, - {"(*Zipf).Uint64", Method, 22, ""}, - {"(Source).Uint64", Method, 22, ""}, - {"ChaCha8", Type, 22, ""}, - {"ExpFloat64", Func, 22, "func() float64"}, - {"Float32", Func, 22, "func() float32"}, - {"Float64", Func, 22, "func() float64"}, - {"Int", Func, 22, "func() int"}, - {"Int32", Func, 22, "func() int32"}, - {"Int32N", Func, 22, "func(n int32) int32"}, - {"Int64", Func, 22, "func() int64"}, - {"Int64N", Func, 22, "func(n int64) int64"}, - {"IntN", Func, 22, "func(n int) int"}, - {"N", Func, 22, "func[Int intType](n Int) Int"}, - {"New", Func, 22, "func(src Source) *Rand"}, - {"NewChaCha8", Func, 22, "func(seed [32]byte) *ChaCha8"}, - {"NewPCG", Func, 22, "func(seed1 uint64, seed2 uint64) *PCG"}, - {"NewZipf", Func, 22, "func(r *Rand, s float64, v float64, imax uint64) *Zipf"}, - {"NormFloat64", Func, 22, "func() float64"}, - {"PCG", Type, 22, ""}, - {"Perm", Func, 22, "func(n int) []int"}, - {"Rand", Type, 22, ""}, - {"Shuffle", Func, 22, "func(n int, swap func(i int, j int))"}, - {"Source", Type, 22, ""}, - {"Uint", Func, 23, "func() uint"}, - {"Uint32", Func, 22, "func() uint32"}, - {"Uint32N", Func, 22, "func(n uint32) uint32"}, - {"Uint64", Func, 22, "func() uint64"}, - {"Uint64N", Func, 22, "func(n uint64) uint64"}, - {"UintN", Func, 22, "func(n uint) uint"}, - {"Zipf", Type, 22, ""}, - }, - "mime": { - {"(*WordDecoder).Decode", Method, 5, ""}, - {"(*WordDecoder).DecodeHeader", Method, 5, ""}, - {"(WordEncoder).Encode", Method, 5, ""}, - {"AddExtensionType", Func, 0, "func(ext string, typ string) error"}, - {"BEncoding", Const, 5, ""}, - {"ErrInvalidMediaParameter", Var, 9, ""}, - {"ExtensionsByType", Func, 5, "func(typ string) ([]string, error)"}, - {"FormatMediaType", Func, 0, "func(t string, param map[string]string) string"}, - {"ParseMediaType", Func, 0, "func(v string) (mediatype string, params map[string]string, err error)"}, - {"QEncoding", Const, 5, ""}, - {"TypeByExtension", Func, 0, "func(ext string) string"}, - {"WordDecoder", Type, 5, ""}, - {"WordDecoder.CharsetReader", Field, 5, ""}, - {"WordEncoder", Type, 5, ""}, - }, - "mime/multipart": { - {"(*FileHeader).Open", Method, 0, ""}, - {"(*Form).RemoveAll", Method, 0, ""}, - {"(*Part).Close", Method, 0, ""}, - {"(*Part).FileName", Method, 0, ""}, - {"(*Part).FormName", Method, 0, ""}, - {"(*Part).Read", Method, 0, ""}, - {"(*Reader).NextPart", Method, 0, ""}, - {"(*Reader).NextRawPart", Method, 14, ""}, - {"(*Reader).ReadForm", Method, 0, ""}, - {"(*Writer).Boundary", Method, 0, ""}, - {"(*Writer).Close", Method, 0, ""}, - {"(*Writer).CreateFormField", Method, 0, ""}, - {"(*Writer).CreateFormFile", Method, 0, ""}, - {"(*Writer).CreatePart", Method, 0, ""}, - {"(*Writer).FormDataContentType", Method, 0, ""}, - {"(*Writer).SetBoundary", Method, 1, ""}, - {"(*Writer).WriteField", Method, 0, ""}, - {"(File).Close", Method, 0, ""}, - {"(File).Read", Method, 0, ""}, - {"(File).ReadAt", Method, 0, ""}, - {"(File).Seek", Method, 0, ""}, - {"ErrMessageTooLarge", Var, 9, ""}, - {"File", Type, 0, ""}, - {"FileContentDisposition", Func, 25, "func(fieldname string, filename string) string"}, - {"FileHeader", Type, 0, ""}, - {"FileHeader.Filename", Field, 0, ""}, - {"FileHeader.Header", Field, 0, ""}, - {"FileHeader.Size", Field, 9, ""}, - {"Form", Type, 0, ""}, - {"Form.File", Field, 0, ""}, - {"Form.Value", Field, 0, ""}, - {"NewReader", Func, 0, "func(r io.Reader, boundary string) *Reader"}, - {"NewWriter", Func, 0, "func(w io.Writer) *Writer"}, - {"Part", Type, 0, ""}, - {"Part.Header", Field, 0, ""}, - {"Reader", Type, 0, ""}, - {"Writer", Type, 0, ""}, - }, - "mime/quotedprintable": { - {"(*Reader).Read", Method, 5, ""}, - {"(*Writer).Close", Method, 5, ""}, - {"(*Writer).Write", Method, 5, ""}, - {"NewReader", Func, 5, "func(r io.Reader) *Reader"}, - {"NewWriter", Func, 5, "func(w io.Writer) *Writer"}, - {"Reader", Type, 5, ""}, - {"Writer", Type, 5, ""}, - {"Writer.Binary", Field, 5, ""}, - }, - "net": { - {"(*AddrError).Error", Method, 0, ""}, - {"(*AddrError).Temporary", Method, 0, ""}, - {"(*AddrError).Timeout", Method, 0, ""}, - {"(*Buffers).Read", Method, 8, ""}, - {"(*Buffers).WriteTo", Method, 8, ""}, - {"(*DNSConfigError).Error", Method, 0, ""}, - {"(*DNSConfigError).Temporary", Method, 0, ""}, - {"(*DNSConfigError).Timeout", Method, 0, ""}, - {"(*DNSConfigError).Unwrap", Method, 13, ""}, - {"(*DNSError).Error", Method, 0, ""}, - {"(*DNSError).Temporary", Method, 0, ""}, - {"(*DNSError).Timeout", Method, 0, ""}, - {"(*DNSError).Unwrap", Method, 23, ""}, - {"(*Dialer).Dial", Method, 1, ""}, - {"(*Dialer).DialContext", Method, 7, ""}, - {"(*Dialer).DialIP", Method, 26, ""}, - {"(*Dialer).DialTCP", Method, 26, ""}, - {"(*Dialer).DialUDP", Method, 26, ""}, - {"(*Dialer).DialUnix", Method, 26, ""}, - {"(*Dialer).MultipathTCP", Method, 21, ""}, - {"(*Dialer).SetMultipathTCP", Method, 21, ""}, - {"(*IP).UnmarshalText", Method, 2, ""}, - {"(*IPAddr).Network", Method, 0, ""}, - {"(*IPAddr).String", Method, 0, ""}, - {"(*IPConn).Close", Method, 0, ""}, - {"(*IPConn).File", Method, 0, ""}, - {"(*IPConn).LocalAddr", Method, 0, ""}, - {"(*IPConn).Read", Method, 0, ""}, - {"(*IPConn).ReadFrom", Method, 0, ""}, - {"(*IPConn).ReadFromIP", Method, 0, ""}, - {"(*IPConn).ReadMsgIP", Method, 1, ""}, - {"(*IPConn).RemoteAddr", Method, 0, ""}, - {"(*IPConn).SetDeadline", Method, 0, ""}, - {"(*IPConn).SetReadBuffer", Method, 0, ""}, - {"(*IPConn).SetReadDeadline", Method, 0, ""}, - {"(*IPConn).SetWriteBuffer", Method, 0, ""}, - {"(*IPConn).SetWriteDeadline", Method, 0, ""}, - {"(*IPConn).SyscallConn", Method, 9, ""}, - {"(*IPConn).Write", Method, 0, ""}, - {"(*IPConn).WriteMsgIP", Method, 1, ""}, - {"(*IPConn).WriteTo", Method, 0, ""}, - {"(*IPConn).WriteToIP", Method, 0, ""}, - {"(*IPNet).Contains", Method, 0, ""}, - {"(*IPNet).Network", Method, 0, ""}, - {"(*IPNet).String", Method, 0, ""}, - {"(*Interface).Addrs", Method, 0, ""}, - {"(*Interface).MulticastAddrs", Method, 0, ""}, - {"(*ListenConfig).Listen", Method, 11, ""}, - {"(*ListenConfig).ListenPacket", Method, 11, ""}, - {"(*ListenConfig).MultipathTCP", Method, 21, ""}, - {"(*ListenConfig).SetMultipathTCP", Method, 21, ""}, - {"(*OpError).Error", Method, 0, ""}, - {"(*OpError).Temporary", Method, 0, ""}, - {"(*OpError).Timeout", Method, 0, ""}, - {"(*OpError).Unwrap", Method, 13, ""}, - {"(*ParseError).Error", Method, 0, ""}, - {"(*ParseError).Temporary", Method, 17, ""}, - {"(*ParseError).Timeout", Method, 17, ""}, - {"(*Resolver).LookupAddr", Method, 8, ""}, - {"(*Resolver).LookupCNAME", Method, 8, ""}, - {"(*Resolver).LookupHost", Method, 8, ""}, - {"(*Resolver).LookupIP", Method, 15, ""}, - {"(*Resolver).LookupIPAddr", Method, 8, ""}, - {"(*Resolver).LookupMX", Method, 8, ""}, - {"(*Resolver).LookupNS", Method, 8, ""}, - {"(*Resolver).LookupNetIP", Method, 18, ""}, - {"(*Resolver).LookupPort", Method, 8, ""}, - {"(*Resolver).LookupSRV", Method, 8, ""}, - {"(*Resolver).LookupTXT", Method, 8, ""}, - {"(*TCPAddr).AddrPort", Method, 18, ""}, - {"(*TCPAddr).Network", Method, 0, ""}, - {"(*TCPAddr).String", Method, 0, ""}, - {"(*TCPConn).Close", Method, 0, ""}, - {"(*TCPConn).CloseRead", Method, 0, ""}, - {"(*TCPConn).CloseWrite", Method, 0, ""}, - {"(*TCPConn).File", Method, 0, ""}, - {"(*TCPConn).LocalAddr", Method, 0, ""}, - {"(*TCPConn).MultipathTCP", Method, 21, ""}, - {"(*TCPConn).Read", Method, 0, ""}, - {"(*TCPConn).ReadFrom", Method, 0, ""}, - {"(*TCPConn).RemoteAddr", Method, 0, ""}, - {"(*TCPConn).SetDeadline", Method, 0, ""}, - {"(*TCPConn).SetKeepAlive", Method, 0, ""}, - {"(*TCPConn).SetKeepAliveConfig", Method, 23, ""}, - {"(*TCPConn).SetKeepAlivePeriod", Method, 2, ""}, - {"(*TCPConn).SetLinger", Method, 0, ""}, - {"(*TCPConn).SetNoDelay", Method, 0, ""}, - {"(*TCPConn).SetReadBuffer", Method, 0, ""}, - {"(*TCPConn).SetReadDeadline", Method, 0, ""}, - {"(*TCPConn).SetWriteBuffer", Method, 0, ""}, - {"(*TCPConn).SetWriteDeadline", Method, 0, ""}, - {"(*TCPConn).SyscallConn", Method, 9, ""}, - {"(*TCPConn).Write", Method, 0, ""}, - {"(*TCPConn).WriteTo", Method, 22, ""}, - {"(*TCPListener).Accept", Method, 0, ""}, - {"(*TCPListener).AcceptTCP", Method, 0, ""}, - {"(*TCPListener).Addr", Method, 0, ""}, - {"(*TCPListener).Close", Method, 0, ""}, - {"(*TCPListener).File", Method, 0, ""}, - {"(*TCPListener).SetDeadline", Method, 0, ""}, - {"(*TCPListener).SyscallConn", Method, 10, ""}, - {"(*UDPAddr).AddrPort", Method, 18, ""}, - {"(*UDPAddr).Network", Method, 0, ""}, - {"(*UDPAddr).String", Method, 0, ""}, - {"(*UDPConn).Close", Method, 0, ""}, - {"(*UDPConn).File", Method, 0, ""}, - {"(*UDPConn).LocalAddr", Method, 0, ""}, - {"(*UDPConn).Read", Method, 0, ""}, - {"(*UDPConn).ReadFrom", Method, 0, ""}, - {"(*UDPConn).ReadFromUDP", Method, 0, ""}, - {"(*UDPConn).ReadFromUDPAddrPort", Method, 18, ""}, - {"(*UDPConn).ReadMsgUDP", Method, 1, ""}, - {"(*UDPConn).ReadMsgUDPAddrPort", Method, 18, ""}, - {"(*UDPConn).RemoteAddr", Method, 0, ""}, - {"(*UDPConn).SetDeadline", Method, 0, ""}, - {"(*UDPConn).SetReadBuffer", Method, 0, ""}, - {"(*UDPConn).SetReadDeadline", Method, 0, ""}, - {"(*UDPConn).SetWriteBuffer", Method, 0, ""}, - {"(*UDPConn).SetWriteDeadline", Method, 0, ""}, - {"(*UDPConn).SyscallConn", Method, 9, ""}, - {"(*UDPConn).Write", Method, 0, ""}, - {"(*UDPConn).WriteMsgUDP", Method, 1, ""}, - {"(*UDPConn).WriteMsgUDPAddrPort", Method, 18, ""}, - {"(*UDPConn).WriteTo", Method, 0, ""}, - {"(*UDPConn).WriteToUDP", Method, 0, ""}, - {"(*UDPConn).WriteToUDPAddrPort", Method, 18, ""}, - {"(*UnixAddr).Network", Method, 0, ""}, - {"(*UnixAddr).String", Method, 0, ""}, - {"(*UnixConn).Close", Method, 0, ""}, - {"(*UnixConn).CloseRead", Method, 1, ""}, - {"(*UnixConn).CloseWrite", Method, 1, ""}, - {"(*UnixConn).File", Method, 0, ""}, - {"(*UnixConn).LocalAddr", Method, 0, ""}, - {"(*UnixConn).Read", Method, 0, ""}, - {"(*UnixConn).ReadFrom", Method, 0, ""}, - {"(*UnixConn).ReadFromUnix", Method, 0, ""}, - {"(*UnixConn).ReadMsgUnix", Method, 0, ""}, - {"(*UnixConn).RemoteAddr", Method, 0, ""}, - {"(*UnixConn).SetDeadline", Method, 0, ""}, - {"(*UnixConn).SetReadBuffer", Method, 0, ""}, - {"(*UnixConn).SetReadDeadline", Method, 0, ""}, - {"(*UnixConn).SetWriteBuffer", Method, 0, ""}, - {"(*UnixConn).SetWriteDeadline", Method, 0, ""}, - {"(*UnixConn).SyscallConn", Method, 9, ""}, - {"(*UnixConn).Write", Method, 0, ""}, - {"(*UnixConn).WriteMsgUnix", Method, 0, ""}, - {"(*UnixConn).WriteTo", Method, 0, ""}, - {"(*UnixConn).WriteToUnix", Method, 0, ""}, - {"(*UnixListener).Accept", Method, 0, ""}, - {"(*UnixListener).AcceptUnix", Method, 0, ""}, - {"(*UnixListener).Addr", Method, 0, ""}, - {"(*UnixListener).Close", Method, 0, ""}, - {"(*UnixListener).File", Method, 0, ""}, - {"(*UnixListener).SetDeadline", Method, 0, ""}, - {"(*UnixListener).SetUnlinkOnClose", Method, 8, ""}, - {"(*UnixListener).SyscallConn", Method, 10, ""}, - {"(Addr).Network", Method, 0, ""}, - {"(Addr).String", Method, 0, ""}, - {"(Conn).Close", Method, 0, ""}, - {"(Conn).LocalAddr", Method, 0, ""}, - {"(Conn).Read", Method, 0, ""}, - {"(Conn).RemoteAddr", Method, 0, ""}, - {"(Conn).SetDeadline", Method, 0, ""}, - {"(Conn).SetReadDeadline", Method, 0, ""}, - {"(Conn).SetWriteDeadline", Method, 0, ""}, - {"(Conn).Write", Method, 0, ""}, - {"(Error).Error", Method, 0, ""}, - {"(Error).Temporary", Method, 0, ""}, - {"(Error).Timeout", Method, 0, ""}, - {"(Flags).String", Method, 0, ""}, - {"(HardwareAddr).String", Method, 0, ""}, - {"(IP).AppendText", Method, 24, ""}, - {"(IP).DefaultMask", Method, 0, ""}, - {"(IP).Equal", Method, 0, ""}, - {"(IP).IsGlobalUnicast", Method, 0, ""}, - {"(IP).IsInterfaceLocalMulticast", Method, 0, ""}, - {"(IP).IsLinkLocalMulticast", Method, 0, ""}, - {"(IP).IsLinkLocalUnicast", Method, 0, ""}, - {"(IP).IsLoopback", Method, 0, ""}, - {"(IP).IsMulticast", Method, 0, ""}, - {"(IP).IsPrivate", Method, 17, ""}, - {"(IP).IsUnspecified", Method, 0, ""}, - {"(IP).MarshalText", Method, 2, ""}, - {"(IP).Mask", Method, 0, ""}, - {"(IP).String", Method, 0, ""}, - {"(IP).To16", Method, 0, ""}, - {"(IP).To4", Method, 0, ""}, - {"(IPMask).Size", Method, 0, ""}, - {"(IPMask).String", Method, 0, ""}, - {"(InvalidAddrError).Error", Method, 0, ""}, - {"(InvalidAddrError).Temporary", Method, 0, ""}, - {"(InvalidAddrError).Timeout", Method, 0, ""}, - {"(Listener).Accept", Method, 0, ""}, - {"(Listener).Addr", Method, 0, ""}, - {"(Listener).Close", Method, 0, ""}, - {"(PacketConn).Close", Method, 0, ""}, - {"(PacketConn).LocalAddr", Method, 0, ""}, - {"(PacketConn).ReadFrom", Method, 0, ""}, - {"(PacketConn).SetDeadline", Method, 0, ""}, - {"(PacketConn).SetReadDeadline", Method, 0, ""}, - {"(PacketConn).SetWriteDeadline", Method, 0, ""}, - {"(PacketConn).WriteTo", Method, 0, ""}, - {"(UnknownNetworkError).Error", Method, 0, ""}, - {"(UnknownNetworkError).Temporary", Method, 0, ""}, - {"(UnknownNetworkError).Timeout", Method, 0, ""}, - {"Addr", Type, 0, ""}, - {"AddrError", Type, 0, ""}, - {"AddrError.Addr", Field, 0, ""}, - {"AddrError.Err", Field, 0, ""}, - {"Buffers", Type, 8, ""}, - {"CIDRMask", Func, 0, "func(ones int, bits int) IPMask"}, - {"Conn", Type, 0, ""}, - {"DNSConfigError", Type, 0, ""}, - {"DNSConfigError.Err", Field, 0, ""}, - {"DNSError", Type, 0, ""}, - {"DNSError.Err", Field, 0, ""}, - {"DNSError.IsNotFound", Field, 13, ""}, - {"DNSError.IsTemporary", Field, 6, ""}, - {"DNSError.IsTimeout", Field, 0, ""}, - {"DNSError.Name", Field, 0, ""}, - {"DNSError.Server", Field, 0, ""}, - {"DNSError.UnwrapErr", Field, 23, ""}, - {"DefaultResolver", Var, 8, ""}, - {"Dial", Func, 0, "func(network string, address string) (Conn, error)"}, - {"DialIP", Func, 0, "func(network string, laddr *IPAddr, raddr *IPAddr) (*IPConn, error)"}, - {"DialTCP", Func, 0, "func(network string, laddr *TCPAddr, raddr *TCPAddr) (*TCPConn, error)"}, - {"DialTimeout", Func, 0, "func(network string, address string, timeout time.Duration) (Conn, error)"}, - {"DialUDP", Func, 0, "func(network string, laddr *UDPAddr, raddr *UDPAddr) (*UDPConn, error)"}, - {"DialUnix", Func, 0, "func(network string, laddr *UnixAddr, raddr *UnixAddr) (*UnixConn, error)"}, - {"Dialer", Type, 1, ""}, - {"Dialer.Cancel", Field, 6, ""}, - {"Dialer.Control", Field, 11, ""}, - {"Dialer.ControlContext", Field, 20, ""}, - {"Dialer.Deadline", Field, 1, ""}, - {"Dialer.DualStack", Field, 2, ""}, - {"Dialer.FallbackDelay", Field, 5, ""}, - {"Dialer.KeepAlive", Field, 3, ""}, - {"Dialer.KeepAliveConfig", Field, 23, ""}, - {"Dialer.LocalAddr", Field, 1, ""}, - {"Dialer.Resolver", Field, 8, ""}, - {"Dialer.Timeout", Field, 1, ""}, - {"ErrClosed", Var, 16, ""}, - {"ErrWriteToConnected", Var, 0, ""}, - {"Error", Type, 0, ""}, - {"FileConn", Func, 0, "func(f *os.File) (c Conn, err error)"}, - {"FileListener", Func, 0, "func(f *os.File) (ln Listener, err error)"}, - {"FilePacketConn", Func, 0, "func(f *os.File) (c PacketConn, err error)"}, - {"FlagBroadcast", Const, 0, ""}, - {"FlagLoopback", Const, 0, ""}, - {"FlagMulticast", Const, 0, ""}, - {"FlagPointToPoint", Const, 0, ""}, - {"FlagRunning", Const, 20, ""}, - {"FlagUp", Const, 0, ""}, - {"Flags", Type, 0, ""}, - {"HardwareAddr", Type, 0, ""}, - {"IP", Type, 0, ""}, - {"IPAddr", Type, 0, ""}, - {"IPAddr.IP", Field, 0, ""}, - {"IPAddr.Zone", Field, 1, ""}, - {"IPConn", Type, 0, ""}, - {"IPMask", Type, 0, ""}, - {"IPNet", Type, 0, ""}, - {"IPNet.IP", Field, 0, ""}, - {"IPNet.Mask", Field, 0, ""}, - {"IPv4", Func, 0, "func(a byte, b byte, c byte, d byte) IP"}, - {"IPv4Mask", Func, 0, "func(a byte, b byte, c byte, d byte) IPMask"}, - {"IPv4allrouter", Var, 0, ""}, - {"IPv4allsys", Var, 0, ""}, - {"IPv4bcast", Var, 0, ""}, - {"IPv4len", Const, 0, ""}, - {"IPv4zero", Var, 0, ""}, - {"IPv6interfacelocalallnodes", Var, 0, ""}, - {"IPv6len", Const, 0, ""}, - {"IPv6linklocalallnodes", Var, 0, ""}, - {"IPv6linklocalallrouters", Var, 0, ""}, - {"IPv6loopback", Var, 0, ""}, - {"IPv6unspecified", Var, 0, ""}, - {"IPv6zero", Var, 0, ""}, - {"Interface", Type, 0, ""}, - {"Interface.Flags", Field, 0, ""}, - {"Interface.HardwareAddr", Field, 0, ""}, - {"Interface.Index", Field, 0, ""}, - {"Interface.MTU", Field, 0, ""}, - {"Interface.Name", Field, 0, ""}, - {"InterfaceAddrs", Func, 0, "func() ([]Addr, error)"}, - {"InterfaceByIndex", Func, 0, "func(index int) (*Interface, error)"}, - {"InterfaceByName", Func, 0, "func(name string) (*Interface, error)"}, - {"Interfaces", Func, 0, "func() ([]Interface, error)"}, - {"InvalidAddrError", Type, 0, ""}, - {"JoinHostPort", Func, 0, "func(host string, port string) string"}, - {"KeepAliveConfig", Type, 23, ""}, - {"KeepAliveConfig.Count", Field, 23, ""}, - {"KeepAliveConfig.Enable", Field, 23, ""}, - {"KeepAliveConfig.Idle", Field, 23, ""}, - {"KeepAliveConfig.Interval", Field, 23, ""}, - {"Listen", Func, 0, "func(network string, address string) (Listener, error)"}, - {"ListenConfig", Type, 11, ""}, - {"ListenConfig.Control", Field, 11, ""}, - {"ListenConfig.KeepAlive", Field, 13, ""}, - {"ListenConfig.KeepAliveConfig", Field, 23, ""}, - {"ListenIP", Func, 0, "func(network string, laddr *IPAddr) (*IPConn, error)"}, - {"ListenMulticastUDP", Func, 0, "func(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error)"}, - {"ListenPacket", Func, 0, "func(network string, address string) (PacketConn, error)"}, - {"ListenTCP", Func, 0, "func(network string, laddr *TCPAddr) (*TCPListener, error)"}, - {"ListenUDP", Func, 0, "func(network string, laddr *UDPAddr) (*UDPConn, error)"}, - {"ListenUnix", Func, 0, "func(network string, laddr *UnixAddr) (*UnixListener, error)"}, - {"ListenUnixgram", Func, 0, "func(network string, laddr *UnixAddr) (*UnixConn, error)"}, - {"Listener", Type, 0, ""}, - {"LookupAddr", Func, 0, "func(addr string) (names []string, err error)"}, - {"LookupCNAME", Func, 0, "func(host string) (cname string, err error)"}, - {"LookupHost", Func, 0, "func(host string) (addrs []string, err error)"}, - {"LookupIP", Func, 0, "func(host string) ([]IP, error)"}, - {"LookupMX", Func, 0, "func(name string) ([]*MX, error)"}, - {"LookupNS", Func, 1, "func(name string) ([]*NS, error)"}, - {"LookupPort", Func, 0, "func(network string, service string) (port int, err error)"}, - {"LookupSRV", Func, 0, "func(service string, proto string, name string) (cname string, addrs []*SRV, err error)"}, - {"LookupTXT", Func, 0, "func(name string) ([]string, error)"}, - {"MX", Type, 0, ""}, - {"MX.Host", Field, 0, ""}, - {"MX.Pref", Field, 0, ""}, - {"NS", Type, 1, ""}, - {"NS.Host", Field, 1, ""}, - {"OpError", Type, 0, ""}, - {"OpError.Addr", Field, 0, ""}, - {"OpError.Err", Field, 0, ""}, - {"OpError.Net", Field, 0, ""}, - {"OpError.Op", Field, 0, ""}, - {"OpError.Source", Field, 5, ""}, - {"PacketConn", Type, 0, ""}, - {"ParseCIDR", Func, 0, "func(s string) (IP, *IPNet, error)"}, - {"ParseError", Type, 0, ""}, - {"ParseError.Text", Field, 0, ""}, - {"ParseError.Type", Field, 0, ""}, - {"ParseIP", Func, 0, "func(s string) IP"}, - {"ParseMAC", Func, 0, "func(s string) (hw HardwareAddr, err error)"}, - {"Pipe", Func, 0, "func() (Conn, Conn)"}, - {"ResolveIPAddr", Func, 0, "func(network string, address string) (*IPAddr, error)"}, - {"ResolveTCPAddr", Func, 0, "func(network string, address string) (*TCPAddr, error)"}, - {"ResolveUDPAddr", Func, 0, "func(network string, address string) (*UDPAddr, error)"}, - {"ResolveUnixAddr", Func, 0, "func(network string, address string) (*UnixAddr, error)"}, - {"Resolver", Type, 8, ""}, - {"Resolver.Dial", Field, 9, ""}, - {"Resolver.PreferGo", Field, 8, ""}, - {"Resolver.StrictErrors", Field, 9, ""}, - {"SRV", Type, 0, ""}, - {"SRV.Port", Field, 0, ""}, - {"SRV.Priority", Field, 0, ""}, - {"SRV.Target", Field, 0, ""}, - {"SRV.Weight", Field, 0, ""}, - {"SplitHostPort", Func, 0, "func(hostport string) (host string, port string, err error)"}, - {"TCPAddr", Type, 0, ""}, - {"TCPAddr.IP", Field, 0, ""}, - {"TCPAddr.Port", Field, 0, ""}, - {"TCPAddr.Zone", Field, 1, ""}, - {"TCPAddrFromAddrPort", Func, 18, "func(addr netip.AddrPort) *TCPAddr"}, - {"TCPConn", Type, 0, ""}, - {"TCPListener", Type, 0, ""}, - {"UDPAddr", Type, 0, ""}, - {"UDPAddr.IP", Field, 0, ""}, - {"UDPAddr.Port", Field, 0, ""}, - {"UDPAddr.Zone", Field, 1, ""}, - {"UDPAddrFromAddrPort", Func, 18, "func(addr netip.AddrPort) *UDPAddr"}, - {"UDPConn", Type, 0, ""}, - {"UnixAddr", Type, 0, ""}, - {"UnixAddr.Name", Field, 0, ""}, - {"UnixAddr.Net", Field, 0, ""}, - {"UnixConn", Type, 0, ""}, - {"UnixListener", Type, 0, ""}, - {"UnknownNetworkError", Type, 0, ""}, - }, - "net/http": { - {"(*Client).CloseIdleConnections", Method, 12, ""}, - {"(*Client).Do", Method, 0, ""}, - {"(*Client).Get", Method, 0, ""}, - {"(*Client).Head", Method, 0, ""}, - {"(*Client).Post", Method, 0, ""}, - {"(*Client).PostForm", Method, 0, ""}, - {"(*ClientConn).Available", Method, 26, ""}, - {"(*ClientConn).Close", Method, 26, ""}, - {"(*ClientConn).Err", Method, 26, ""}, - {"(*ClientConn).InFlight", Method, 26, ""}, - {"(*ClientConn).Release", Method, 26, ""}, - {"(*ClientConn).Reserve", Method, 26, ""}, - {"(*ClientConn).RoundTrip", Method, 26, ""}, - {"(*ClientConn).SetStateHook", Method, 26, ""}, - {"(*Cookie).String", Method, 0, ""}, - {"(*Cookie).Valid", Method, 18, ""}, - {"(*CrossOriginProtection).AddInsecureBypassPattern", Method, 25, ""}, - {"(*CrossOriginProtection).AddTrustedOrigin", Method, 25, ""}, - {"(*CrossOriginProtection).Check", Method, 25, ""}, - {"(*CrossOriginProtection).Handler", Method, 25, ""}, - {"(*CrossOriginProtection).SetDenyHandler", Method, 25, ""}, - {"(*MaxBytesError).Error", Method, 19, ""}, - {"(*ProtocolError).Error", Method, 0, ""}, - {"(*ProtocolError).Is", Method, 21, ""}, - {"(*Protocols).SetHTTP1", Method, 24, ""}, - {"(*Protocols).SetHTTP2", Method, 24, ""}, - {"(*Protocols).SetUnencryptedHTTP2", Method, 24, ""}, - {"(*Request).AddCookie", Method, 0, ""}, - {"(*Request).BasicAuth", Method, 4, ""}, - {"(*Request).Clone", Method, 13, ""}, - {"(*Request).Context", Method, 7, ""}, - {"(*Request).Cookie", Method, 0, ""}, - {"(*Request).Cookies", Method, 0, ""}, - {"(*Request).CookiesNamed", Method, 23, ""}, - {"(*Request).FormFile", Method, 0, ""}, - {"(*Request).FormValue", Method, 0, ""}, - {"(*Request).MultipartReader", Method, 0, ""}, - {"(*Request).ParseForm", Method, 0, ""}, - {"(*Request).ParseMultipartForm", Method, 0, ""}, - {"(*Request).PathValue", Method, 22, ""}, - {"(*Request).PostFormValue", Method, 1, ""}, - {"(*Request).ProtoAtLeast", Method, 0, ""}, - {"(*Request).Referer", Method, 0, ""}, - {"(*Request).SetBasicAuth", Method, 0, ""}, - {"(*Request).SetPathValue", Method, 22, ""}, - {"(*Request).UserAgent", Method, 0, ""}, - {"(*Request).WithContext", Method, 7, ""}, - {"(*Request).Write", Method, 0, ""}, - {"(*Request).WriteProxy", Method, 0, ""}, - {"(*Response).Cookies", Method, 0, ""}, - {"(*Response).Location", Method, 0, ""}, - {"(*Response).ProtoAtLeast", Method, 0, ""}, - {"(*Response).Write", Method, 0, ""}, - {"(*ResponseController).EnableFullDuplex", Method, 21, ""}, - {"(*ResponseController).Flush", Method, 20, ""}, - {"(*ResponseController).Hijack", Method, 20, ""}, - {"(*ResponseController).SetReadDeadline", Method, 20, ""}, - {"(*ResponseController).SetWriteDeadline", Method, 20, ""}, - {"(*ServeMux).Handle", Method, 0, ""}, - {"(*ServeMux).HandleFunc", Method, 0, ""}, - {"(*ServeMux).Handler", Method, 1, ""}, - {"(*ServeMux).ServeHTTP", Method, 0, ""}, - {"(*Server).Close", Method, 8, ""}, - {"(*Server).ListenAndServe", Method, 0, ""}, - {"(*Server).ListenAndServeTLS", Method, 0, ""}, - {"(*Server).RegisterOnShutdown", Method, 9, ""}, - {"(*Server).Serve", Method, 0, ""}, - {"(*Server).ServeTLS", Method, 9, ""}, - {"(*Server).SetKeepAlivesEnabled", Method, 3, ""}, - {"(*Server).Shutdown", Method, 8, ""}, - {"(*Transport).CancelRequest", Method, 1, ""}, - {"(*Transport).Clone", Method, 13, ""}, - {"(*Transport).CloseIdleConnections", Method, 0, ""}, - {"(*Transport).NewClientConn", Method, 26, ""}, - {"(*Transport).RegisterProtocol", Method, 0, ""}, - {"(*Transport).RoundTrip", Method, 0, ""}, - {"(CloseNotifier).CloseNotify", Method, 1, ""}, - {"(ConnState).String", Method, 3, ""}, - {"(CookieJar).Cookies", Method, 0, ""}, - {"(CookieJar).SetCookies", Method, 0, ""}, - {"(Dir).Open", Method, 0, ""}, - {"(File).Close", Method, 0, ""}, - {"(File).Read", Method, 0, ""}, - {"(File).Readdir", Method, 0, ""}, - {"(File).Seek", Method, 0, ""}, - {"(File).Stat", Method, 0, ""}, - {"(FileSystem).Open", Method, 0, ""}, - {"(Flusher).Flush", Method, 0, ""}, - {"(Handler).ServeHTTP", Method, 0, ""}, - {"(HandlerFunc).ServeHTTP", Method, 0, ""}, - {"(Header).Add", Method, 0, ""}, - {"(Header).Clone", Method, 13, ""}, - {"(Header).Del", Method, 0, ""}, - {"(Header).Get", Method, 0, ""}, - {"(Header).Set", Method, 0, ""}, - {"(Header).Values", Method, 14, ""}, - {"(Header).Write", Method, 0, ""}, - {"(Header).WriteSubset", Method, 0, ""}, - {"(Hijacker).Hijack", Method, 0, ""}, - {"(Protocols).HTTP1", Method, 24, ""}, - {"(Protocols).HTTP2", Method, 24, ""}, - {"(Protocols).String", Method, 24, ""}, - {"(Protocols).UnencryptedHTTP2", Method, 24, ""}, - {"(Pusher).Push", Method, 8, ""}, - {"(ResponseWriter).Header", Method, 0, ""}, - {"(ResponseWriter).Write", Method, 0, ""}, - {"(ResponseWriter).WriteHeader", Method, 0, ""}, - {"(RoundTripper).RoundTrip", Method, 0, ""}, - {"AllowQuerySemicolons", Func, 17, "func(h Handler) Handler"}, - {"CanonicalHeaderKey", Func, 0, "func(s string) string"}, - {"Client", Type, 0, ""}, - {"Client.CheckRedirect", Field, 0, ""}, - {"Client.Jar", Field, 0, ""}, - {"Client.Timeout", Field, 3, ""}, - {"Client.Transport", Field, 0, ""}, - {"ClientConn", Type, 26, ""}, - {"CloseNotifier", Type, 1, ""}, - {"ConnState", Type, 3, ""}, - {"Cookie", Type, 0, ""}, - {"Cookie.Domain", Field, 0, ""}, - {"Cookie.Expires", Field, 0, ""}, - {"Cookie.HttpOnly", Field, 0, ""}, - {"Cookie.MaxAge", Field, 0, ""}, - {"Cookie.Name", Field, 0, ""}, - {"Cookie.Partitioned", Field, 23, ""}, - {"Cookie.Path", Field, 0, ""}, - {"Cookie.Quoted", Field, 23, ""}, - {"Cookie.Raw", Field, 0, ""}, - {"Cookie.RawExpires", Field, 0, ""}, - {"Cookie.SameSite", Field, 11, ""}, - {"Cookie.Secure", Field, 0, ""}, - {"Cookie.Unparsed", Field, 0, ""}, - {"Cookie.Value", Field, 0, ""}, - {"CookieJar", Type, 0, ""}, - {"CrossOriginProtection", Type, 25, ""}, - {"DefaultClient", Var, 0, ""}, - {"DefaultMaxHeaderBytes", Const, 0, ""}, - {"DefaultMaxIdleConnsPerHost", Const, 0, ""}, - {"DefaultServeMux", Var, 0, ""}, - {"DefaultTransport", Var, 0, ""}, - {"DetectContentType", Func, 0, "func(data []byte) string"}, - {"Dir", Type, 0, ""}, - {"ErrAbortHandler", Var, 8, ""}, - {"ErrBodyNotAllowed", Var, 0, ""}, - {"ErrBodyReadAfterClose", Var, 0, ""}, - {"ErrContentLength", Var, 0, ""}, - {"ErrHandlerTimeout", Var, 0, ""}, - {"ErrHeaderTooLong", Var, 0, ""}, - {"ErrHijacked", Var, 0, ""}, - {"ErrLineTooLong", Var, 0, ""}, - {"ErrMissingBoundary", Var, 0, ""}, - {"ErrMissingContentLength", Var, 0, ""}, - {"ErrMissingFile", Var, 0, ""}, - {"ErrNoCookie", Var, 0, ""}, - {"ErrNoLocation", Var, 0, ""}, - {"ErrNotMultipart", Var, 0, ""}, - {"ErrNotSupported", Var, 0, ""}, - {"ErrSchemeMismatch", Var, 21, ""}, - {"ErrServerClosed", Var, 8, ""}, - {"ErrShortBody", Var, 0, ""}, - {"ErrSkipAltProtocol", Var, 6, ""}, - {"ErrUnexpectedTrailer", Var, 0, ""}, - {"ErrUseLastResponse", Var, 7, ""}, - {"ErrWriteAfterFlush", Var, 0, ""}, - {"Error", Func, 0, "func(w ResponseWriter, error string, code int)"}, - {"FS", Func, 16, "func(fsys fs.FS) FileSystem"}, - {"File", Type, 0, ""}, - {"FileServer", Func, 0, "func(root FileSystem) Handler"}, - {"FileServerFS", Func, 22, "func(root fs.FS) Handler"}, - {"FileSystem", Type, 0, ""}, - {"Flusher", Type, 0, ""}, - {"Get", Func, 0, "func(url string) (resp *Response, err error)"}, - {"HTTP2Config", Type, 24, ""}, - {"HTTP2Config.CountError", Field, 24, ""}, - {"HTTP2Config.MaxConcurrentStreams", Field, 24, ""}, - {"HTTP2Config.MaxDecoderHeaderTableSize", Field, 24, ""}, - {"HTTP2Config.MaxEncoderHeaderTableSize", Field, 24, ""}, - {"HTTP2Config.MaxReadFrameSize", Field, 24, ""}, - {"HTTP2Config.MaxReceiveBufferPerConnection", Field, 24, ""}, - {"HTTP2Config.MaxReceiveBufferPerStream", Field, 24, ""}, - {"HTTP2Config.PermitProhibitedCipherSuites", Field, 24, ""}, - {"HTTP2Config.PingTimeout", Field, 24, ""}, - {"HTTP2Config.SendPingTimeout", Field, 24, ""}, - {"HTTP2Config.StrictMaxConcurrentRequests", Field, 26, ""}, - {"HTTP2Config.WriteByteTimeout", Field, 24, ""}, - {"Handle", Func, 0, "func(pattern string, handler Handler)"}, - {"HandleFunc", Func, 0, "func(pattern string, handler func(ResponseWriter, *Request))"}, - {"Handler", Type, 0, ""}, - {"HandlerFunc", Type, 0, ""}, - {"Head", Func, 0, "func(url string) (resp *Response, err error)"}, - {"Header", Type, 0, ""}, - {"Hijacker", Type, 0, ""}, - {"ListenAndServe", Func, 0, "func(addr string, handler Handler) error"}, - {"ListenAndServeTLS", Func, 0, "func(addr string, certFile string, keyFile string, handler Handler) error"}, - {"LocalAddrContextKey", Var, 7, ""}, - {"MaxBytesError", Type, 19, ""}, - {"MaxBytesError.Limit", Field, 19, ""}, - {"MaxBytesHandler", Func, 18, "func(h Handler, n int64) Handler"}, - {"MaxBytesReader", Func, 0, "func(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser"}, - {"MethodConnect", Const, 6, ""}, - {"MethodDelete", Const, 6, ""}, - {"MethodGet", Const, 6, ""}, - {"MethodHead", Const, 6, ""}, - {"MethodOptions", Const, 6, ""}, - {"MethodPatch", Const, 6, ""}, - {"MethodPost", Const, 6, ""}, - {"MethodPut", Const, 6, ""}, - {"MethodTrace", Const, 6, ""}, - {"NewCrossOriginProtection", Func, 25, "func() *CrossOriginProtection"}, - {"NewFileTransport", Func, 0, "func(fs FileSystem) RoundTripper"}, - {"NewFileTransportFS", Func, 22, "func(fsys fs.FS) RoundTripper"}, - {"NewRequest", Func, 0, "func(method string, url string, body io.Reader) (*Request, error)"}, - {"NewRequestWithContext", Func, 13, "func(ctx context.Context, method string, url string, body io.Reader) (*Request, error)"}, - {"NewResponseController", Func, 20, "func(rw ResponseWriter) *ResponseController"}, - {"NewServeMux", Func, 0, "func() *ServeMux"}, - {"NoBody", Var, 8, ""}, - {"NotFound", Func, 0, "func(w ResponseWriter, r *Request)"}, - {"NotFoundHandler", Func, 0, "func() Handler"}, - {"ParseCookie", Func, 23, "func(line string) ([]*Cookie, error)"}, - {"ParseHTTPVersion", Func, 0, "func(vers string) (major int, minor int, ok bool)"}, - {"ParseSetCookie", Func, 23, "func(line string) (*Cookie, error)"}, - {"ParseTime", Func, 1, "func(text string) (t time.Time, err error)"}, - {"Post", Func, 0, "func(url string, contentType string, body io.Reader) (resp *Response, err error)"}, - {"PostForm", Func, 0, "func(url string, data url.Values) (resp *Response, err error)"}, - {"ProtocolError", Type, 0, ""}, - {"ProtocolError.ErrorString", Field, 0, ""}, - {"Protocols", Type, 24, ""}, - {"ProxyFromEnvironment", Func, 0, "func(req *Request) (*url.URL, error)"}, - {"ProxyURL", Func, 0, "func(fixedURL *url.URL) func(*Request) (*url.URL, error)"}, - {"PushOptions", Type, 8, ""}, - {"PushOptions.Header", Field, 8, ""}, - {"PushOptions.Method", Field, 8, ""}, - {"Pusher", Type, 8, ""}, - {"ReadRequest", Func, 0, "func(b *bufio.Reader) (*Request, error)"}, - {"ReadResponse", Func, 0, "func(r *bufio.Reader, req *Request) (*Response, error)"}, - {"Redirect", Func, 0, "func(w ResponseWriter, r *Request, url string, code int)"}, - {"RedirectHandler", Func, 0, "func(url string, code int) Handler"}, - {"Request", Type, 0, ""}, - {"Request.Body", Field, 0, ""}, - {"Request.Cancel", Field, 5, ""}, - {"Request.Close", Field, 0, ""}, - {"Request.ContentLength", Field, 0, ""}, - {"Request.Form", Field, 0, ""}, - {"Request.GetBody", Field, 8, ""}, - {"Request.Header", Field, 0, ""}, - {"Request.Host", Field, 0, ""}, - {"Request.Method", Field, 0, ""}, - {"Request.MultipartForm", Field, 0, ""}, - {"Request.Pattern", Field, 23, ""}, - {"Request.PostForm", Field, 1, ""}, - {"Request.Proto", Field, 0, ""}, - {"Request.ProtoMajor", Field, 0, ""}, - {"Request.ProtoMinor", Field, 0, ""}, - {"Request.RemoteAddr", Field, 0, ""}, - {"Request.RequestURI", Field, 0, ""}, - {"Request.Response", Field, 7, ""}, - {"Request.TLS", Field, 0, ""}, - {"Request.Trailer", Field, 0, ""}, - {"Request.TransferEncoding", Field, 0, ""}, - {"Request.URL", Field, 0, ""}, - {"Response", Type, 0, ""}, - {"Response.Body", Field, 0, ""}, - {"Response.Close", Field, 0, ""}, - {"Response.ContentLength", Field, 0, ""}, - {"Response.Header", Field, 0, ""}, - {"Response.Proto", Field, 0, ""}, - {"Response.ProtoMajor", Field, 0, ""}, - {"Response.ProtoMinor", Field, 0, ""}, - {"Response.Request", Field, 0, ""}, - {"Response.Status", Field, 0, ""}, - {"Response.StatusCode", Field, 0, ""}, - {"Response.TLS", Field, 3, ""}, - {"Response.Trailer", Field, 0, ""}, - {"Response.TransferEncoding", Field, 0, ""}, - {"Response.Uncompressed", Field, 7, ""}, - {"ResponseController", Type, 20, ""}, - {"ResponseWriter", Type, 0, ""}, - {"RoundTripper", Type, 0, ""}, - {"SameSite", Type, 11, ""}, - {"SameSiteDefaultMode", Const, 11, ""}, - {"SameSiteLaxMode", Const, 11, ""}, - {"SameSiteNoneMode", Const, 13, ""}, - {"SameSiteStrictMode", Const, 11, ""}, - {"Serve", Func, 0, "func(l net.Listener, handler Handler) error"}, - {"ServeContent", Func, 0, "func(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker)"}, - {"ServeFile", Func, 0, "func(w ResponseWriter, r *Request, name string)"}, - {"ServeFileFS", Func, 22, "func(w ResponseWriter, r *Request, fsys fs.FS, name string)"}, - {"ServeMux", Type, 0, ""}, - {"ServeTLS", Func, 9, "func(l net.Listener, handler Handler, certFile string, keyFile string) error"}, - {"Server", Type, 0, ""}, - {"Server.Addr", Field, 0, ""}, - {"Server.BaseContext", Field, 13, ""}, - {"Server.ConnContext", Field, 13, ""}, - {"Server.ConnState", Field, 3, ""}, - {"Server.DisableGeneralOptionsHandler", Field, 20, ""}, - {"Server.ErrorLog", Field, 3, ""}, - {"Server.HTTP2", Field, 24, ""}, - {"Server.Handler", Field, 0, ""}, - {"Server.IdleTimeout", Field, 8, ""}, - {"Server.MaxHeaderBytes", Field, 0, ""}, - {"Server.Protocols", Field, 24, ""}, - {"Server.ReadHeaderTimeout", Field, 8, ""}, - {"Server.ReadTimeout", Field, 0, ""}, - {"Server.TLSConfig", Field, 0, ""}, - {"Server.TLSNextProto", Field, 1, ""}, - {"Server.WriteTimeout", Field, 0, ""}, - {"ServerContextKey", Var, 7, ""}, - {"SetCookie", Func, 0, "func(w ResponseWriter, cookie *Cookie)"}, - {"StateActive", Const, 3, ""}, - {"StateClosed", Const, 3, ""}, - {"StateHijacked", Const, 3, ""}, - {"StateIdle", Const, 3, ""}, - {"StateNew", Const, 3, ""}, - {"StatusAccepted", Const, 0, ""}, - {"StatusAlreadyReported", Const, 7, ""}, - {"StatusBadGateway", Const, 0, ""}, - {"StatusBadRequest", Const, 0, ""}, - {"StatusConflict", Const, 0, ""}, - {"StatusContinue", Const, 0, ""}, - {"StatusCreated", Const, 0, ""}, - {"StatusEarlyHints", Const, 13, ""}, - {"StatusExpectationFailed", Const, 0, ""}, - {"StatusFailedDependency", Const, 7, ""}, - {"StatusForbidden", Const, 0, ""}, - {"StatusFound", Const, 0, ""}, - {"StatusGatewayTimeout", Const, 0, ""}, - {"StatusGone", Const, 0, ""}, - {"StatusHTTPVersionNotSupported", Const, 0, ""}, - {"StatusIMUsed", Const, 7, ""}, - {"StatusInsufficientStorage", Const, 7, ""}, - {"StatusInternalServerError", Const, 0, ""}, - {"StatusLengthRequired", Const, 0, ""}, - {"StatusLocked", Const, 7, ""}, - {"StatusLoopDetected", Const, 7, ""}, - {"StatusMethodNotAllowed", Const, 0, ""}, - {"StatusMisdirectedRequest", Const, 11, ""}, - {"StatusMovedPermanently", Const, 0, ""}, - {"StatusMultiStatus", Const, 7, ""}, - {"StatusMultipleChoices", Const, 0, ""}, - {"StatusNetworkAuthenticationRequired", Const, 6, ""}, - {"StatusNoContent", Const, 0, ""}, - {"StatusNonAuthoritativeInfo", Const, 0, ""}, - {"StatusNotAcceptable", Const, 0, ""}, - {"StatusNotExtended", Const, 7, ""}, - {"StatusNotFound", Const, 0, ""}, - {"StatusNotImplemented", Const, 0, ""}, - {"StatusNotModified", Const, 0, ""}, - {"StatusOK", Const, 0, ""}, - {"StatusPartialContent", Const, 0, ""}, - {"StatusPaymentRequired", Const, 0, ""}, - {"StatusPermanentRedirect", Const, 7, ""}, - {"StatusPreconditionFailed", Const, 0, ""}, - {"StatusPreconditionRequired", Const, 6, ""}, - {"StatusProcessing", Const, 7, ""}, - {"StatusProxyAuthRequired", Const, 0, ""}, - {"StatusRequestEntityTooLarge", Const, 0, ""}, - {"StatusRequestHeaderFieldsTooLarge", Const, 6, ""}, - {"StatusRequestTimeout", Const, 0, ""}, - {"StatusRequestURITooLong", Const, 0, ""}, - {"StatusRequestedRangeNotSatisfiable", Const, 0, ""}, - {"StatusResetContent", Const, 0, ""}, - {"StatusSeeOther", Const, 0, ""}, - {"StatusServiceUnavailable", Const, 0, ""}, - {"StatusSwitchingProtocols", Const, 0, ""}, - {"StatusTeapot", Const, 0, ""}, - {"StatusTemporaryRedirect", Const, 0, ""}, - {"StatusText", Func, 0, "func(code int) string"}, - {"StatusTooEarly", Const, 12, ""}, - {"StatusTooManyRequests", Const, 6, ""}, - {"StatusUnauthorized", Const, 0, ""}, - {"StatusUnavailableForLegalReasons", Const, 6, ""}, - {"StatusUnprocessableEntity", Const, 7, ""}, - {"StatusUnsupportedMediaType", Const, 0, ""}, - {"StatusUpgradeRequired", Const, 7, ""}, - {"StatusUseProxy", Const, 0, ""}, - {"StatusVariantAlsoNegotiates", Const, 7, ""}, - {"StripPrefix", Func, 0, "func(prefix string, h Handler) Handler"}, - {"TimeFormat", Const, 0, ""}, - {"TimeoutHandler", Func, 0, "func(h Handler, dt time.Duration, msg string) Handler"}, - {"TrailerPrefix", Const, 8, ""}, - {"Transport", Type, 0, ""}, - {"Transport.Dial", Field, 0, ""}, - {"Transport.DialContext", Field, 7, ""}, - {"Transport.DialTLS", Field, 4, ""}, - {"Transport.DialTLSContext", Field, 14, ""}, - {"Transport.DisableCompression", Field, 0, ""}, - {"Transport.DisableKeepAlives", Field, 0, ""}, - {"Transport.ExpectContinueTimeout", Field, 6, ""}, - {"Transport.ForceAttemptHTTP2", Field, 13, ""}, - {"Transport.GetProxyConnectHeader", Field, 16, ""}, - {"Transport.HTTP2", Field, 24, ""}, - {"Transport.IdleConnTimeout", Field, 7, ""}, - {"Transport.MaxConnsPerHost", Field, 11, ""}, - {"Transport.MaxIdleConns", Field, 7, ""}, - {"Transport.MaxIdleConnsPerHost", Field, 0, ""}, - {"Transport.MaxResponseHeaderBytes", Field, 7, ""}, - {"Transport.OnProxyConnectResponse", Field, 20, ""}, - {"Transport.Protocols", Field, 24, ""}, - {"Transport.Proxy", Field, 0, ""}, - {"Transport.ProxyConnectHeader", Field, 8, ""}, - {"Transport.ReadBufferSize", Field, 13, ""}, - {"Transport.ResponseHeaderTimeout", Field, 1, ""}, - {"Transport.TLSClientConfig", Field, 0, ""}, - {"Transport.TLSHandshakeTimeout", Field, 3, ""}, - {"Transport.TLSNextProto", Field, 6, ""}, - {"Transport.WriteBufferSize", Field, 13, ""}, - }, - "net/http/cgi": { - {"(*Handler).ServeHTTP", Method, 0, ""}, - {"Handler", Type, 0, ""}, - {"Handler.Args", Field, 0, ""}, - {"Handler.Dir", Field, 0, ""}, - {"Handler.Env", Field, 0, ""}, - {"Handler.InheritEnv", Field, 0, ""}, - {"Handler.Logger", Field, 0, ""}, - {"Handler.Path", Field, 0, ""}, - {"Handler.PathLocationHandler", Field, 0, ""}, - {"Handler.Root", Field, 0, ""}, - {"Handler.Stderr", Field, 7, ""}, - {"Request", Func, 0, "func() (*http.Request, error)"}, - {"RequestFromMap", Func, 0, "func(params map[string]string) (*http.Request, error)"}, - {"Serve", Func, 0, "func(handler http.Handler) error"}, - }, - "net/http/cookiejar": { - {"(*Jar).Cookies", Method, 1, ""}, - {"(*Jar).SetCookies", Method, 1, ""}, - {"(PublicSuffixList).PublicSuffix", Method, 1, ""}, - {"(PublicSuffixList).String", Method, 1, ""}, - {"Jar", Type, 1, ""}, - {"New", Func, 1, "func(o *Options) (*Jar, error)"}, - {"Options", Type, 1, ""}, - {"Options.PublicSuffixList", Field, 1, ""}, - {"PublicSuffixList", Type, 1, ""}, - }, - "net/http/fcgi": { - {"ErrConnClosed", Var, 5, ""}, - {"ErrRequestAborted", Var, 5, ""}, - {"ProcessEnv", Func, 9, "func(r *http.Request) map[string]string"}, - {"Serve", Func, 0, "func(l net.Listener, handler http.Handler) error"}, - }, - "net/http/httptest": { - {"(*ResponseRecorder).Flush", Method, 0, ""}, - {"(*ResponseRecorder).Header", Method, 0, ""}, - {"(*ResponseRecorder).Result", Method, 7, ""}, - {"(*ResponseRecorder).Write", Method, 0, ""}, - {"(*ResponseRecorder).WriteHeader", Method, 0, ""}, - {"(*ResponseRecorder).WriteString", Method, 6, ""}, - {"(*Server).Certificate", Method, 9, ""}, - {"(*Server).Client", Method, 9, ""}, - {"(*Server).Close", Method, 0, ""}, - {"(*Server).CloseClientConnections", Method, 0, ""}, - {"(*Server).Start", Method, 0, ""}, - {"(*Server).StartTLS", Method, 0, ""}, - {"DefaultRemoteAddr", Const, 0, ""}, - {"NewRecorder", Func, 0, "func() *ResponseRecorder"}, - {"NewRequest", Func, 7, "func(method string, target string, body io.Reader) *http.Request"}, - {"NewRequestWithContext", Func, 23, "func(ctx context.Context, method string, target string, body io.Reader) *http.Request"}, - {"NewServer", Func, 0, "func(handler http.Handler) *Server"}, - {"NewTLSServer", Func, 0, "func(handler http.Handler) *Server"}, - {"NewUnstartedServer", Func, 0, "func(handler http.Handler) *Server"}, - {"ResponseRecorder", Type, 0, ""}, - {"ResponseRecorder.Body", Field, 0, ""}, - {"ResponseRecorder.Code", Field, 0, ""}, - {"ResponseRecorder.Flushed", Field, 0, ""}, - {"ResponseRecorder.HeaderMap", Field, 0, ""}, - {"Server", Type, 0, ""}, - {"Server.Config", Field, 0, ""}, - {"Server.EnableHTTP2", Field, 14, ""}, - {"Server.Listener", Field, 0, ""}, - {"Server.TLS", Field, 0, ""}, - {"Server.URL", Field, 0, ""}, - }, - "net/http/httptrace": { - {"ClientTrace", Type, 7, ""}, - {"ClientTrace.ConnectDone", Field, 7, ""}, - {"ClientTrace.ConnectStart", Field, 7, ""}, - {"ClientTrace.DNSDone", Field, 7, ""}, - {"ClientTrace.DNSStart", Field, 7, ""}, - {"ClientTrace.GetConn", Field, 7, ""}, - {"ClientTrace.Got100Continue", Field, 7, ""}, - {"ClientTrace.Got1xxResponse", Field, 11, ""}, - {"ClientTrace.GotConn", Field, 7, ""}, - {"ClientTrace.GotFirstResponseByte", Field, 7, ""}, - {"ClientTrace.PutIdleConn", Field, 7, ""}, - {"ClientTrace.TLSHandshakeDone", Field, 8, ""}, - {"ClientTrace.TLSHandshakeStart", Field, 8, ""}, - {"ClientTrace.Wait100Continue", Field, 7, ""}, - {"ClientTrace.WroteHeaderField", Field, 11, ""}, - {"ClientTrace.WroteHeaders", Field, 7, ""}, - {"ClientTrace.WroteRequest", Field, 7, ""}, - {"ContextClientTrace", Func, 7, "func(ctx context.Context) *ClientTrace"}, - {"DNSDoneInfo", Type, 7, ""}, - {"DNSDoneInfo.Addrs", Field, 7, ""}, - {"DNSDoneInfo.Coalesced", Field, 7, ""}, - {"DNSDoneInfo.Err", Field, 7, ""}, - {"DNSStartInfo", Type, 7, ""}, - {"DNSStartInfo.Host", Field, 7, ""}, - {"GotConnInfo", Type, 7, ""}, - {"GotConnInfo.Conn", Field, 7, ""}, - {"GotConnInfo.IdleTime", Field, 7, ""}, - {"GotConnInfo.Reused", Field, 7, ""}, - {"GotConnInfo.WasIdle", Field, 7, ""}, - {"WithClientTrace", Func, 7, "func(ctx context.Context, trace *ClientTrace) context.Context"}, - {"WroteRequestInfo", Type, 7, ""}, - {"WroteRequestInfo.Err", Field, 7, ""}, - }, - "net/http/httputil": { - {"(*ClientConn).Close", Method, 0, ""}, - {"(*ClientConn).Do", Method, 0, ""}, - {"(*ClientConn).Hijack", Method, 0, ""}, - {"(*ClientConn).Pending", Method, 0, ""}, - {"(*ClientConn).Read", Method, 0, ""}, - {"(*ClientConn).Write", Method, 0, ""}, - {"(*ProxyRequest).SetURL", Method, 20, ""}, - {"(*ProxyRequest).SetXForwarded", Method, 20, ""}, - {"(*ReverseProxy).ServeHTTP", Method, 0, ""}, - {"(*ServerConn).Close", Method, 0, ""}, - {"(*ServerConn).Hijack", Method, 0, ""}, - {"(*ServerConn).Pending", Method, 0, ""}, - {"(*ServerConn).Read", Method, 0, ""}, - {"(*ServerConn).Write", Method, 0, ""}, - {"(BufferPool).Get", Method, 6, ""}, - {"(BufferPool).Put", Method, 6, ""}, - {"BufferPool", Type, 6, ""}, - {"ClientConn", Type, 0, ""}, - {"DumpRequest", Func, 0, "func(req *http.Request, body bool) ([]byte, error)"}, - {"DumpRequestOut", Func, 0, "func(req *http.Request, body bool) ([]byte, error)"}, - {"DumpResponse", Func, 0, "func(resp *http.Response, body bool) ([]byte, error)"}, - {"ErrClosed", Var, 0, ""}, - {"ErrLineTooLong", Var, 0, ""}, - {"ErrPersistEOF", Var, 0, ""}, - {"ErrPipeline", Var, 0, ""}, - {"NewChunkedReader", Func, 0, "func(r io.Reader) io.Reader"}, - {"NewChunkedWriter", Func, 0, "func(w io.Writer) io.WriteCloser"}, - {"NewClientConn", Func, 0, "func(c net.Conn, r *bufio.Reader) *ClientConn"}, - {"NewProxyClientConn", Func, 0, "func(c net.Conn, r *bufio.Reader) *ClientConn"}, - {"NewServerConn", Func, 0, "func(c net.Conn, r *bufio.Reader) *ServerConn"}, - {"NewSingleHostReverseProxy", Func, 0, "func(target *url.URL) *ReverseProxy"}, - {"ProxyRequest", Type, 20, ""}, - {"ProxyRequest.In", Field, 20, ""}, - {"ProxyRequest.Out", Field, 20, ""}, - {"ReverseProxy", Type, 0, ""}, - {"ReverseProxy.BufferPool", Field, 6, ""}, - {"ReverseProxy.Director", Field, 0, ""}, - {"ReverseProxy.ErrorHandler", Field, 11, ""}, - {"ReverseProxy.ErrorLog", Field, 4, ""}, - {"ReverseProxy.FlushInterval", Field, 0, ""}, - {"ReverseProxy.ModifyResponse", Field, 8, ""}, - {"ReverseProxy.Rewrite", Field, 20, ""}, - {"ReverseProxy.Transport", Field, 0, ""}, - {"ServerConn", Type, 0, ""}, - }, - "net/http/pprof": { - {"Cmdline", Func, 0, "func(w http.ResponseWriter, r *http.Request)"}, - {"Handler", Func, 0, "func(name string) http.Handler"}, - {"Index", Func, 0, "func(w http.ResponseWriter, r *http.Request)"}, - {"Profile", Func, 0, "func(w http.ResponseWriter, r *http.Request)"}, - {"Symbol", Func, 0, "func(w http.ResponseWriter, r *http.Request)"}, - {"Trace", Func, 5, "func(w http.ResponseWriter, r *http.Request)"}, - }, - "net/mail": { - {"(*Address).String", Method, 0, ""}, - {"(*AddressParser).Parse", Method, 5, ""}, - {"(*AddressParser).ParseList", Method, 5, ""}, - {"(Header).AddressList", Method, 0, ""}, - {"(Header).Date", Method, 0, ""}, - {"(Header).Get", Method, 0, ""}, - {"Address", Type, 0, ""}, - {"Address.Address", Field, 0, ""}, - {"Address.Name", Field, 0, ""}, - {"AddressParser", Type, 5, ""}, - {"AddressParser.WordDecoder", Field, 5, ""}, - {"ErrHeaderNotPresent", Var, 0, ""}, - {"Header", Type, 0, ""}, - {"Message", Type, 0, ""}, - {"Message.Body", Field, 0, ""}, - {"Message.Header", Field, 0, ""}, - {"ParseAddress", Func, 1, "func(address string) (*Address, error)"}, - {"ParseAddressList", Func, 1, "func(list string) ([]*Address, error)"}, - {"ParseDate", Func, 8, "func(date string) (time.Time, error)"}, - {"ReadMessage", Func, 0, "func(r io.Reader) (msg *Message, err error)"}, - }, - "net/netip": { - {"(*Addr).UnmarshalBinary", Method, 18, ""}, - {"(*Addr).UnmarshalText", Method, 18, ""}, - {"(*AddrPort).UnmarshalBinary", Method, 18, ""}, - {"(*AddrPort).UnmarshalText", Method, 18, ""}, - {"(*Prefix).UnmarshalBinary", Method, 18, ""}, - {"(*Prefix).UnmarshalText", Method, 18, ""}, - {"(Addr).AppendBinary", Method, 24, ""}, - {"(Addr).AppendText", Method, 24, ""}, - {"(Addr).AppendTo", Method, 18, ""}, - {"(Addr).As16", Method, 18, ""}, - {"(Addr).As4", Method, 18, ""}, - {"(Addr).AsSlice", Method, 18, ""}, - {"(Addr).BitLen", Method, 18, ""}, - {"(Addr).Compare", Method, 18, ""}, - {"(Addr).Is4", Method, 18, ""}, - {"(Addr).Is4In6", Method, 18, ""}, - {"(Addr).Is6", Method, 18, ""}, - {"(Addr).IsGlobalUnicast", Method, 18, ""}, - {"(Addr).IsInterfaceLocalMulticast", Method, 18, ""}, - {"(Addr).IsLinkLocalMulticast", Method, 18, ""}, - {"(Addr).IsLinkLocalUnicast", Method, 18, ""}, - {"(Addr).IsLoopback", Method, 18, ""}, - {"(Addr).IsMulticast", Method, 18, ""}, - {"(Addr).IsPrivate", Method, 18, ""}, - {"(Addr).IsUnspecified", Method, 18, ""}, - {"(Addr).IsValid", Method, 18, ""}, - {"(Addr).Less", Method, 18, ""}, - {"(Addr).MarshalBinary", Method, 18, ""}, - {"(Addr).MarshalText", Method, 18, ""}, - {"(Addr).Next", Method, 18, ""}, - {"(Addr).Prefix", Method, 18, ""}, - {"(Addr).Prev", Method, 18, ""}, - {"(Addr).String", Method, 18, ""}, - {"(Addr).StringExpanded", Method, 18, ""}, - {"(Addr).Unmap", Method, 18, ""}, - {"(Addr).WithZone", Method, 18, ""}, - {"(Addr).Zone", Method, 18, ""}, - {"(AddrPort).Addr", Method, 18, ""}, - {"(AddrPort).AppendBinary", Method, 24, ""}, - {"(AddrPort).AppendText", Method, 24, ""}, - {"(AddrPort).AppendTo", Method, 18, ""}, - {"(AddrPort).Compare", Method, 22, ""}, - {"(AddrPort).IsValid", Method, 18, ""}, - {"(AddrPort).MarshalBinary", Method, 18, ""}, - {"(AddrPort).MarshalText", Method, 18, ""}, - {"(AddrPort).Port", Method, 18, ""}, - {"(AddrPort).String", Method, 18, ""}, - {"(Prefix).Addr", Method, 18, ""}, - {"(Prefix).AppendBinary", Method, 24, ""}, - {"(Prefix).AppendText", Method, 24, ""}, - {"(Prefix).AppendTo", Method, 18, ""}, - {"(Prefix).Bits", Method, 18, ""}, - {"(Prefix).Compare", Method, 26, ""}, - {"(Prefix).Contains", Method, 18, ""}, - {"(Prefix).IsSingleIP", Method, 18, ""}, - {"(Prefix).IsValid", Method, 18, ""}, - {"(Prefix).MarshalBinary", Method, 18, ""}, - {"(Prefix).MarshalText", Method, 18, ""}, - {"(Prefix).Masked", Method, 18, ""}, - {"(Prefix).Overlaps", Method, 18, ""}, - {"(Prefix).String", Method, 18, ""}, - {"Addr", Type, 18, ""}, - {"AddrFrom16", Func, 18, "func(addr [16]byte) Addr"}, - {"AddrFrom4", Func, 18, "func(addr [4]byte) Addr"}, - {"AddrFromSlice", Func, 18, "func(slice []byte) (ip Addr, ok bool)"}, - {"AddrPort", Type, 18, ""}, - {"AddrPortFrom", Func, 18, "func(ip Addr, port uint16) AddrPort"}, - {"IPv4Unspecified", Func, 18, "func() Addr"}, - {"IPv6LinkLocalAllNodes", Func, 18, "func() Addr"}, - {"IPv6LinkLocalAllRouters", Func, 20, "func() Addr"}, - {"IPv6Loopback", Func, 20, "func() Addr"}, - {"IPv6Unspecified", Func, 18, "func() Addr"}, - {"MustParseAddr", Func, 18, "func(s string) Addr"}, - {"MustParseAddrPort", Func, 18, "func(s string) AddrPort"}, - {"MustParsePrefix", Func, 18, "func(s string) Prefix"}, - {"ParseAddr", Func, 18, "func(s string) (Addr, error)"}, - {"ParseAddrPort", Func, 18, "func(s string) (AddrPort, error)"}, - {"ParsePrefix", Func, 18, "func(s string) (Prefix, error)"}, - {"Prefix", Type, 18, ""}, - {"PrefixFrom", Func, 18, "func(ip Addr, bits int) Prefix"}, - }, - "net/rpc": { - {"(*Client).Call", Method, 0, ""}, - {"(*Client).Close", Method, 0, ""}, - {"(*Client).Go", Method, 0, ""}, - {"(*Server).Accept", Method, 0, ""}, - {"(*Server).HandleHTTP", Method, 0, ""}, - {"(*Server).Register", Method, 0, ""}, - {"(*Server).RegisterName", Method, 0, ""}, - {"(*Server).ServeCodec", Method, 0, ""}, - {"(*Server).ServeConn", Method, 0, ""}, - {"(*Server).ServeHTTP", Method, 0, ""}, - {"(*Server).ServeRequest", Method, 0, ""}, - {"(ClientCodec).Close", Method, 0, ""}, - {"(ClientCodec).ReadResponseBody", Method, 0, ""}, - {"(ClientCodec).ReadResponseHeader", Method, 0, ""}, - {"(ClientCodec).WriteRequest", Method, 0, ""}, - {"(ServerCodec).Close", Method, 0, ""}, - {"(ServerCodec).ReadRequestBody", Method, 0, ""}, - {"(ServerCodec).ReadRequestHeader", Method, 0, ""}, - {"(ServerCodec).WriteResponse", Method, 0, ""}, - {"(ServerError).Error", Method, 0, ""}, - {"Accept", Func, 0, "func(lis net.Listener)"}, - {"Call", Type, 0, ""}, - {"Call.Args", Field, 0, ""}, - {"Call.Done", Field, 0, ""}, - {"Call.Error", Field, 0, ""}, - {"Call.Reply", Field, 0, ""}, - {"Call.ServiceMethod", Field, 0, ""}, - {"Client", Type, 0, ""}, - {"ClientCodec", Type, 0, ""}, - {"DefaultDebugPath", Const, 0, ""}, - {"DefaultRPCPath", Const, 0, ""}, - {"DefaultServer", Var, 0, ""}, - {"Dial", Func, 0, "func(network string, address string) (*Client, error)"}, - {"DialHTTP", Func, 0, "func(network string, address string) (*Client, error)"}, - {"DialHTTPPath", Func, 0, "func(network string, address string, path string) (*Client, error)"}, - {"ErrShutdown", Var, 0, ""}, - {"HandleHTTP", Func, 0, "func()"}, - {"NewClient", Func, 0, "func(conn io.ReadWriteCloser) *Client"}, - {"NewClientWithCodec", Func, 0, "func(codec ClientCodec) *Client"}, - {"NewServer", Func, 0, "func() *Server"}, - {"Register", Func, 0, "func(rcvr any) error"}, - {"RegisterName", Func, 0, "func(name string, rcvr any) error"}, - {"Request", Type, 0, ""}, - {"Request.Seq", Field, 0, ""}, - {"Request.ServiceMethod", Field, 0, ""}, - {"Response", Type, 0, ""}, - {"Response.Error", Field, 0, ""}, - {"Response.Seq", Field, 0, ""}, - {"Response.ServiceMethod", Field, 0, ""}, - {"ServeCodec", Func, 0, "func(codec ServerCodec)"}, - {"ServeConn", Func, 0, "func(conn io.ReadWriteCloser)"}, - {"ServeRequest", Func, 0, "func(codec ServerCodec) error"}, - {"Server", Type, 0, ""}, - {"ServerCodec", Type, 0, ""}, - {"ServerError", Type, 0, ""}, - }, - "net/rpc/jsonrpc": { - {"Dial", Func, 0, "func(network string, address string) (*rpc.Client, error)"}, - {"NewClient", Func, 0, "func(conn io.ReadWriteCloser) *rpc.Client"}, - {"NewClientCodec", Func, 0, "func(conn io.ReadWriteCloser) rpc.ClientCodec"}, - {"NewServerCodec", Func, 0, "func(conn io.ReadWriteCloser) rpc.ServerCodec"}, - {"ServeConn", Func, 0, "func(conn io.ReadWriteCloser)"}, - }, - "net/smtp": { - {"(*Client).Auth", Method, 0, ""}, - {"(*Client).Close", Method, 2, ""}, - {"(*Client).Data", Method, 0, ""}, - {"(*Client).Extension", Method, 0, ""}, - {"(*Client).Hello", Method, 1, ""}, - {"(*Client).Mail", Method, 0, ""}, - {"(*Client).Noop", Method, 10, ""}, - {"(*Client).Quit", Method, 0, ""}, - {"(*Client).Rcpt", Method, 0, ""}, - {"(*Client).Reset", Method, 0, ""}, - {"(*Client).StartTLS", Method, 0, ""}, - {"(*Client).TLSConnectionState", Method, 5, ""}, - {"(*Client).Verify", Method, 0, ""}, - {"(Auth).Next", Method, 0, ""}, - {"(Auth).Start", Method, 0, ""}, - {"Auth", Type, 0, ""}, - {"CRAMMD5Auth", Func, 0, "func(username string, secret string) Auth"}, - {"Client", Type, 0, ""}, - {"Client.Text", Field, 0, ""}, - {"Dial", Func, 0, "func(addr string) (*Client, error)"}, - {"NewClient", Func, 0, "func(conn net.Conn, host string) (*Client, error)"}, - {"PlainAuth", Func, 0, "func(identity string, username string, password string, host string) Auth"}, - {"SendMail", Func, 0, "func(addr string, a Auth, from string, to []string, msg []byte) error"}, - {"ServerInfo", Type, 0, ""}, - {"ServerInfo.Auth", Field, 0, ""}, - {"ServerInfo.Name", Field, 0, ""}, - {"ServerInfo.TLS", Field, 0, ""}, - }, - "net/textproto": { - {"(*Conn).Close", Method, 0, ""}, - {"(*Conn).Cmd", Method, 0, ""}, - {"(*Conn).DotReader", Method, 0, ""}, - {"(*Conn).DotWriter", Method, 0, ""}, - {"(*Conn).EndRequest", Method, 0, ""}, - {"(*Conn).EndResponse", Method, 0, ""}, - {"(*Conn).Next", Method, 0, ""}, - {"(*Conn).PrintfLine", Method, 0, ""}, - {"(*Conn).ReadCodeLine", Method, 0, ""}, - {"(*Conn).ReadContinuedLine", Method, 0, ""}, - {"(*Conn).ReadContinuedLineBytes", Method, 0, ""}, - {"(*Conn).ReadDotBytes", Method, 0, ""}, - {"(*Conn).ReadDotLines", Method, 0, ""}, - {"(*Conn).ReadLine", Method, 0, ""}, - {"(*Conn).ReadLineBytes", Method, 0, ""}, - {"(*Conn).ReadMIMEHeader", Method, 0, ""}, - {"(*Conn).ReadResponse", Method, 0, ""}, - {"(*Conn).StartRequest", Method, 0, ""}, - {"(*Conn).StartResponse", Method, 0, ""}, - {"(*Error).Error", Method, 0, ""}, - {"(*Pipeline).EndRequest", Method, 0, ""}, - {"(*Pipeline).EndResponse", Method, 0, ""}, - {"(*Pipeline).Next", Method, 0, ""}, - {"(*Pipeline).StartRequest", Method, 0, ""}, - {"(*Pipeline).StartResponse", Method, 0, ""}, - {"(*Reader).DotReader", Method, 0, ""}, - {"(*Reader).ReadCodeLine", Method, 0, ""}, - {"(*Reader).ReadContinuedLine", Method, 0, ""}, - {"(*Reader).ReadContinuedLineBytes", Method, 0, ""}, - {"(*Reader).ReadDotBytes", Method, 0, ""}, - {"(*Reader).ReadDotLines", Method, 0, ""}, - {"(*Reader).ReadLine", Method, 0, ""}, - {"(*Reader).ReadLineBytes", Method, 0, ""}, - {"(*Reader).ReadMIMEHeader", Method, 0, ""}, - {"(*Reader).ReadResponse", Method, 0, ""}, - {"(*Writer).DotWriter", Method, 0, ""}, - {"(*Writer).PrintfLine", Method, 0, ""}, - {"(MIMEHeader).Add", Method, 0, ""}, - {"(MIMEHeader).Del", Method, 0, ""}, - {"(MIMEHeader).Get", Method, 0, ""}, - {"(MIMEHeader).Set", Method, 0, ""}, - {"(MIMEHeader).Values", Method, 14, ""}, - {"(ProtocolError).Error", Method, 0, ""}, - {"CanonicalMIMEHeaderKey", Func, 0, "func(s string) string"}, - {"Conn", Type, 0, ""}, - {"Conn.Pipeline", Field, 0, ""}, - {"Conn.Reader", Field, 0, ""}, - {"Conn.Writer", Field, 0, ""}, - {"Dial", Func, 0, "func(network string, addr string) (*Conn, error)"}, - {"Error", Type, 0, ""}, - {"Error.Code", Field, 0, ""}, - {"Error.Msg", Field, 0, ""}, - {"MIMEHeader", Type, 0, ""}, - {"NewConn", Func, 0, "func(conn io.ReadWriteCloser) *Conn"}, - {"NewReader", Func, 0, "func(r *bufio.Reader) *Reader"}, - {"NewWriter", Func, 0, "func(w *bufio.Writer) *Writer"}, - {"Pipeline", Type, 0, ""}, - {"ProtocolError", Type, 0, ""}, - {"Reader", Type, 0, ""}, - {"Reader.R", Field, 0, ""}, - {"TrimBytes", Func, 1, "func(b []byte) []byte"}, - {"TrimString", Func, 1, "func(s string) string"}, - {"Writer", Type, 0, ""}, - {"Writer.W", Field, 0, ""}, - }, - "net/url": { - {"(*Error).Error", Method, 0, ""}, - {"(*Error).Temporary", Method, 6, ""}, - {"(*Error).Timeout", Method, 6, ""}, - {"(*Error).Unwrap", Method, 13, ""}, - {"(*URL).AppendBinary", Method, 24, ""}, - {"(*URL).EscapedFragment", Method, 15, ""}, - {"(*URL).EscapedPath", Method, 5, ""}, - {"(*URL).Hostname", Method, 8, ""}, - {"(*URL).IsAbs", Method, 0, ""}, - {"(*URL).JoinPath", Method, 19, ""}, - {"(*URL).MarshalBinary", Method, 8, ""}, - {"(*URL).Parse", Method, 0, ""}, - {"(*URL).Port", Method, 8, ""}, - {"(*URL).Query", Method, 0, ""}, - {"(*URL).Redacted", Method, 15, ""}, - {"(*URL).RequestURI", Method, 0, ""}, - {"(*URL).ResolveReference", Method, 0, ""}, - {"(*URL).String", Method, 0, ""}, - {"(*URL).UnmarshalBinary", Method, 8, ""}, - {"(*Userinfo).Password", Method, 0, ""}, - {"(*Userinfo).String", Method, 0, ""}, - {"(*Userinfo).Username", Method, 0, ""}, - {"(EscapeError).Error", Method, 0, ""}, - {"(InvalidHostError).Error", Method, 6, ""}, - {"(Values).Add", Method, 0, ""}, - {"(Values).Del", Method, 0, ""}, - {"(Values).Encode", Method, 0, ""}, - {"(Values).Get", Method, 0, ""}, - {"(Values).Has", Method, 17, ""}, - {"(Values).Set", Method, 0, ""}, - {"Error", Type, 0, ""}, - {"Error.Err", Field, 0, ""}, - {"Error.Op", Field, 0, ""}, - {"Error.URL", Field, 0, ""}, - {"EscapeError", Type, 0, ""}, - {"InvalidHostError", Type, 6, ""}, - {"JoinPath", Func, 19, "func(base string, elem ...string) (result string, err error)"}, - {"Parse", Func, 0, "func(rawURL string) (*URL, error)"}, - {"ParseQuery", Func, 0, "func(query string) (Values, error)"}, - {"ParseRequestURI", Func, 0, "func(rawURL string) (*URL, error)"}, - {"PathEscape", Func, 8, "func(s string) string"}, - {"PathUnescape", Func, 8, "func(s string) (string, error)"}, - {"QueryEscape", Func, 0, "func(s string) string"}, - {"QueryUnescape", Func, 0, "func(s string) (string, error)"}, - {"URL", Type, 0, ""}, - {"URL.ForceQuery", Field, 7, ""}, - {"URL.Fragment", Field, 0, ""}, - {"URL.Host", Field, 0, ""}, - {"URL.OmitHost", Field, 19, ""}, - {"URL.Opaque", Field, 0, ""}, - {"URL.Path", Field, 0, ""}, - {"URL.RawFragment", Field, 15, ""}, - {"URL.RawPath", Field, 5, ""}, - {"URL.RawQuery", Field, 0, ""}, - {"URL.Scheme", Field, 0, ""}, - {"URL.User", Field, 0, ""}, - {"User", Func, 0, "func(username string) *Userinfo"}, - {"UserPassword", Func, 0, "func(username string, password string) *Userinfo"}, - {"Userinfo", Type, 0, ""}, - {"Values", Type, 0, ""}, - }, - "os": { - {"(*File).Chdir", Method, 0, ""}, - {"(*File).Chmod", Method, 0, ""}, - {"(*File).Chown", Method, 0, ""}, - {"(*File).Close", Method, 0, ""}, - {"(*File).Fd", Method, 0, ""}, - {"(*File).Name", Method, 0, ""}, - {"(*File).Read", Method, 0, ""}, - {"(*File).ReadAt", Method, 0, ""}, - {"(*File).ReadDir", Method, 16, ""}, - {"(*File).ReadFrom", Method, 15, ""}, - {"(*File).Readdir", Method, 0, ""}, - {"(*File).Readdirnames", Method, 0, ""}, - {"(*File).Seek", Method, 0, ""}, - {"(*File).SetDeadline", Method, 10, ""}, - {"(*File).SetReadDeadline", Method, 10, ""}, - {"(*File).SetWriteDeadline", Method, 10, ""}, - {"(*File).Stat", Method, 0, ""}, - {"(*File).Sync", Method, 0, ""}, - {"(*File).SyscallConn", Method, 12, ""}, - {"(*File).Truncate", Method, 0, ""}, - {"(*File).Write", Method, 0, ""}, - {"(*File).WriteAt", Method, 0, ""}, - {"(*File).WriteString", Method, 0, ""}, - {"(*File).WriteTo", Method, 22, ""}, - {"(*LinkError).Error", Method, 0, ""}, - {"(*LinkError).Unwrap", Method, 13, ""}, - {"(*PathError).Error", Method, 0, ""}, - {"(*PathError).Timeout", Method, 10, ""}, - {"(*PathError).Unwrap", Method, 13, ""}, - {"(*Process).Kill", Method, 0, ""}, - {"(*Process).Release", Method, 0, ""}, - {"(*Process).Signal", Method, 0, ""}, - {"(*Process).Wait", Method, 0, ""}, - {"(*Process).WithHandle", Method, 26, ""}, - {"(*ProcessState).ExitCode", Method, 12, ""}, - {"(*ProcessState).Exited", Method, 0, ""}, - {"(*ProcessState).Pid", Method, 0, ""}, - {"(*ProcessState).String", Method, 0, ""}, - {"(*ProcessState).Success", Method, 0, ""}, - {"(*ProcessState).Sys", Method, 0, ""}, - {"(*ProcessState).SysUsage", Method, 0, ""}, - {"(*ProcessState).SystemTime", Method, 0, ""}, - {"(*ProcessState).UserTime", Method, 0, ""}, - {"(*Root).Chmod", Method, 25, ""}, - {"(*Root).Chown", Method, 25, ""}, - {"(*Root).Chtimes", Method, 25, ""}, - {"(*Root).Close", Method, 24, ""}, - {"(*Root).Create", Method, 24, ""}, - {"(*Root).FS", Method, 24, ""}, - {"(*Root).Lchown", Method, 25, ""}, - {"(*Root).Link", Method, 25, ""}, - {"(*Root).Lstat", Method, 24, ""}, - {"(*Root).Mkdir", Method, 24, ""}, - {"(*Root).MkdirAll", Method, 25, ""}, - {"(*Root).Name", Method, 24, ""}, - {"(*Root).Open", Method, 24, ""}, - {"(*Root).OpenFile", Method, 24, ""}, - {"(*Root).OpenRoot", Method, 24, ""}, - {"(*Root).ReadFile", Method, 25, ""}, - {"(*Root).Readlink", Method, 25, ""}, - {"(*Root).Remove", Method, 24, ""}, - {"(*Root).RemoveAll", Method, 25, ""}, - {"(*Root).Rename", Method, 25, ""}, - {"(*Root).Stat", Method, 24, ""}, - {"(*Root).Symlink", Method, 25, ""}, - {"(*Root).WriteFile", Method, 25, ""}, - {"(*SyscallError).Error", Method, 0, ""}, - {"(*SyscallError).Timeout", Method, 10, ""}, - {"(*SyscallError).Unwrap", Method, 13, ""}, - {"(FileInfo).IsDir", Method, 0, ""}, - {"(FileInfo).ModTime", Method, 0, ""}, - {"(FileInfo).Mode", Method, 0, ""}, - {"(FileInfo).Name", Method, 0, ""}, - {"(FileInfo).Size", Method, 0, ""}, - {"(FileInfo).Sys", Method, 0, ""}, - {"(FileMode).IsDir", Method, 0, ""}, - {"(FileMode).IsRegular", Method, 1, ""}, - {"(FileMode).Perm", Method, 0, ""}, - {"(FileMode).String", Method, 0, ""}, - {"(Signal).Signal", Method, 0, ""}, - {"(Signal).String", Method, 0, ""}, - {"Args", Var, 0, ""}, - {"Chdir", Func, 0, "func(dir string) error"}, - {"Chmod", Func, 0, "func(name string, mode FileMode) error"}, - {"Chown", Func, 0, "func(name string, uid int, gid int) error"}, - {"Chtimes", Func, 0, "func(name string, atime time.Time, mtime time.Time) error"}, - {"Clearenv", Func, 0, "func()"}, - {"CopyFS", Func, 23, "func(dir string, fsys fs.FS) error"}, - {"Create", Func, 0, "func(name string) (*File, error)"}, - {"CreateTemp", Func, 16, "func(dir string, pattern string) (*File, error)"}, - {"DevNull", Const, 0, ""}, - {"DirEntry", Type, 16, ""}, - {"DirFS", Func, 16, "func(dir string) fs.FS"}, - {"Environ", Func, 0, "func() []string"}, - {"ErrClosed", Var, 8, ""}, - {"ErrDeadlineExceeded", Var, 15, ""}, - {"ErrExist", Var, 0, ""}, - {"ErrInvalid", Var, 0, ""}, - {"ErrNoDeadline", Var, 10, ""}, - {"ErrNoHandle", Var, 26, ""}, - {"ErrNotExist", Var, 0, ""}, - {"ErrPermission", Var, 0, ""}, - {"ErrProcessDone", Var, 16, ""}, - {"Executable", Func, 8, "func() (string, error)"}, - {"Exit", Func, 0, "func(code int)"}, - {"Expand", Func, 0, "func(s string, mapping func(string) string) string"}, - {"ExpandEnv", Func, 0, "func(s string) string"}, - {"File", Type, 0, ""}, - {"FileInfo", Type, 0, ""}, - {"FileMode", Type, 0, ""}, - {"FindProcess", Func, 0, "func(pid int) (*Process, error)"}, - {"Getegid", Func, 0, "func() int"}, - {"Getenv", Func, 0, "func(key string) string"}, - {"Geteuid", Func, 0, "func() int"}, - {"Getgid", Func, 0, "func() int"}, - {"Getgroups", Func, 0, "func() ([]int, error)"}, - {"Getpagesize", Func, 0, "func() int"}, - {"Getpid", Func, 0, "func() int"}, - {"Getppid", Func, 0, "func() int"}, - {"Getuid", Func, 0, "func() int"}, - {"Getwd", Func, 0, "func() (dir string, err error)"}, - {"Hostname", Func, 0, "func() (name string, err error)"}, - {"Interrupt", Var, 0, ""}, - {"IsExist", Func, 0, "func(err error) bool"}, - {"IsNotExist", Func, 0, "func(err error) bool"}, - {"IsPathSeparator", Func, 0, "func(c uint8) bool"}, - {"IsPermission", Func, 0, "func(err error) bool"}, - {"IsTimeout", Func, 10, "func(err error) bool"}, - {"Kill", Var, 0, ""}, - {"Lchown", Func, 0, "func(name string, uid int, gid int) error"}, - {"Link", Func, 0, "func(oldname string, newname string) error"}, - {"LinkError", Type, 0, ""}, - {"LinkError.Err", Field, 0, ""}, - {"LinkError.New", Field, 0, ""}, - {"LinkError.Old", Field, 0, ""}, - {"LinkError.Op", Field, 0, ""}, - {"LookupEnv", Func, 5, "func(key string) (string, bool)"}, - {"Lstat", Func, 0, "func(name string) (FileInfo, error)"}, - {"Mkdir", Func, 0, "func(name string, perm FileMode) error"}, - {"MkdirAll", Func, 0, "func(path string, perm FileMode) error"}, - {"MkdirTemp", Func, 16, "func(dir string, pattern string) (string, error)"}, - {"ModeAppend", Const, 0, ""}, - {"ModeCharDevice", Const, 0, ""}, - {"ModeDevice", Const, 0, ""}, - {"ModeDir", Const, 0, ""}, - {"ModeExclusive", Const, 0, ""}, - {"ModeIrregular", Const, 11, ""}, - {"ModeNamedPipe", Const, 0, ""}, - {"ModePerm", Const, 0, ""}, - {"ModeSetgid", Const, 0, ""}, - {"ModeSetuid", Const, 0, ""}, - {"ModeSocket", Const, 0, ""}, - {"ModeSticky", Const, 0, ""}, - {"ModeSymlink", Const, 0, ""}, - {"ModeTemporary", Const, 0, ""}, - {"ModeType", Const, 0, ""}, - {"NewFile", Func, 0, "func(fd uintptr, name string) *File"}, - {"NewSyscallError", Func, 0, "func(syscall string, err error) error"}, - {"O_APPEND", Const, 0, ""}, - {"O_CREATE", Const, 0, ""}, - {"O_EXCL", Const, 0, ""}, - {"O_RDONLY", Const, 0, ""}, - {"O_RDWR", Const, 0, ""}, - {"O_SYNC", Const, 0, ""}, - {"O_TRUNC", Const, 0, ""}, - {"O_WRONLY", Const, 0, ""}, - {"Open", Func, 0, "func(name string) (*File, error)"}, - {"OpenFile", Func, 0, "func(name string, flag int, perm FileMode) (*File, error)"}, - {"OpenInRoot", Func, 24, "func(dir string, name string) (*File, error)"}, - {"OpenRoot", Func, 24, "func(name string) (*Root, error)"}, - {"PathError", Type, 0, ""}, - {"PathError.Err", Field, 0, ""}, - {"PathError.Op", Field, 0, ""}, - {"PathError.Path", Field, 0, ""}, - {"PathListSeparator", Const, 0, ""}, - {"PathSeparator", Const, 0, ""}, - {"Pipe", Func, 0, "func() (r *File, w *File, err error)"}, - {"ProcAttr", Type, 0, ""}, - {"ProcAttr.Dir", Field, 0, ""}, - {"ProcAttr.Env", Field, 0, ""}, - {"ProcAttr.Files", Field, 0, ""}, - {"ProcAttr.Sys", Field, 0, ""}, - {"Process", Type, 0, ""}, - {"Process.Pid", Field, 0, ""}, - {"ProcessState", Type, 0, ""}, - {"ReadDir", Func, 16, "func(name string) ([]DirEntry, error)"}, - {"ReadFile", Func, 16, "func(name string) ([]byte, error)"}, - {"Readlink", Func, 0, "func(name string) (string, error)"}, - {"Remove", Func, 0, "func(name string) error"}, - {"RemoveAll", Func, 0, "func(path string) error"}, - {"Rename", Func, 0, "func(oldpath string, newpath string) error"}, - {"Root", Type, 24, ""}, - {"SEEK_CUR", Const, 0, ""}, - {"SEEK_END", Const, 0, ""}, - {"SEEK_SET", Const, 0, ""}, - {"SameFile", Func, 0, "func(fi1 FileInfo, fi2 FileInfo) bool"}, - {"Setenv", Func, 0, "func(key string, value string) error"}, - {"Signal", Type, 0, ""}, - {"StartProcess", Func, 0, "func(name string, argv []string, attr *ProcAttr) (*Process, error)"}, - {"Stat", Func, 0, "func(name string) (FileInfo, error)"}, - {"Stderr", Var, 0, ""}, - {"Stdin", Var, 0, ""}, - {"Stdout", Var, 0, ""}, - {"Symlink", Func, 0, "func(oldname string, newname string) error"}, - {"SyscallError", Type, 0, ""}, - {"SyscallError.Err", Field, 0, ""}, - {"SyscallError.Syscall", Field, 0, ""}, - {"TempDir", Func, 0, "func() string"}, - {"Truncate", Func, 0, "func(name string, size int64) error"}, - {"Unsetenv", Func, 4, "func(key string) error"}, - {"UserCacheDir", Func, 11, "func() (string, error)"}, - {"UserConfigDir", Func, 13, "func() (string, error)"}, - {"UserHomeDir", Func, 12, "func() (string, error)"}, - {"WriteFile", Func, 16, "func(name string, data []byte, perm FileMode) error"}, - }, - "os/exec": { - {"(*Cmd).CombinedOutput", Method, 0, ""}, - {"(*Cmd).Environ", Method, 19, ""}, - {"(*Cmd).Output", Method, 0, ""}, - {"(*Cmd).Run", Method, 0, ""}, - {"(*Cmd).Start", Method, 0, ""}, - {"(*Cmd).StderrPipe", Method, 0, ""}, - {"(*Cmd).StdinPipe", Method, 0, ""}, - {"(*Cmd).StdoutPipe", Method, 0, ""}, - {"(*Cmd).String", Method, 13, ""}, - {"(*Cmd).Wait", Method, 0, ""}, - {"(*Error).Error", Method, 0, ""}, - {"(*Error).Unwrap", Method, 13, ""}, - {"(*ExitError).Error", Method, 0, ""}, - {"(ExitError).ExitCode", Method, 12, ""}, - {"(ExitError).Exited", Method, 0, ""}, - {"(ExitError).Pid", Method, 0, ""}, - {"(ExitError).String", Method, 0, ""}, - {"(ExitError).Success", Method, 0, ""}, - {"(ExitError).Sys", Method, 0, ""}, - {"(ExitError).SysUsage", Method, 0, ""}, - {"(ExitError).SystemTime", Method, 0, ""}, - {"(ExitError).UserTime", Method, 0, ""}, - {"Cmd", Type, 0, ""}, - {"Cmd.Args", Field, 0, ""}, - {"Cmd.Cancel", Field, 20, ""}, - {"Cmd.Dir", Field, 0, ""}, - {"Cmd.Env", Field, 0, ""}, - {"Cmd.Err", Field, 19, ""}, - {"Cmd.ExtraFiles", Field, 0, ""}, - {"Cmd.Path", Field, 0, ""}, - {"Cmd.Process", Field, 0, ""}, - {"Cmd.ProcessState", Field, 0, ""}, - {"Cmd.Stderr", Field, 0, ""}, - {"Cmd.Stdin", Field, 0, ""}, - {"Cmd.Stdout", Field, 0, ""}, - {"Cmd.SysProcAttr", Field, 0, ""}, - {"Cmd.WaitDelay", Field, 20, ""}, - {"Command", Func, 0, "func(name string, arg ...string) *Cmd"}, - {"CommandContext", Func, 7, "func(ctx context.Context, name string, arg ...string) *Cmd"}, - {"ErrDot", Var, 19, ""}, - {"ErrNotFound", Var, 0, ""}, - {"ErrWaitDelay", Var, 20, ""}, - {"Error", Type, 0, ""}, - {"Error.Err", Field, 0, ""}, - {"Error.Name", Field, 0, ""}, - {"ExitError", Type, 0, ""}, - {"ExitError.ProcessState", Field, 0, ""}, - {"ExitError.Stderr", Field, 6, ""}, - {"LookPath", Func, 0, "func(file string) (string, error)"}, - }, - "os/signal": { - {"Ignore", Func, 5, "func(sig ...os.Signal)"}, - {"Ignored", Func, 11, "func(sig os.Signal) bool"}, - {"Notify", Func, 0, "func(c chan<- os.Signal, sig ...os.Signal)"}, - {"NotifyContext", Func, 16, "func(parent context.Context, signals ...os.Signal) (ctx context.Context, stop context.CancelFunc)"}, - {"Reset", Func, 5, "func(sig ...os.Signal)"}, - {"Stop", Func, 1, "func(c chan<- os.Signal)"}, - }, - "os/user": { - {"(*User).GroupIds", Method, 7, ""}, - {"(UnknownGroupError).Error", Method, 7, ""}, - {"(UnknownGroupIdError).Error", Method, 7, ""}, - {"(UnknownUserError).Error", Method, 0, ""}, - {"(UnknownUserIdError).Error", Method, 0, ""}, - {"Current", Func, 0, "func() (*User, error)"}, - {"Group", Type, 7, ""}, - {"Group.Gid", Field, 7, ""}, - {"Group.Name", Field, 7, ""}, - {"Lookup", Func, 0, "func(username string) (*User, error)"}, - {"LookupGroup", Func, 7, "func(name string) (*Group, error)"}, - {"LookupGroupId", Func, 7, "func(gid string) (*Group, error)"}, - {"LookupId", Func, 0, "func(uid string) (*User, error)"}, - {"UnknownGroupError", Type, 7, ""}, - {"UnknownGroupIdError", Type, 7, ""}, - {"UnknownUserError", Type, 0, ""}, - {"UnknownUserIdError", Type, 0, ""}, - {"User", Type, 0, ""}, - {"User.Gid", Field, 0, ""}, - {"User.HomeDir", Field, 0, ""}, - {"User.Name", Field, 0, ""}, - {"User.Uid", Field, 0, ""}, - {"User.Username", Field, 0, ""}, - }, - "path": { - {"Base", Func, 0, "func(path string) string"}, - {"Clean", Func, 0, "func(path string) string"}, - {"Dir", Func, 0, "func(path string) string"}, - {"ErrBadPattern", Var, 0, ""}, - {"Ext", Func, 0, "func(path string) string"}, - {"IsAbs", Func, 0, "func(path string) bool"}, - {"Join", Func, 0, "func(elem ...string) string"}, - {"Match", Func, 0, "func(pattern string, name string) (matched bool, err error)"}, - {"Split", Func, 0, "func(path string) (dir string, file string)"}, - }, - "path/filepath": { - {"Abs", Func, 0, "func(path string) (string, error)"}, - {"Base", Func, 0, "func(path string) string"}, - {"Clean", Func, 0, "func(path string) string"}, - {"Dir", Func, 0, "func(path string) string"}, - {"ErrBadPattern", Var, 0, ""}, - {"EvalSymlinks", Func, 0, "func(path string) (string, error)"}, - {"Ext", Func, 0, "func(path string) string"}, - {"FromSlash", Func, 0, "func(path string) string"}, - {"Glob", Func, 0, "func(pattern string) (matches []string, err error)"}, - {"HasPrefix", Func, 0, "func(p string, prefix string) bool"}, - {"IsAbs", Func, 0, "func(path string) bool"}, - {"IsLocal", Func, 20, "func(path string) bool"}, - {"Join", Func, 0, "func(elem ...string) string"}, - {"ListSeparator", Const, 0, ""}, - {"Localize", Func, 23, "func(path string) (string, error)"}, - {"Match", Func, 0, "func(pattern string, name string) (matched bool, err error)"}, - {"Rel", Func, 0, "func(basePath string, targPath string) (string, error)"}, - {"Separator", Const, 0, ""}, - {"SkipAll", Var, 20, ""}, - {"SkipDir", Var, 0, ""}, - {"Split", Func, 0, "func(path string) (dir string, file string)"}, - {"SplitList", Func, 0, "func(path string) []string"}, - {"ToSlash", Func, 0, "func(path string) string"}, - {"VolumeName", Func, 0, "func(path string) string"}, - {"Walk", Func, 0, "func(root string, fn WalkFunc) error"}, - {"WalkDir", Func, 16, "func(root string, fn fs.WalkDirFunc) error"}, - {"WalkFunc", Type, 0, ""}, - }, - "plugin": { - {"(*Plugin).Lookup", Method, 8, ""}, - {"Open", Func, 8, "func(path string) (*Plugin, error)"}, - {"Plugin", Type, 8, ""}, - {"Symbol", Type, 8, ""}, - }, - "reflect": { - {"(*MapIter).Key", Method, 12, ""}, - {"(*MapIter).Next", Method, 12, ""}, - {"(*MapIter).Reset", Method, 18, ""}, - {"(*MapIter).Value", Method, 12, ""}, - {"(*ValueError).Error", Method, 0, ""}, - {"(ChanDir).String", Method, 0, ""}, - {"(Kind).String", Method, 0, ""}, - {"(Method).IsExported", Method, 17, ""}, - {"(StructField).IsExported", Method, 17, ""}, - {"(StructTag).Get", Method, 0, ""}, - {"(StructTag).Lookup", Method, 7, ""}, - {"(Type).Align", Method, 0, ""}, - {"(Type).AssignableTo", Method, 0, ""}, - {"(Type).Bits", Method, 0, ""}, - {"(Type).CanSeq", Method, 23, ""}, - {"(Type).CanSeq2", Method, 23, ""}, - {"(Type).ChanDir", Method, 0, ""}, - {"(Type).Comparable", Method, 4, ""}, - {"(Type).ConvertibleTo", Method, 1, ""}, - {"(Type).Elem", Method, 0, ""}, - {"(Type).Field", Method, 0, ""}, - {"(Type).FieldAlign", Method, 0, ""}, - {"(Type).FieldByIndex", Method, 0, ""}, - {"(Type).FieldByName", Method, 0, ""}, - {"(Type).FieldByNameFunc", Method, 0, ""}, - {"(Type).Fields", Method, 26, ""}, - {"(Type).Implements", Method, 0, ""}, - {"(Type).In", Method, 0, ""}, - {"(Type).Ins", Method, 26, ""}, - {"(Type).IsVariadic", Method, 0, ""}, - {"(Type).Key", Method, 0, ""}, - {"(Type).Kind", Method, 0, ""}, - {"(Type).Len", Method, 0, ""}, - {"(Type).Method", Method, 0, ""}, - {"(Type).MethodByName", Method, 0, ""}, - {"(Type).Methods", Method, 26, ""}, - {"(Type).Name", Method, 0, ""}, - {"(Type).NumField", Method, 0, ""}, - {"(Type).NumIn", Method, 0, ""}, - {"(Type).NumMethod", Method, 0, ""}, - {"(Type).NumOut", Method, 0, ""}, - {"(Type).Out", Method, 0, ""}, - {"(Type).Outs", Method, 26, ""}, - {"(Type).OverflowComplex", Method, 23, ""}, - {"(Type).OverflowFloat", Method, 23, ""}, - {"(Type).OverflowInt", Method, 23, ""}, - {"(Type).OverflowUint", Method, 23, ""}, - {"(Type).PkgPath", Method, 0, ""}, - {"(Type).Size", Method, 0, ""}, - {"(Type).String", Method, 0, ""}, - {"(Value).Addr", Method, 0, ""}, - {"(Value).Bool", Method, 0, ""}, - {"(Value).Bytes", Method, 0, ""}, - {"(Value).Call", Method, 0, ""}, - {"(Value).CallSlice", Method, 0, ""}, - {"(Value).CanAddr", Method, 0, ""}, - {"(Value).CanComplex", Method, 18, ""}, - {"(Value).CanConvert", Method, 17, ""}, - {"(Value).CanFloat", Method, 18, ""}, - {"(Value).CanInt", Method, 18, ""}, - {"(Value).CanInterface", Method, 0, ""}, - {"(Value).CanSet", Method, 0, ""}, - {"(Value).CanUint", Method, 18, ""}, - {"(Value).Cap", Method, 0, ""}, - {"(Value).Clear", Method, 21, ""}, - {"(Value).Close", Method, 0, ""}, - {"(Value).Comparable", Method, 20, ""}, - {"(Value).Complex", Method, 0, ""}, - {"(Value).Convert", Method, 1, ""}, - {"(Value).Elem", Method, 0, ""}, - {"(Value).Equal", Method, 20, ""}, - {"(Value).Field", Method, 0, ""}, - {"(Value).FieldByIndex", Method, 0, ""}, - {"(Value).FieldByIndexErr", Method, 18, ""}, - {"(Value).FieldByName", Method, 0, ""}, - {"(Value).FieldByNameFunc", Method, 0, ""}, - {"(Value).Fields", Method, 26, ""}, - {"(Value).Float", Method, 0, ""}, - {"(Value).Grow", Method, 20, ""}, - {"(Value).Index", Method, 0, ""}, - {"(Value).Int", Method, 0, ""}, - {"(Value).Interface", Method, 0, ""}, - {"(Value).InterfaceData", Method, 0, ""}, - {"(Value).IsNil", Method, 0, ""}, - {"(Value).IsValid", Method, 0, ""}, - {"(Value).IsZero", Method, 13, ""}, - {"(Value).Kind", Method, 0, ""}, - {"(Value).Len", Method, 0, ""}, - {"(Value).MapIndex", Method, 0, ""}, - {"(Value).MapKeys", Method, 0, ""}, - {"(Value).MapRange", Method, 12, ""}, - {"(Value).Method", Method, 0, ""}, - {"(Value).MethodByName", Method, 0, ""}, - {"(Value).Methods", Method, 26, ""}, - {"(Value).NumField", Method, 0, ""}, - {"(Value).NumMethod", Method, 0, ""}, - {"(Value).OverflowComplex", Method, 0, ""}, - {"(Value).OverflowFloat", Method, 0, ""}, - {"(Value).OverflowInt", Method, 0, ""}, - {"(Value).OverflowUint", Method, 0, ""}, - {"(Value).Pointer", Method, 0, ""}, - {"(Value).Recv", Method, 0, ""}, - {"(Value).Send", Method, 0, ""}, - {"(Value).Seq", Method, 23, ""}, - {"(Value).Seq2", Method, 23, ""}, - {"(Value).Set", Method, 0, ""}, - {"(Value).SetBool", Method, 0, ""}, - {"(Value).SetBytes", Method, 0, ""}, - {"(Value).SetCap", Method, 2, ""}, - {"(Value).SetComplex", Method, 0, ""}, - {"(Value).SetFloat", Method, 0, ""}, - {"(Value).SetInt", Method, 0, ""}, - {"(Value).SetIterKey", Method, 18, ""}, - {"(Value).SetIterValue", Method, 18, ""}, - {"(Value).SetLen", Method, 0, ""}, - {"(Value).SetMapIndex", Method, 0, ""}, - {"(Value).SetPointer", Method, 0, ""}, - {"(Value).SetString", Method, 0, ""}, - {"(Value).SetUint", Method, 0, ""}, - {"(Value).SetZero", Method, 20, ""}, - {"(Value).Slice", Method, 0, ""}, - {"(Value).Slice3", Method, 2, ""}, - {"(Value).String", Method, 0, ""}, - {"(Value).TryRecv", Method, 0, ""}, - {"(Value).TrySend", Method, 0, ""}, - {"(Value).Type", Method, 0, ""}, - {"(Value).Uint", Method, 0, ""}, - {"(Value).UnsafeAddr", Method, 0, ""}, - {"(Value).UnsafePointer", Method, 18, ""}, - {"Append", Func, 0, "func(s Value, x ...Value) Value"}, - {"AppendSlice", Func, 0, "func(s Value, t Value) Value"}, - {"Array", Const, 0, ""}, - {"ArrayOf", Func, 5, "func(length int, elem Type) Type"}, - {"Bool", Const, 0, ""}, - {"BothDir", Const, 0, ""}, - {"Chan", Const, 0, ""}, - {"ChanDir", Type, 0, ""}, - {"ChanOf", Func, 1, "func(dir ChanDir, t Type) Type"}, - {"Complex128", Const, 0, ""}, - {"Complex64", Const, 0, ""}, - {"Copy", Func, 0, "func(dst Value, src Value) int"}, - {"DeepEqual", Func, 0, "func(x any, y any) bool"}, - {"Float32", Const, 0, ""}, - {"Float64", Const, 0, ""}, - {"Func", Const, 0, ""}, - {"FuncOf", Func, 5, "func(in []Type, out []Type, variadic bool) Type"}, - {"Indirect", Func, 0, "func(v Value) Value"}, - {"Int", Const, 0, ""}, - {"Int16", Const, 0, ""}, - {"Int32", Const, 0, ""}, - {"Int64", Const, 0, ""}, - {"Int8", Const, 0, ""}, - {"Interface", Const, 0, ""}, - {"Invalid", Const, 0, ""}, - {"Kind", Type, 0, ""}, - {"MakeChan", Func, 0, "func(typ Type, buffer int) Value"}, - {"MakeFunc", Func, 1, "func(typ Type, fn func(args []Value) (results []Value)) Value"}, - {"MakeMap", Func, 0, "func(typ Type) Value"}, - {"MakeMapWithSize", Func, 9, "func(typ Type, n int) Value"}, - {"MakeSlice", Func, 0, "func(typ Type, len int, cap int) Value"}, - {"Map", Const, 0, ""}, - {"MapIter", Type, 12, ""}, - {"MapOf", Func, 1, "func(key Type, elem Type) Type"}, - {"Method", Type, 0, ""}, - {"Method.Func", Field, 0, ""}, - {"Method.Index", Field, 0, ""}, - {"Method.Name", Field, 0, ""}, - {"Method.PkgPath", Field, 0, ""}, - {"Method.Type", Field, 0, ""}, - {"New", Func, 0, "func(typ Type) Value"}, - {"NewAt", Func, 0, "func(typ Type, p unsafe.Pointer) Value"}, - {"Pointer", Const, 18, ""}, - {"PointerTo", Func, 18, "func(t Type) Type"}, - {"Ptr", Const, 0, ""}, - {"PtrTo", Func, 0, "func(t Type) Type"}, - {"RecvDir", Const, 0, ""}, - {"Select", Func, 1, "func(cases []SelectCase) (chosen int, recv Value, recvOK bool)"}, - {"SelectCase", Type, 1, ""}, - {"SelectCase.Chan", Field, 1, ""}, - {"SelectCase.Dir", Field, 1, ""}, - {"SelectCase.Send", Field, 1, ""}, - {"SelectDefault", Const, 1, ""}, - {"SelectDir", Type, 1, ""}, - {"SelectRecv", Const, 1, ""}, - {"SelectSend", Const, 1, ""}, - {"SendDir", Const, 0, ""}, - {"Slice", Const, 0, ""}, - {"SliceAt", Func, 23, "func(typ Type, p unsafe.Pointer, n int) Value"}, - {"SliceHeader", Type, 0, ""}, - {"SliceHeader.Cap", Field, 0, ""}, - {"SliceHeader.Data", Field, 0, ""}, - {"SliceHeader.Len", Field, 0, ""}, - {"SliceOf", Func, 1, "func(t Type) Type"}, - {"String", Const, 0, ""}, - {"StringHeader", Type, 0, ""}, - {"StringHeader.Data", Field, 0, ""}, - {"StringHeader.Len", Field, 0, ""}, - {"Struct", Const, 0, ""}, - {"StructField", Type, 0, ""}, - {"StructField.Anonymous", Field, 0, ""}, - {"StructField.Index", Field, 0, ""}, - {"StructField.Name", Field, 0, ""}, - {"StructField.Offset", Field, 0, ""}, - {"StructField.PkgPath", Field, 0, ""}, - {"StructField.Tag", Field, 0, ""}, - {"StructField.Type", Field, 0, ""}, - {"StructOf", Func, 7, "func(fields []StructField) Type"}, - {"StructTag", Type, 0, ""}, - {"Swapper", Func, 8, "func(slice any) func(i int, j int)"}, - {"TypeAssert", Func, 25, "func[T any](v Value) (T, bool)"}, - {"TypeFor", Func, 22, "func[T any]() Type"}, - {"TypeOf", Func, 0, "func(i any) Type"}, - {"Uint", Const, 0, ""}, - {"Uint16", Const, 0, ""}, - {"Uint32", Const, 0, ""}, - {"Uint64", Const, 0, ""}, - {"Uint8", Const, 0, ""}, - {"Uintptr", Const, 0, ""}, - {"UnsafePointer", Const, 0, ""}, - {"Value", Type, 0, ""}, - {"ValueError", Type, 0, ""}, - {"ValueError.Kind", Field, 0, ""}, - {"ValueError.Method", Field, 0, ""}, - {"ValueOf", Func, 0, "func(i any) Value"}, - {"VisibleFields", Func, 17, "func(t Type) []StructField"}, - {"Zero", Func, 0, "func(typ Type) Value"}, - }, - "regexp": { - {"(*Regexp).AppendText", Method, 24, ""}, - {"(*Regexp).Copy", Method, 6, ""}, - {"(*Regexp).Expand", Method, 0, ""}, - {"(*Regexp).ExpandString", Method, 0, ""}, - {"(*Regexp).Find", Method, 0, ""}, - {"(*Regexp).FindAll", Method, 0, ""}, - {"(*Regexp).FindAllIndex", Method, 0, ""}, - {"(*Regexp).FindAllString", Method, 0, ""}, - {"(*Regexp).FindAllStringIndex", Method, 0, ""}, - {"(*Regexp).FindAllStringSubmatch", Method, 0, ""}, - {"(*Regexp).FindAllStringSubmatchIndex", Method, 0, ""}, - {"(*Regexp).FindAllSubmatch", Method, 0, ""}, - {"(*Regexp).FindAllSubmatchIndex", Method, 0, ""}, - {"(*Regexp).FindIndex", Method, 0, ""}, - {"(*Regexp).FindReaderIndex", Method, 0, ""}, - {"(*Regexp).FindReaderSubmatchIndex", Method, 0, ""}, - {"(*Regexp).FindString", Method, 0, ""}, - {"(*Regexp).FindStringIndex", Method, 0, ""}, - {"(*Regexp).FindStringSubmatch", Method, 0, ""}, - {"(*Regexp).FindStringSubmatchIndex", Method, 0, ""}, - {"(*Regexp).FindSubmatch", Method, 0, ""}, - {"(*Regexp).FindSubmatchIndex", Method, 0, ""}, - {"(*Regexp).LiteralPrefix", Method, 0, ""}, - {"(*Regexp).Longest", Method, 1, ""}, - {"(*Regexp).MarshalText", Method, 21, ""}, - {"(*Regexp).Match", Method, 0, ""}, - {"(*Regexp).MatchReader", Method, 0, ""}, - {"(*Regexp).MatchString", Method, 0, ""}, - {"(*Regexp).NumSubexp", Method, 0, ""}, - {"(*Regexp).ReplaceAll", Method, 0, ""}, - {"(*Regexp).ReplaceAllFunc", Method, 0, ""}, - {"(*Regexp).ReplaceAllLiteral", Method, 0, ""}, - {"(*Regexp).ReplaceAllLiteralString", Method, 0, ""}, - {"(*Regexp).ReplaceAllString", Method, 0, ""}, - {"(*Regexp).ReplaceAllStringFunc", Method, 0, ""}, - {"(*Regexp).Split", Method, 1, ""}, - {"(*Regexp).String", Method, 0, ""}, - {"(*Regexp).SubexpIndex", Method, 15, ""}, - {"(*Regexp).SubexpNames", Method, 0, ""}, - {"(*Regexp).UnmarshalText", Method, 21, ""}, - {"Compile", Func, 0, "func(expr string) (*Regexp, error)"}, - {"CompilePOSIX", Func, 0, "func(expr string) (*Regexp, error)"}, - {"Match", Func, 0, "func(pattern string, b []byte) (matched bool, err error)"}, - {"MatchReader", Func, 0, "func(pattern string, r io.RuneReader) (matched bool, err error)"}, - {"MatchString", Func, 0, "func(pattern string, s string) (matched bool, err error)"}, - {"MustCompile", Func, 0, "func(str string) *Regexp"}, - {"MustCompilePOSIX", Func, 0, "func(str string) *Regexp"}, - {"QuoteMeta", Func, 0, "func(s string) string"}, - {"Regexp", Type, 0, ""}, - }, - "regexp/syntax": { - {"(*Error).Error", Method, 0, ""}, - {"(*Inst).MatchEmptyWidth", Method, 0, ""}, - {"(*Inst).MatchRune", Method, 0, ""}, - {"(*Inst).MatchRunePos", Method, 3, ""}, - {"(*Inst).String", Method, 0, ""}, - {"(*Prog).Prefix", Method, 0, ""}, - {"(*Prog).StartCond", Method, 0, ""}, - {"(*Prog).String", Method, 0, ""}, - {"(*Regexp).CapNames", Method, 0, ""}, - {"(*Regexp).Equal", Method, 0, ""}, - {"(*Regexp).MaxCap", Method, 0, ""}, - {"(*Regexp).Simplify", Method, 0, ""}, - {"(*Regexp).String", Method, 0, ""}, - {"(ErrorCode).String", Method, 0, ""}, - {"(InstOp).String", Method, 3, ""}, - {"(Op).String", Method, 11, ""}, - {"ClassNL", Const, 0, ""}, - {"Compile", Func, 0, "func(re *Regexp) (*Prog, error)"}, - {"DotNL", Const, 0, ""}, - {"EmptyBeginLine", Const, 0, ""}, - {"EmptyBeginText", Const, 0, ""}, - {"EmptyEndLine", Const, 0, ""}, - {"EmptyEndText", Const, 0, ""}, - {"EmptyNoWordBoundary", Const, 0, ""}, - {"EmptyOp", Type, 0, ""}, - {"EmptyOpContext", Func, 0, "func(r1 rune, r2 rune) EmptyOp"}, - {"EmptyWordBoundary", Const, 0, ""}, - {"ErrInternalError", Const, 0, ""}, - {"ErrInvalidCharClass", Const, 0, ""}, - {"ErrInvalidCharRange", Const, 0, ""}, - {"ErrInvalidEscape", Const, 0, ""}, - {"ErrInvalidNamedCapture", Const, 0, ""}, - {"ErrInvalidPerlOp", Const, 0, ""}, - {"ErrInvalidRepeatOp", Const, 0, ""}, - {"ErrInvalidRepeatSize", Const, 0, ""}, - {"ErrInvalidUTF8", Const, 0, ""}, - {"ErrLarge", Const, 20, ""}, - {"ErrMissingBracket", Const, 0, ""}, - {"ErrMissingParen", Const, 0, ""}, - {"ErrMissingRepeatArgument", Const, 0, ""}, - {"ErrNestingDepth", Const, 19, ""}, - {"ErrTrailingBackslash", Const, 0, ""}, - {"ErrUnexpectedParen", Const, 1, ""}, - {"Error", Type, 0, ""}, - {"Error.Code", Field, 0, ""}, - {"Error.Expr", Field, 0, ""}, - {"ErrorCode", Type, 0, ""}, - {"Flags", Type, 0, ""}, - {"FoldCase", Const, 0, ""}, - {"Inst", Type, 0, ""}, - {"Inst.Arg", Field, 0, ""}, - {"Inst.Op", Field, 0, ""}, - {"Inst.Out", Field, 0, ""}, - {"Inst.Rune", Field, 0, ""}, - {"InstAlt", Const, 0, ""}, - {"InstAltMatch", Const, 0, ""}, - {"InstCapture", Const, 0, ""}, - {"InstEmptyWidth", Const, 0, ""}, - {"InstFail", Const, 0, ""}, - {"InstMatch", Const, 0, ""}, - {"InstNop", Const, 0, ""}, - {"InstOp", Type, 0, ""}, - {"InstRune", Const, 0, ""}, - {"InstRune1", Const, 0, ""}, - {"InstRuneAny", Const, 0, ""}, - {"InstRuneAnyNotNL", Const, 0, ""}, - {"IsWordChar", Func, 0, "func(r rune) bool"}, - {"Literal", Const, 0, ""}, - {"MatchNL", Const, 0, ""}, - {"NonGreedy", Const, 0, ""}, - {"OneLine", Const, 0, ""}, - {"Op", Type, 0, ""}, - {"OpAlternate", Const, 0, ""}, - {"OpAnyChar", Const, 0, ""}, - {"OpAnyCharNotNL", Const, 0, ""}, - {"OpBeginLine", Const, 0, ""}, - {"OpBeginText", Const, 0, ""}, - {"OpCapture", Const, 0, ""}, - {"OpCharClass", Const, 0, ""}, - {"OpConcat", Const, 0, ""}, - {"OpEmptyMatch", Const, 0, ""}, - {"OpEndLine", Const, 0, ""}, - {"OpEndText", Const, 0, ""}, - {"OpLiteral", Const, 0, ""}, - {"OpNoMatch", Const, 0, ""}, - {"OpNoWordBoundary", Const, 0, ""}, - {"OpPlus", Const, 0, ""}, - {"OpQuest", Const, 0, ""}, - {"OpRepeat", Const, 0, ""}, - {"OpStar", Const, 0, ""}, - {"OpWordBoundary", Const, 0, ""}, - {"POSIX", Const, 0, ""}, - {"Parse", Func, 0, "func(s string, flags Flags) (*Regexp, error)"}, - {"Perl", Const, 0, ""}, - {"PerlX", Const, 0, ""}, - {"Prog", Type, 0, ""}, - {"Prog.Inst", Field, 0, ""}, - {"Prog.NumCap", Field, 0, ""}, - {"Prog.Start", Field, 0, ""}, - {"Regexp", Type, 0, ""}, - {"Regexp.Cap", Field, 0, ""}, - {"Regexp.Flags", Field, 0, ""}, - {"Regexp.Max", Field, 0, ""}, - {"Regexp.Min", Field, 0, ""}, - {"Regexp.Name", Field, 0, ""}, - {"Regexp.Op", Field, 0, ""}, - {"Regexp.Rune", Field, 0, ""}, - {"Regexp.Rune0", Field, 0, ""}, - {"Regexp.Sub", Field, 0, ""}, - {"Regexp.Sub0", Field, 0, ""}, - {"Simple", Const, 0, ""}, - {"UnicodeGroups", Const, 0, ""}, - {"WasDollar", Const, 0, ""}, - }, - "runtime": { - {"(*BlockProfileRecord).Stack", Method, 1, ""}, - {"(*Frames).Next", Method, 7, ""}, - {"(*Func).Entry", Method, 0, ""}, - {"(*Func).FileLine", Method, 0, ""}, - {"(*Func).Name", Method, 0, ""}, - {"(*MemProfileRecord).InUseBytes", Method, 0, ""}, - {"(*MemProfileRecord).InUseObjects", Method, 0, ""}, - {"(*MemProfileRecord).Stack", Method, 0, ""}, - {"(*PanicNilError).Error", Method, 21, ""}, - {"(*PanicNilError).RuntimeError", Method, 21, ""}, - {"(*Pinner).Pin", Method, 21, ""}, - {"(*Pinner).Unpin", Method, 21, ""}, - {"(*StackRecord).Stack", Method, 0, ""}, - {"(*TypeAssertionError).Error", Method, 0, ""}, - {"(*TypeAssertionError).RuntimeError", Method, 0, ""}, - {"(Cleanup).Stop", Method, 24, ""}, - {"(Error).Error", Method, 0, ""}, - {"(Error).RuntimeError", Method, 0, ""}, - {"AddCleanup", Func, 24, "func[T, S any](ptr *T, cleanup func(S), arg S) Cleanup"}, - {"BlockProfile", Func, 1, "func(p []BlockProfileRecord) (n int, ok bool)"}, - {"BlockProfileRecord", Type, 1, ""}, - {"BlockProfileRecord.Count", Field, 1, ""}, - {"BlockProfileRecord.Cycles", Field, 1, ""}, - {"BlockProfileRecord.StackRecord", Field, 1, ""}, - {"Breakpoint", Func, 0, "func()"}, - {"CPUProfile", Func, 0, "func() []byte"}, - {"Caller", Func, 0, "func(skip int) (pc uintptr, file string, line int, ok bool)"}, - {"Callers", Func, 0, "func(skip int, pc []uintptr) int"}, - {"CallersFrames", Func, 7, "func(callers []uintptr) *Frames"}, - {"Cleanup", Type, 24, ""}, - {"Compiler", Const, 0, ""}, - {"Error", Type, 0, ""}, - {"Frame", Type, 7, ""}, - {"Frame.Entry", Field, 7, ""}, - {"Frame.File", Field, 7, ""}, - {"Frame.Func", Field, 7, ""}, - {"Frame.Function", Field, 7, ""}, - {"Frame.Line", Field, 7, ""}, - {"Frame.PC", Field, 7, ""}, - {"Frames", Type, 7, ""}, - {"Func", Type, 0, ""}, - {"FuncForPC", Func, 0, "func(pc uintptr) *Func"}, - {"GC", Func, 0, "func()"}, - {"GOARCH", Const, 0, ""}, - {"GOMAXPROCS", Func, 0, "func(n int) int"}, - {"GOOS", Const, 0, ""}, - {"GOROOT", Func, 0, "func() string"}, - {"Goexit", Func, 0, "func()"}, - {"GoroutineProfile", Func, 0, "func(p []StackRecord) (n int, ok bool)"}, - {"Gosched", Func, 0, "func()"}, - {"KeepAlive", Func, 7, "func(x any)"}, - {"LockOSThread", Func, 0, "func()"}, - {"MemProfile", Func, 0, "func(p []MemProfileRecord, inuseZero bool) (n int, ok bool)"}, - {"MemProfileRate", Var, 0, ""}, - {"MemProfileRecord", Type, 0, ""}, - {"MemProfileRecord.AllocBytes", Field, 0, ""}, - {"MemProfileRecord.AllocObjects", Field, 0, ""}, - {"MemProfileRecord.FreeBytes", Field, 0, ""}, - {"MemProfileRecord.FreeObjects", Field, 0, ""}, - {"MemProfileRecord.Stack0", Field, 0, ""}, - {"MemStats", Type, 0, ""}, - {"MemStats.Alloc", Field, 0, ""}, - {"MemStats.BuckHashSys", Field, 0, ""}, - {"MemStats.BySize", Field, 0, ""}, - {"MemStats.DebugGC", Field, 0, ""}, - {"MemStats.EnableGC", Field, 0, ""}, - {"MemStats.Frees", Field, 0, ""}, - {"MemStats.GCCPUFraction", Field, 5, ""}, - {"MemStats.GCSys", Field, 2, ""}, - {"MemStats.HeapAlloc", Field, 0, ""}, - {"MemStats.HeapIdle", Field, 0, ""}, - {"MemStats.HeapInuse", Field, 0, ""}, - {"MemStats.HeapObjects", Field, 0, ""}, - {"MemStats.HeapReleased", Field, 0, ""}, - {"MemStats.HeapSys", Field, 0, ""}, - {"MemStats.LastGC", Field, 0, ""}, - {"MemStats.Lookups", Field, 0, ""}, - {"MemStats.MCacheInuse", Field, 0, ""}, - {"MemStats.MCacheSys", Field, 0, ""}, - {"MemStats.MSpanInuse", Field, 0, ""}, - {"MemStats.MSpanSys", Field, 0, ""}, - {"MemStats.Mallocs", Field, 0, ""}, - {"MemStats.NextGC", Field, 0, ""}, - {"MemStats.NumForcedGC", Field, 8, ""}, - {"MemStats.NumGC", Field, 0, ""}, - {"MemStats.OtherSys", Field, 2, ""}, - {"MemStats.PauseEnd", Field, 4, ""}, - {"MemStats.PauseNs", Field, 0, ""}, - {"MemStats.PauseTotalNs", Field, 0, ""}, - {"MemStats.StackInuse", Field, 0, ""}, - {"MemStats.StackSys", Field, 0, ""}, - {"MemStats.Sys", Field, 0, ""}, - {"MemStats.TotalAlloc", Field, 0, ""}, - {"MutexProfile", Func, 8, "func(p []BlockProfileRecord) (n int, ok bool)"}, - {"NumCPU", Func, 0, "func() int"}, - {"NumCgoCall", Func, 0, "func() int64"}, - {"NumGoroutine", Func, 0, "func() int"}, - {"PanicNilError", Type, 21, ""}, - {"Pinner", Type, 21, ""}, - {"ReadMemStats", Func, 0, "func(m *MemStats)"}, - {"ReadTrace", Func, 5, "func() (buf []byte)"}, - {"SetBlockProfileRate", Func, 1, "func(rate int)"}, - {"SetCPUProfileRate", Func, 0, "func(hz int)"}, - {"SetCgoTraceback", Func, 7, "func(version int, traceback unsafe.Pointer, context unsafe.Pointer, symbolizer unsafe.Pointer)"}, - {"SetDefaultGOMAXPROCS", Func, 25, "func()"}, - {"SetFinalizer", Func, 0, "func(obj any, finalizer any)"}, - {"SetMutexProfileFraction", Func, 8, "func(rate int) int"}, - {"Stack", Func, 0, "func(buf []byte, all bool) int"}, - {"StackRecord", Type, 0, ""}, - {"StackRecord.Stack0", Field, 0, ""}, - {"StartTrace", Func, 5, "func() error"}, - {"StopTrace", Func, 5, "func()"}, - {"ThreadCreateProfile", Func, 0, "func(p []StackRecord) (n int, ok bool)"}, - {"TypeAssertionError", Type, 0, ""}, - {"UnlockOSThread", Func, 0, "func()"}, - {"Version", Func, 0, "func() string"}, - }, - "runtime/cgo": { - {"(Handle).Delete", Method, 17, ""}, - {"(Handle).Value", Method, 17, ""}, - {"Handle", Type, 17, ""}, - {"Incomplete", Type, 20, ""}, - {"NewHandle", Func, 17, ""}, - }, - "runtime/coverage": { - {"ClearCounters", Func, 20, "func() error"}, - {"WriteCounters", Func, 20, "func(w io.Writer) error"}, - {"WriteCountersDir", Func, 20, "func(dir string) error"}, - {"WriteMeta", Func, 20, "func(w io.Writer) error"}, - {"WriteMetaDir", Func, 20, "func(dir string) error"}, - }, - "runtime/debug": { - {"(*BuildInfo).String", Method, 18, ""}, - {"BuildInfo", Type, 12, ""}, - {"BuildInfo.Deps", Field, 12, ""}, - {"BuildInfo.GoVersion", Field, 18, ""}, - {"BuildInfo.Main", Field, 12, ""}, - {"BuildInfo.Path", Field, 12, ""}, - {"BuildInfo.Settings", Field, 18, ""}, - {"BuildSetting", Type, 18, ""}, - {"BuildSetting.Key", Field, 18, ""}, - {"BuildSetting.Value", Field, 18, ""}, - {"CrashOptions", Type, 23, ""}, - {"FreeOSMemory", Func, 1, "func()"}, - {"GCStats", Type, 1, ""}, - {"GCStats.LastGC", Field, 1, ""}, - {"GCStats.NumGC", Field, 1, ""}, - {"GCStats.Pause", Field, 1, ""}, - {"GCStats.PauseEnd", Field, 4, ""}, - {"GCStats.PauseQuantiles", Field, 1, ""}, - {"GCStats.PauseTotal", Field, 1, ""}, - {"Module", Type, 12, ""}, - {"Module.Path", Field, 12, ""}, - {"Module.Replace", Field, 12, ""}, - {"Module.Sum", Field, 12, ""}, - {"Module.Version", Field, 12, ""}, - {"ParseBuildInfo", Func, 18, "func(data string) (bi *BuildInfo, err error)"}, - {"PrintStack", Func, 0, "func()"}, - {"ReadBuildInfo", Func, 12, "func() (info *BuildInfo, ok bool)"}, - {"ReadGCStats", Func, 1, "func(stats *GCStats)"}, - {"SetCrashOutput", Func, 23, "func(f *os.File, opts CrashOptions) error"}, - {"SetGCPercent", Func, 1, "func(percent int) int"}, - {"SetMaxStack", Func, 2, "func(bytes int) int"}, - {"SetMaxThreads", Func, 2, "func(threads int) int"}, - {"SetMemoryLimit", Func, 19, "func(limit int64) int64"}, - {"SetPanicOnFault", Func, 3, "func(enabled bool) bool"}, - {"SetTraceback", Func, 6, "func(level string)"}, - {"Stack", Func, 0, "func() []byte"}, - {"WriteHeapDump", Func, 3, "func(fd uintptr)"}, - }, - "runtime/metrics": { - {"(Value).Float64", Method, 16, ""}, - {"(Value).Float64Histogram", Method, 16, ""}, - {"(Value).Kind", Method, 16, ""}, - {"(Value).Uint64", Method, 16, ""}, - {"All", Func, 16, "func() []Description"}, - {"Description", Type, 16, ""}, - {"Description.Cumulative", Field, 16, ""}, - {"Description.Description", Field, 16, ""}, - {"Description.Kind", Field, 16, ""}, - {"Description.Name", Field, 16, ""}, - {"Float64Histogram", Type, 16, ""}, - {"Float64Histogram.Buckets", Field, 16, ""}, - {"Float64Histogram.Counts", Field, 16, ""}, - {"KindBad", Const, 16, ""}, - {"KindFloat64", Const, 16, ""}, - {"KindFloat64Histogram", Const, 16, ""}, - {"KindUint64", Const, 16, ""}, - {"Read", Func, 16, "func(m []Sample)"}, - {"Sample", Type, 16, ""}, - {"Sample.Name", Field, 16, ""}, - {"Sample.Value", Field, 16, ""}, - {"Value", Type, 16, ""}, - {"ValueKind", Type, 16, ""}, - }, - "runtime/pprof": { - {"(*Profile).Add", Method, 0, ""}, - {"(*Profile).Count", Method, 0, ""}, - {"(*Profile).Name", Method, 0, ""}, - {"(*Profile).Remove", Method, 0, ""}, - {"(*Profile).WriteTo", Method, 0, ""}, - {"Do", Func, 9, "func(ctx context.Context, labels LabelSet, f func(context.Context))"}, - {"ForLabels", Func, 9, "func(ctx context.Context, f func(key string, value string) bool)"}, - {"Label", Func, 9, "func(ctx context.Context, key string) (string, bool)"}, - {"LabelSet", Type, 9, ""}, - {"Labels", Func, 9, "func(args ...string) LabelSet"}, - {"Lookup", Func, 0, "func(name string) *Profile"}, - {"NewProfile", Func, 0, "func(name string) *Profile"}, - {"Profile", Type, 0, ""}, - {"Profiles", Func, 0, "func() []*Profile"}, - {"SetGoroutineLabels", Func, 9, "func(ctx context.Context)"}, - {"StartCPUProfile", Func, 0, "func(w io.Writer) error"}, - {"StopCPUProfile", Func, 0, "func()"}, - {"WithLabels", Func, 9, "func(ctx context.Context, labels LabelSet) context.Context"}, - {"WriteHeapProfile", Func, 0, "func(w io.Writer) error"}, - }, - "runtime/trace": { - {"(*FlightRecorder).Enabled", Method, 25, ""}, - {"(*FlightRecorder).Start", Method, 25, ""}, - {"(*FlightRecorder).Stop", Method, 25, ""}, - {"(*FlightRecorder).WriteTo", Method, 25, ""}, - {"(*Region).End", Method, 11, ""}, - {"(*Task).End", Method, 11, ""}, - {"FlightRecorder", Type, 25, ""}, - {"FlightRecorderConfig", Type, 25, ""}, - {"FlightRecorderConfig.MaxBytes", Field, 25, ""}, - {"FlightRecorderConfig.MinAge", Field, 25, ""}, - {"IsEnabled", Func, 11, "func() bool"}, - {"Log", Func, 11, "func(ctx context.Context, category string, message string)"}, - {"Logf", Func, 11, "func(ctx context.Context, category string, format string, args ...any)"}, - {"NewFlightRecorder", Func, 25, "func(cfg FlightRecorderConfig) *FlightRecorder"}, - {"NewTask", Func, 11, "func(pctx context.Context, taskType string) (ctx context.Context, task *Task)"}, - {"Region", Type, 11, ""}, - {"Start", Func, 5, "func(w io.Writer) error"}, - {"StartRegion", Func, 11, "func(ctx context.Context, regionType string) *Region"}, - {"Stop", Func, 5, "func()"}, - {"Task", Type, 11, ""}, - {"WithRegion", Func, 11, "func(ctx context.Context, regionType string, fn func())"}, - }, - "slices": { - {"All", Func, 23, "func[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]"}, - {"AppendSeq", Func, 23, "func[Slice ~[]E, E any](s Slice, seq iter.Seq[E]) Slice"}, - {"Backward", Func, 23, "func[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]"}, - {"BinarySearch", Func, 21, "func[S ~[]E, E cmp.Ordered](x S, target E) (int, bool)"}, - {"BinarySearchFunc", Func, 21, "func[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool)"}, - {"Chunk", Func, 23, "func[Slice ~[]E, E any](s Slice, n int) iter.Seq[Slice]"}, - {"Clip", Func, 21, "func[S ~[]E, E any](s S) S"}, - {"Clone", Func, 21, "func[S ~[]E, E any](s S) S"}, - {"Collect", Func, 23, "func[E any](seq iter.Seq[E]) []E"}, - {"Compact", Func, 21, "func[S ~[]E, E comparable](s S) S"}, - {"CompactFunc", Func, 21, "func[S ~[]E, E any](s S, eq func(E, E) bool) S"}, - {"Compare", Func, 21, "func[S ~[]E, E cmp.Ordered](s1 S, s2 S) int"}, - {"CompareFunc", Func, 21, "func[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int"}, - {"Concat", Func, 22, "func[S ~[]E, E any](slices ...S) S"}, - {"Contains", Func, 21, "func[S ~[]E, E comparable](s S, v E) bool"}, - {"ContainsFunc", Func, 21, "func[S ~[]E, E any](s S, f func(E) bool) bool"}, - {"Delete", Func, 21, "func[S ~[]E, E any](s S, i int, j int) S"}, - {"DeleteFunc", Func, 21, "func[S ~[]E, E any](s S, del func(E) bool) S"}, - {"Equal", Func, 21, "func[S ~[]E, E comparable](s1 S, s2 S) bool"}, - {"EqualFunc", Func, 21, "func[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool"}, - {"Grow", Func, 21, "func[S ~[]E, E any](s S, n int) S"}, - {"Index", Func, 21, "func[S ~[]E, E comparable](s S, v E) int"}, - {"IndexFunc", Func, 21, "func[S ~[]E, E any](s S, f func(E) bool) int"}, - {"Insert", Func, 21, "func[S ~[]E, E any](s S, i int, v ...E) S"}, - {"IsSorted", Func, 21, "func[S ~[]E, E cmp.Ordered](x S) bool"}, - {"IsSortedFunc", Func, 21, "func[S ~[]E, E any](x S, cmp func(a E, b E) int) bool"}, - {"Max", Func, 21, "func[S ~[]E, E cmp.Ordered](x S) E"}, - {"MaxFunc", Func, 21, "func[S ~[]E, E any](x S, cmp func(a E, b E) int) E"}, - {"Min", Func, 21, "func[S ~[]E, E cmp.Ordered](x S) E"}, - {"MinFunc", Func, 21, "func[S ~[]E, E any](x S, cmp func(a E, b E) int) E"}, - {"Repeat", Func, 23, "func[S ~[]E, E any](x S, count int) S"}, - {"Replace", Func, 21, "func[S ~[]E, E any](s S, i int, j int, v ...E) S"}, - {"Reverse", Func, 21, "func[S ~[]E, E any](s S)"}, - {"Sort", Func, 21, "func[S ~[]E, E cmp.Ordered](x S)"}, - {"SortFunc", Func, 21, "func[S ~[]E, E any](x S, cmp func(a E, b E) int)"}, - {"SortStableFunc", Func, 21, "func[S ~[]E, E any](x S, cmp func(a E, b E) int)"}, - {"Sorted", Func, 23, "func[E cmp.Ordered](seq iter.Seq[E]) []E"}, - {"SortedFunc", Func, 23, "func[E any](seq iter.Seq[E], cmp func(E, E) int) []E"}, - {"SortedStableFunc", Func, 23, "func[E any](seq iter.Seq[E], cmp func(E, E) int) []E"}, - {"Values", Func, 23, "func[Slice ~[]E, E any](s Slice) iter.Seq[E]"}, - }, - "sort": { - {"(Float64Slice).Len", Method, 0, ""}, - {"(Float64Slice).Less", Method, 0, ""}, - {"(Float64Slice).Search", Method, 0, ""}, - {"(Float64Slice).Sort", Method, 0, ""}, - {"(Float64Slice).Swap", Method, 0, ""}, - {"(IntSlice).Len", Method, 0, ""}, - {"(IntSlice).Less", Method, 0, ""}, - {"(IntSlice).Search", Method, 0, ""}, - {"(IntSlice).Sort", Method, 0, ""}, - {"(IntSlice).Swap", Method, 0, ""}, - {"(Interface).Len", Method, 0, ""}, - {"(Interface).Less", Method, 0, ""}, - {"(Interface).Swap", Method, 0, ""}, - {"(StringSlice).Len", Method, 0, ""}, - {"(StringSlice).Less", Method, 0, ""}, - {"(StringSlice).Search", Method, 0, ""}, - {"(StringSlice).Sort", Method, 0, ""}, - {"(StringSlice).Swap", Method, 0, ""}, - {"Find", Func, 19, "func(n int, cmp func(int) int) (i int, found bool)"}, - {"Float64Slice", Type, 0, ""}, - {"Float64s", Func, 0, "func(x []float64)"}, - {"Float64sAreSorted", Func, 0, "func(x []float64) bool"}, - {"IntSlice", Type, 0, ""}, - {"Interface", Type, 0, ""}, - {"Ints", Func, 0, "func(x []int)"}, - {"IntsAreSorted", Func, 0, "func(x []int) bool"}, - {"IsSorted", Func, 0, "func(data Interface) bool"}, - {"Reverse", Func, 1, "func(data Interface) Interface"}, - {"Search", Func, 0, "func(n int, f func(int) bool) int"}, - {"SearchFloat64s", Func, 0, "func(a []float64, x float64) int"}, - {"SearchInts", Func, 0, "func(a []int, x int) int"}, - {"SearchStrings", Func, 0, "func(a []string, x string) int"}, - {"Slice", Func, 8, "func(x any, less func(i int, j int) bool)"}, - {"SliceIsSorted", Func, 8, "func(x any, less func(i int, j int) bool) bool"}, - {"SliceStable", Func, 8, "func(x any, less func(i int, j int) bool)"}, - {"Sort", Func, 0, "func(data Interface)"}, - {"Stable", Func, 2, "func(data Interface)"}, - {"StringSlice", Type, 0, ""}, - {"Strings", Func, 0, "func(x []string)"}, - {"StringsAreSorted", Func, 0, "func(x []string) bool"}, - }, - "strconv": { - {"(*NumError).Error", Method, 0, ""}, - {"(*NumError).Unwrap", Method, 14, ""}, - {"AppendBool", Func, 0, "func(dst []byte, b bool) []byte"}, - {"AppendFloat", Func, 0, "func(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte"}, - {"AppendInt", Func, 0, "func(dst []byte, i int64, base int) []byte"}, - {"AppendQuote", Func, 0, "func(dst []byte, s string) []byte"}, - {"AppendQuoteRune", Func, 0, "func(dst []byte, r rune) []byte"}, - {"AppendQuoteRuneToASCII", Func, 0, "func(dst []byte, r rune) []byte"}, - {"AppendQuoteRuneToGraphic", Func, 6, "func(dst []byte, r rune) []byte"}, - {"AppendQuoteToASCII", Func, 0, "func(dst []byte, s string) []byte"}, - {"AppendQuoteToGraphic", Func, 6, "func(dst []byte, s string) []byte"}, - {"AppendUint", Func, 0, "func(dst []byte, i uint64, base int) []byte"}, - {"Atoi", Func, 0, "func(s string) (int, error)"}, - {"CanBackquote", Func, 0, "func(s string) bool"}, - {"ErrRange", Var, 0, ""}, - {"ErrSyntax", Var, 0, ""}, - {"FormatBool", Func, 0, "func(b bool) string"}, - {"FormatComplex", Func, 15, "func(c complex128, fmt byte, prec int, bitSize int) string"}, - {"FormatFloat", Func, 0, "func(f float64, fmt byte, prec int, bitSize int) string"}, - {"FormatInt", Func, 0, "func(i int64, base int) string"}, - {"FormatUint", Func, 0, "func(i uint64, base int) string"}, - {"IntSize", Const, 0, ""}, - {"IsGraphic", Func, 6, "func(r rune) bool"}, - {"IsPrint", Func, 0, "func(r rune) bool"}, - {"Itoa", Func, 0, "func(i int) string"}, - {"NumError", Type, 0, ""}, - {"NumError.Err", Field, 0, ""}, - {"NumError.Func", Field, 0, ""}, - {"NumError.Num", Field, 0, ""}, - {"ParseBool", Func, 0, "func(str string) (bool, error)"}, - {"ParseComplex", Func, 15, "func(s string, bitSize int) (complex128, error)"}, - {"ParseFloat", Func, 0, "func(s string, bitSize int) (float64, error)"}, - {"ParseInt", Func, 0, "func(s string, base int, bitSize int) (i int64, err error)"}, - {"ParseUint", Func, 0, "func(s string, base int, bitSize int) (uint64, error)"}, - {"Quote", Func, 0, "func(s string) string"}, - {"QuoteRune", Func, 0, "func(r rune) string"}, - {"QuoteRuneToASCII", Func, 0, "func(r rune) string"}, - {"QuoteRuneToGraphic", Func, 6, "func(r rune) string"}, - {"QuoteToASCII", Func, 0, "func(s string) string"}, - {"QuoteToGraphic", Func, 6, "func(s string) string"}, - {"QuotedPrefix", Func, 17, "func(s string) (string, error)"}, - {"Unquote", Func, 0, "func(s string) (string, error)"}, - {"UnquoteChar", Func, 0, "func(s string, quote byte) (value rune, multibyte bool, tail string, err error)"}, - }, - "strings": { - {"(*Builder).Cap", Method, 12, ""}, - {"(*Builder).Grow", Method, 10, ""}, - {"(*Builder).Len", Method, 10, ""}, - {"(*Builder).Reset", Method, 10, ""}, - {"(*Builder).String", Method, 10, ""}, - {"(*Builder).Write", Method, 10, ""}, - {"(*Builder).WriteByte", Method, 10, ""}, - {"(*Builder).WriteRune", Method, 10, ""}, - {"(*Builder).WriteString", Method, 10, ""}, - {"(*Reader).Len", Method, 0, ""}, - {"(*Reader).Read", Method, 0, ""}, - {"(*Reader).ReadAt", Method, 0, ""}, - {"(*Reader).ReadByte", Method, 0, ""}, - {"(*Reader).ReadRune", Method, 0, ""}, - {"(*Reader).Reset", Method, 7, ""}, - {"(*Reader).Seek", Method, 0, ""}, - {"(*Reader).Size", Method, 5, ""}, - {"(*Reader).UnreadByte", Method, 0, ""}, - {"(*Reader).UnreadRune", Method, 0, ""}, - {"(*Reader).WriteTo", Method, 1, ""}, - {"(*Replacer).Replace", Method, 0, ""}, - {"(*Replacer).WriteString", Method, 0, ""}, - {"Builder", Type, 10, ""}, - {"Clone", Func, 18, "func(s string) string"}, - {"Compare", Func, 5, "func(a string, b string) int"}, - {"Contains", Func, 0, "func(s string, substr string) bool"}, - {"ContainsAny", Func, 0, "func(s string, chars string) bool"}, - {"ContainsFunc", Func, 21, "func(s string, f func(rune) bool) bool"}, - {"ContainsRune", Func, 0, "func(s string, r rune) bool"}, - {"Count", Func, 0, "func(s string, substr string) int"}, - {"Cut", Func, 18, "func(s string, sep string) (before string, after string, found bool)"}, - {"CutPrefix", Func, 20, "func(s string, prefix string) (after string, found bool)"}, - {"CutSuffix", Func, 20, "func(s string, suffix string) (before string, found bool)"}, - {"EqualFold", Func, 0, "func(s string, t string) bool"}, - {"Fields", Func, 0, "func(s string) []string"}, - {"FieldsFunc", Func, 0, "func(s string, f func(rune) bool) []string"}, - {"FieldsFuncSeq", Func, 24, "func(s string, f func(rune) bool) iter.Seq[string]"}, - {"FieldsSeq", Func, 24, "func(s string) iter.Seq[string]"}, - {"HasPrefix", Func, 0, "func(s string, prefix string) bool"}, - {"HasSuffix", Func, 0, "func(s string, suffix string) bool"}, - {"Index", Func, 0, "func(s string, substr string) int"}, - {"IndexAny", Func, 0, "func(s string, chars string) int"}, - {"IndexByte", Func, 2, "func(s string, c byte) int"}, - {"IndexFunc", Func, 0, "func(s string, f func(rune) bool) int"}, - {"IndexRune", Func, 0, "func(s string, r rune) int"}, - {"Join", Func, 0, "func(elems []string, sep string) string"}, - {"LastIndex", Func, 0, "func(s string, substr string) int"}, - {"LastIndexAny", Func, 0, "func(s string, chars string) int"}, - {"LastIndexByte", Func, 5, "func(s string, c byte) int"}, - {"LastIndexFunc", Func, 0, "func(s string, f func(rune) bool) int"}, - {"Lines", Func, 24, "func(s string) iter.Seq[string]"}, - {"Map", Func, 0, "func(mapping func(rune) rune, s string) string"}, - {"NewReader", Func, 0, "func(s string) *Reader"}, - {"NewReplacer", Func, 0, "func(oldnew ...string) *Replacer"}, - {"Reader", Type, 0, ""}, - {"Repeat", Func, 0, "func(s string, count int) string"}, - {"Replace", Func, 0, "func(s string, old string, new string, n int) string"}, - {"ReplaceAll", Func, 12, "func(s string, old string, new string) string"}, - {"Replacer", Type, 0, ""}, - {"Split", Func, 0, "func(s string, sep string) []string"}, - {"SplitAfter", Func, 0, "func(s string, sep string) []string"}, - {"SplitAfterN", Func, 0, "func(s string, sep string, n int) []string"}, - {"SplitAfterSeq", Func, 24, "func(s string, sep string) iter.Seq[string]"}, - {"SplitN", Func, 0, "func(s string, sep string, n int) []string"}, - {"SplitSeq", Func, 24, "func(s string, sep string) iter.Seq[string]"}, - {"Title", Func, 0, "func(s string) string"}, - {"ToLower", Func, 0, "func(s string) string"}, - {"ToLowerSpecial", Func, 0, "func(c unicode.SpecialCase, s string) string"}, - {"ToTitle", Func, 0, "func(s string) string"}, - {"ToTitleSpecial", Func, 0, "func(c unicode.SpecialCase, s string) string"}, - {"ToUpper", Func, 0, "func(s string) string"}, - {"ToUpperSpecial", Func, 0, "func(c unicode.SpecialCase, s string) string"}, - {"ToValidUTF8", Func, 13, "func(s string, replacement string) string"}, - {"Trim", Func, 0, "func(s string, cutset string) string"}, - {"TrimFunc", Func, 0, "func(s string, f func(rune) bool) string"}, - {"TrimLeft", Func, 0, "func(s string, cutset string) string"}, - {"TrimLeftFunc", Func, 0, "func(s string, f func(rune) bool) string"}, - {"TrimPrefix", Func, 1, "func(s string, prefix string) string"}, - {"TrimRight", Func, 0, "func(s string, cutset string) string"}, - {"TrimRightFunc", Func, 0, "func(s string, f func(rune) bool) string"}, - {"TrimSpace", Func, 0, "func(s string) string"}, - {"TrimSuffix", Func, 1, "func(s string, suffix string) string"}, - }, - "structs": { - {"HostLayout", Type, 23, ""}, - }, - "sync": { - {"(*Cond).Broadcast", Method, 0, ""}, - {"(*Cond).Signal", Method, 0, ""}, - {"(*Cond).Wait", Method, 0, ""}, - {"(*Map).Clear", Method, 23, ""}, - {"(*Map).CompareAndDelete", Method, 20, ""}, - {"(*Map).CompareAndSwap", Method, 20, ""}, - {"(*Map).Delete", Method, 9, ""}, - {"(*Map).Load", Method, 9, ""}, - {"(*Map).LoadAndDelete", Method, 15, ""}, - {"(*Map).LoadOrStore", Method, 9, ""}, - {"(*Map).Range", Method, 9, ""}, - {"(*Map).Store", Method, 9, ""}, - {"(*Map).Swap", Method, 20, ""}, - {"(*Mutex).Lock", Method, 0, ""}, - {"(*Mutex).TryLock", Method, 18, ""}, - {"(*Mutex).Unlock", Method, 0, ""}, - {"(*Once).Do", Method, 0, ""}, - {"(*Pool).Get", Method, 3, ""}, - {"(*Pool).Put", Method, 3, ""}, - {"(*RWMutex).Lock", Method, 0, ""}, - {"(*RWMutex).RLock", Method, 0, ""}, - {"(*RWMutex).RLocker", Method, 0, ""}, - {"(*RWMutex).RUnlock", Method, 0, ""}, - {"(*RWMutex).TryLock", Method, 18, ""}, - {"(*RWMutex).TryRLock", Method, 18, ""}, - {"(*RWMutex).Unlock", Method, 0, ""}, - {"(*WaitGroup).Add", Method, 0, ""}, - {"(*WaitGroup).Done", Method, 0, ""}, - {"(*WaitGroup).Go", Method, 25, ""}, - {"(*WaitGroup).Wait", Method, 0, ""}, - {"(Locker).Lock", Method, 0, ""}, - {"(Locker).Unlock", Method, 0, ""}, - {"Cond", Type, 0, ""}, - {"Cond.L", Field, 0, ""}, - {"Locker", Type, 0, ""}, - {"Map", Type, 9, ""}, - {"Mutex", Type, 0, ""}, - {"NewCond", Func, 0, "func(l Locker) *Cond"}, - {"Once", Type, 0, ""}, - {"OnceFunc", Func, 21, "func(f func()) func()"}, - {"OnceValue", Func, 21, "func[T any](f func() T) func() T"}, - {"OnceValues", Func, 21, "func[T1, T2 any](f func() (T1, T2)) func() (T1, T2)"}, - {"Pool", Type, 3, ""}, - {"Pool.New", Field, 3, ""}, - {"RWMutex", Type, 0, ""}, - {"WaitGroup", Type, 0, ""}, - }, - "sync/atomic": { - {"(*Bool).CompareAndSwap", Method, 19, ""}, - {"(*Bool).Load", Method, 19, ""}, - {"(*Bool).Store", Method, 19, ""}, - {"(*Bool).Swap", Method, 19, ""}, - {"(*Int32).Add", Method, 19, ""}, - {"(*Int32).And", Method, 23, ""}, - {"(*Int32).CompareAndSwap", Method, 19, ""}, - {"(*Int32).Load", Method, 19, ""}, - {"(*Int32).Or", Method, 23, ""}, - {"(*Int32).Store", Method, 19, ""}, - {"(*Int32).Swap", Method, 19, ""}, - {"(*Int64).Add", Method, 19, ""}, - {"(*Int64).And", Method, 23, ""}, - {"(*Int64).CompareAndSwap", Method, 19, ""}, - {"(*Int64).Load", Method, 19, ""}, - {"(*Int64).Or", Method, 23, ""}, - {"(*Int64).Store", Method, 19, ""}, - {"(*Int64).Swap", Method, 19, ""}, - {"(*Pointer).CompareAndSwap", Method, 19, ""}, - {"(*Pointer).Load", Method, 19, ""}, - {"(*Pointer).Store", Method, 19, ""}, - {"(*Pointer).Swap", Method, 19, ""}, - {"(*Uint32).Add", Method, 19, ""}, - {"(*Uint32).And", Method, 23, ""}, - {"(*Uint32).CompareAndSwap", Method, 19, ""}, - {"(*Uint32).Load", Method, 19, ""}, - {"(*Uint32).Or", Method, 23, ""}, - {"(*Uint32).Store", Method, 19, ""}, - {"(*Uint32).Swap", Method, 19, ""}, - {"(*Uint64).Add", Method, 19, ""}, - {"(*Uint64).And", Method, 23, ""}, - {"(*Uint64).CompareAndSwap", Method, 19, ""}, - {"(*Uint64).Load", Method, 19, ""}, - {"(*Uint64).Or", Method, 23, ""}, - {"(*Uint64).Store", Method, 19, ""}, - {"(*Uint64).Swap", Method, 19, ""}, - {"(*Uintptr).Add", Method, 19, ""}, - {"(*Uintptr).And", Method, 23, ""}, - {"(*Uintptr).CompareAndSwap", Method, 19, ""}, - {"(*Uintptr).Load", Method, 19, ""}, - {"(*Uintptr).Or", Method, 23, ""}, - {"(*Uintptr).Store", Method, 19, ""}, - {"(*Uintptr).Swap", Method, 19, ""}, - {"(*Value).CompareAndSwap", Method, 17, ""}, - {"(*Value).Load", Method, 4, ""}, - {"(*Value).Store", Method, 4, ""}, - {"(*Value).Swap", Method, 17, ""}, - {"AddInt32", Func, 0, "func(addr *int32, delta int32) (new int32)"}, - {"AddInt64", Func, 0, "func(addr *int64, delta int64) (new int64)"}, - {"AddUint32", Func, 0, "func(addr *uint32, delta uint32) (new uint32)"}, - {"AddUint64", Func, 0, "func(addr *uint64, delta uint64) (new uint64)"}, - {"AddUintptr", Func, 0, "func(addr *uintptr, delta uintptr) (new uintptr)"}, - {"AndInt32", Func, 23, "func(addr *int32, mask int32) (old int32)"}, - {"AndInt64", Func, 23, "func(addr *int64, mask int64) (old int64)"}, - {"AndUint32", Func, 23, "func(addr *uint32, mask uint32) (old uint32)"}, - {"AndUint64", Func, 23, "func(addr *uint64, mask uint64) (old uint64)"}, - {"AndUintptr", Func, 23, "func(addr *uintptr, mask uintptr) (old uintptr)"}, - {"Bool", Type, 19, ""}, - {"CompareAndSwapInt32", Func, 0, "func(addr *int32, old int32, new int32) (swapped bool)"}, - {"CompareAndSwapInt64", Func, 0, "func(addr *int64, old int64, new int64) (swapped bool)"}, - {"CompareAndSwapPointer", Func, 0, "func(addr *unsafe.Pointer, old unsafe.Pointer, new unsafe.Pointer) (swapped bool)"}, - {"CompareAndSwapUint32", Func, 0, "func(addr *uint32, old uint32, new uint32) (swapped bool)"}, - {"CompareAndSwapUint64", Func, 0, "func(addr *uint64, old uint64, new uint64) (swapped bool)"}, - {"CompareAndSwapUintptr", Func, 0, "func(addr *uintptr, old uintptr, new uintptr) (swapped bool)"}, - {"Int32", Type, 19, ""}, - {"Int64", Type, 19, ""}, - {"LoadInt32", Func, 0, "func(addr *int32) (val int32)"}, - {"LoadInt64", Func, 0, "func(addr *int64) (val int64)"}, - {"LoadPointer", Func, 0, "func(addr *unsafe.Pointer) (val unsafe.Pointer)"}, - {"LoadUint32", Func, 0, "func(addr *uint32) (val uint32)"}, - {"LoadUint64", Func, 0, "func(addr *uint64) (val uint64)"}, - {"LoadUintptr", Func, 0, "func(addr *uintptr) (val uintptr)"}, - {"OrInt32", Func, 23, "func(addr *int32, mask int32) (old int32)"}, - {"OrInt64", Func, 23, "func(addr *int64, mask int64) (old int64)"}, - {"OrUint32", Func, 23, "func(addr *uint32, mask uint32) (old uint32)"}, - {"OrUint64", Func, 23, "func(addr *uint64, mask uint64) (old uint64)"}, - {"OrUintptr", Func, 23, "func(addr *uintptr, mask uintptr) (old uintptr)"}, - {"Pointer", Type, 19, ""}, - {"StoreInt32", Func, 0, "func(addr *int32, val int32)"}, - {"StoreInt64", Func, 0, "func(addr *int64, val int64)"}, - {"StorePointer", Func, 0, "func(addr *unsafe.Pointer, val unsafe.Pointer)"}, - {"StoreUint32", Func, 0, "func(addr *uint32, val uint32)"}, - {"StoreUint64", Func, 0, "func(addr *uint64, val uint64)"}, - {"StoreUintptr", Func, 0, "func(addr *uintptr, val uintptr)"}, - {"SwapInt32", Func, 2, "func(addr *int32, new int32) (old int32)"}, - {"SwapInt64", Func, 2, "func(addr *int64, new int64) (old int64)"}, - {"SwapPointer", Func, 2, "func(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)"}, - {"SwapUint32", Func, 2, "func(addr *uint32, new uint32) (old uint32)"}, - {"SwapUint64", Func, 2, "func(addr *uint64, new uint64) (old uint64)"}, - {"SwapUintptr", Func, 2, "func(addr *uintptr, new uintptr) (old uintptr)"}, - {"Uint32", Type, 19, ""}, - {"Uint64", Type, 19, ""}, - {"Uintptr", Type, 19, ""}, - {"Value", Type, 4, ""}, - }, - "syscall": { - {"(*Cmsghdr).SetLen", Method, 0, ""}, - {"(*DLL).FindProc", Method, 0, ""}, - {"(*DLL).MustFindProc", Method, 0, ""}, - {"(*DLL).Release", Method, 0, ""}, - {"(*DLLError).Error", Method, 0, ""}, - {"(*DLLError).Unwrap", Method, 16, ""}, - {"(*Filetime).Nanoseconds", Method, 0, ""}, - {"(*Iovec).SetLen", Method, 0, ""}, - {"(*LazyDLL).Handle", Method, 0, ""}, - {"(*LazyDLL).Load", Method, 0, ""}, - {"(*LazyDLL).NewProc", Method, 0, ""}, - {"(*LazyProc).Addr", Method, 0, ""}, - {"(*LazyProc).Call", Method, 0, ""}, - {"(*LazyProc).Find", Method, 0, ""}, - {"(*Msghdr).SetControllen", Method, 0, ""}, - {"(*Proc).Addr", Method, 0, ""}, - {"(*Proc).Call", Method, 0, ""}, - {"(*PtraceRegs).PC", Method, 0, ""}, - {"(*PtraceRegs).SetPC", Method, 0, ""}, - {"(*RawSockaddrAny).Sockaddr", Method, 0, ""}, - {"(*SID).Copy", Method, 0, ""}, - {"(*SID).Len", Method, 0, ""}, - {"(*SID).LookupAccount", Method, 0, ""}, - {"(*SID).String", Method, 0, ""}, - {"(*Timespec).Nano", Method, 0, ""}, - {"(*Timespec).Unix", Method, 0, ""}, - {"(*Timeval).Nano", Method, 0, ""}, - {"(*Timeval).Nanoseconds", Method, 0, ""}, - {"(*Timeval).Unix", Method, 0, ""}, - {"(Conn).SyscallConn", Method, 9, ""}, - {"(Errno).Error", Method, 0, ""}, - {"(Errno).Is", Method, 13, ""}, - {"(Errno).Temporary", Method, 0, ""}, - {"(Errno).Timeout", Method, 0, ""}, - {"(RawConn).Control", Method, 9, ""}, - {"(RawConn).Read", Method, 9, ""}, - {"(RawConn).Write", Method, 9, ""}, - {"(Signal).Signal", Method, 0, ""}, - {"(Signal).String", Method, 0, ""}, - {"(Token).Close", Method, 0, ""}, - {"(Token).GetTokenPrimaryGroup", Method, 0, ""}, - {"(Token).GetTokenUser", Method, 0, ""}, - {"(Token).GetUserProfileDirectory", Method, 0, ""}, - {"(WaitStatus).Continued", Method, 0, ""}, - {"(WaitStatus).CoreDump", Method, 0, ""}, - {"(WaitStatus).ExitStatus", Method, 0, ""}, - {"(WaitStatus).Exited", Method, 0, ""}, - {"(WaitStatus).Signal", Method, 0, ""}, - {"(WaitStatus).Signaled", Method, 0, ""}, - {"(WaitStatus).StopSignal", Method, 0, ""}, - {"(WaitStatus).Stopped", Method, 0, ""}, - {"(WaitStatus).TrapCause", Method, 0, ""}, - {"AF_ALG", Const, 0, ""}, - {"AF_APPLETALK", Const, 0, ""}, - {"AF_ARP", Const, 0, ""}, - {"AF_ASH", Const, 0, ""}, - {"AF_ATM", Const, 0, ""}, - {"AF_ATMPVC", Const, 0, ""}, - {"AF_ATMSVC", Const, 0, ""}, - {"AF_AX25", Const, 0, ""}, - {"AF_BLUETOOTH", Const, 0, ""}, - {"AF_BRIDGE", Const, 0, ""}, - {"AF_CAIF", Const, 0, ""}, - {"AF_CAN", Const, 0, ""}, - {"AF_CCITT", Const, 0, ""}, - {"AF_CHAOS", Const, 0, ""}, - {"AF_CNT", Const, 0, ""}, - {"AF_COIP", Const, 0, ""}, - {"AF_DATAKIT", Const, 0, ""}, - {"AF_DECnet", Const, 0, ""}, - {"AF_DLI", Const, 0, ""}, - {"AF_E164", Const, 0, ""}, - {"AF_ECMA", Const, 0, ""}, - {"AF_ECONET", Const, 0, ""}, - {"AF_ENCAP", Const, 1, ""}, - {"AF_FILE", Const, 0, ""}, - {"AF_HYLINK", Const, 0, ""}, - {"AF_IEEE80211", Const, 0, ""}, - {"AF_IEEE802154", Const, 0, ""}, - {"AF_IMPLINK", Const, 0, ""}, - {"AF_INET", Const, 0, ""}, - {"AF_INET6", Const, 0, ""}, - {"AF_INET6_SDP", Const, 3, ""}, - {"AF_INET_SDP", Const, 3, ""}, - {"AF_IPX", Const, 0, ""}, - {"AF_IRDA", Const, 0, ""}, - {"AF_ISDN", Const, 0, ""}, - {"AF_ISO", Const, 0, ""}, - {"AF_IUCV", Const, 0, ""}, - {"AF_KEY", Const, 0, ""}, - {"AF_LAT", Const, 0, ""}, - {"AF_LINK", Const, 0, ""}, - {"AF_LLC", Const, 0, ""}, - {"AF_LOCAL", Const, 0, ""}, - {"AF_MAX", Const, 0, ""}, - {"AF_MPLS", Const, 1, ""}, - {"AF_NATM", Const, 0, ""}, - {"AF_NDRV", Const, 0, ""}, - {"AF_NETBEUI", Const, 0, ""}, - {"AF_NETBIOS", Const, 0, ""}, - {"AF_NETGRAPH", Const, 0, ""}, - {"AF_NETLINK", Const, 0, ""}, - {"AF_NETROM", Const, 0, ""}, - {"AF_NS", Const, 0, ""}, - {"AF_OROUTE", Const, 1, ""}, - {"AF_OSI", Const, 0, ""}, - {"AF_PACKET", Const, 0, ""}, - {"AF_PHONET", Const, 0, ""}, - {"AF_PPP", Const, 0, ""}, - {"AF_PPPOX", Const, 0, ""}, - {"AF_PUP", Const, 0, ""}, - {"AF_RDS", Const, 0, ""}, - {"AF_RESERVED_36", Const, 0, ""}, - {"AF_ROSE", Const, 0, ""}, - {"AF_ROUTE", Const, 0, ""}, - {"AF_RXRPC", Const, 0, ""}, - {"AF_SCLUSTER", Const, 0, ""}, - {"AF_SECURITY", Const, 0, ""}, - {"AF_SIP", Const, 0, ""}, - {"AF_SLOW", Const, 0, ""}, - {"AF_SNA", Const, 0, ""}, - {"AF_SYSTEM", Const, 0, ""}, - {"AF_TIPC", Const, 0, ""}, - {"AF_UNIX", Const, 0, ""}, - {"AF_UNSPEC", Const, 0, ""}, - {"AF_UTUN", Const, 16, ""}, - {"AF_VENDOR00", Const, 0, ""}, - {"AF_VENDOR01", Const, 0, ""}, - {"AF_VENDOR02", Const, 0, ""}, - {"AF_VENDOR03", Const, 0, ""}, - {"AF_VENDOR04", Const, 0, ""}, - {"AF_VENDOR05", Const, 0, ""}, - {"AF_VENDOR06", Const, 0, ""}, - {"AF_VENDOR07", Const, 0, ""}, - {"AF_VENDOR08", Const, 0, ""}, - {"AF_VENDOR09", Const, 0, ""}, - {"AF_VENDOR10", Const, 0, ""}, - {"AF_VENDOR11", Const, 0, ""}, - {"AF_VENDOR12", Const, 0, ""}, - {"AF_VENDOR13", Const, 0, ""}, - {"AF_VENDOR14", Const, 0, ""}, - {"AF_VENDOR15", Const, 0, ""}, - {"AF_VENDOR16", Const, 0, ""}, - {"AF_VENDOR17", Const, 0, ""}, - {"AF_VENDOR18", Const, 0, ""}, - {"AF_VENDOR19", Const, 0, ""}, - {"AF_VENDOR20", Const, 0, ""}, - {"AF_VENDOR21", Const, 0, ""}, - {"AF_VENDOR22", Const, 0, ""}, - {"AF_VENDOR23", Const, 0, ""}, - {"AF_VENDOR24", Const, 0, ""}, - {"AF_VENDOR25", Const, 0, ""}, - {"AF_VENDOR26", Const, 0, ""}, - {"AF_VENDOR27", Const, 0, ""}, - {"AF_VENDOR28", Const, 0, ""}, - {"AF_VENDOR29", Const, 0, ""}, - {"AF_VENDOR30", Const, 0, ""}, - {"AF_VENDOR31", Const, 0, ""}, - {"AF_VENDOR32", Const, 0, ""}, - {"AF_VENDOR33", Const, 0, ""}, - {"AF_VENDOR34", Const, 0, ""}, - {"AF_VENDOR35", Const, 0, ""}, - {"AF_VENDOR36", Const, 0, ""}, - {"AF_VENDOR37", Const, 0, ""}, - {"AF_VENDOR38", Const, 0, ""}, - {"AF_VENDOR39", Const, 0, ""}, - {"AF_VENDOR40", Const, 0, ""}, - {"AF_VENDOR41", Const, 0, ""}, - {"AF_VENDOR42", Const, 0, ""}, - {"AF_VENDOR43", Const, 0, ""}, - {"AF_VENDOR44", Const, 0, ""}, - {"AF_VENDOR45", Const, 0, ""}, - {"AF_VENDOR46", Const, 0, ""}, - {"AF_VENDOR47", Const, 0, ""}, - {"AF_WANPIPE", Const, 0, ""}, - {"AF_X25", Const, 0, ""}, - {"AI_CANONNAME", Const, 1, ""}, - {"AI_NUMERICHOST", Const, 1, ""}, - {"AI_PASSIVE", Const, 1, ""}, - {"APPLICATION_ERROR", Const, 0, ""}, - {"ARPHRD_ADAPT", Const, 0, ""}, - {"ARPHRD_APPLETLK", Const, 0, ""}, - {"ARPHRD_ARCNET", Const, 0, ""}, - {"ARPHRD_ASH", Const, 0, ""}, - {"ARPHRD_ATM", Const, 0, ""}, - {"ARPHRD_AX25", Const, 0, ""}, - {"ARPHRD_BIF", Const, 0, ""}, - {"ARPHRD_CHAOS", Const, 0, ""}, - {"ARPHRD_CISCO", Const, 0, ""}, - {"ARPHRD_CSLIP", Const, 0, ""}, - {"ARPHRD_CSLIP6", Const, 0, ""}, - {"ARPHRD_DDCMP", Const, 0, ""}, - {"ARPHRD_DLCI", Const, 0, ""}, - {"ARPHRD_ECONET", Const, 0, ""}, - {"ARPHRD_EETHER", Const, 0, ""}, - {"ARPHRD_ETHER", Const, 0, ""}, - {"ARPHRD_EUI64", Const, 0, ""}, - {"ARPHRD_FCAL", Const, 0, ""}, - {"ARPHRD_FCFABRIC", Const, 0, ""}, - {"ARPHRD_FCPL", Const, 0, ""}, - {"ARPHRD_FCPP", Const, 0, ""}, - {"ARPHRD_FDDI", Const, 0, ""}, - {"ARPHRD_FRAD", Const, 0, ""}, - {"ARPHRD_FRELAY", Const, 1, ""}, - {"ARPHRD_HDLC", Const, 0, ""}, - {"ARPHRD_HIPPI", Const, 0, ""}, - {"ARPHRD_HWX25", Const, 0, ""}, - {"ARPHRD_IEEE1394", Const, 0, ""}, - {"ARPHRD_IEEE802", Const, 0, ""}, - {"ARPHRD_IEEE80211", Const, 0, ""}, - {"ARPHRD_IEEE80211_PRISM", Const, 0, ""}, - {"ARPHRD_IEEE80211_RADIOTAP", Const, 0, ""}, - {"ARPHRD_IEEE802154", Const, 0, ""}, - {"ARPHRD_IEEE802154_PHY", Const, 0, ""}, - {"ARPHRD_IEEE802_TR", Const, 0, ""}, - {"ARPHRD_INFINIBAND", Const, 0, ""}, - {"ARPHRD_IPDDP", Const, 0, ""}, - {"ARPHRD_IPGRE", Const, 0, ""}, - {"ARPHRD_IRDA", Const, 0, ""}, - {"ARPHRD_LAPB", Const, 0, ""}, - {"ARPHRD_LOCALTLK", Const, 0, ""}, - {"ARPHRD_LOOPBACK", Const, 0, ""}, - {"ARPHRD_METRICOM", Const, 0, ""}, - {"ARPHRD_NETROM", Const, 0, ""}, - {"ARPHRD_NONE", Const, 0, ""}, - {"ARPHRD_PIMREG", Const, 0, ""}, - {"ARPHRD_PPP", Const, 0, ""}, - {"ARPHRD_PRONET", Const, 0, ""}, - {"ARPHRD_RAWHDLC", Const, 0, ""}, - {"ARPHRD_ROSE", Const, 0, ""}, - {"ARPHRD_RSRVD", Const, 0, ""}, - {"ARPHRD_SIT", Const, 0, ""}, - {"ARPHRD_SKIP", Const, 0, ""}, - {"ARPHRD_SLIP", Const, 0, ""}, - {"ARPHRD_SLIP6", Const, 0, ""}, - {"ARPHRD_STRIP", Const, 1, ""}, - {"ARPHRD_TUNNEL", Const, 0, ""}, - {"ARPHRD_TUNNEL6", Const, 0, ""}, - {"ARPHRD_VOID", Const, 0, ""}, - {"ARPHRD_X25", Const, 0, ""}, - {"AUTHTYPE_CLIENT", Const, 0, ""}, - {"AUTHTYPE_SERVER", Const, 0, ""}, - {"Accept", Func, 0, "func(fd int) (nfd int, sa Sockaddr, err error)"}, - {"Accept4", Func, 1, "func(fd int, flags int) (nfd int, sa Sockaddr, err error)"}, - {"AcceptEx", Func, 0, ""}, - {"Access", Func, 0, "func(path string, mode uint32) (err error)"}, - {"Acct", Func, 0, "func(path string) (err error)"}, - {"AddrinfoW", Type, 1, ""}, - {"AddrinfoW.Addr", Field, 1, ""}, - {"AddrinfoW.Addrlen", Field, 1, ""}, - {"AddrinfoW.Canonname", Field, 1, ""}, - {"AddrinfoW.Family", Field, 1, ""}, - {"AddrinfoW.Flags", Field, 1, ""}, - {"AddrinfoW.Next", Field, 1, ""}, - {"AddrinfoW.Protocol", Field, 1, ""}, - {"AddrinfoW.Socktype", Field, 1, ""}, - {"Adjtime", Func, 0, ""}, - {"Adjtimex", Func, 0, "func(buf *Timex) (state int, err error)"}, - {"AllThreadsSyscall", Func, 16, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err Errno)"}, - {"AllThreadsSyscall6", Func, 16, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err Errno)"}, - {"AttachLsf", Func, 0, "func(fd int, i []SockFilter) error"}, - {"B0", Const, 0, ""}, - {"B1000000", Const, 0, ""}, - {"B110", Const, 0, ""}, - {"B115200", Const, 0, ""}, - {"B1152000", Const, 0, ""}, - {"B1200", Const, 0, ""}, - {"B134", Const, 0, ""}, - {"B14400", Const, 1, ""}, - {"B150", Const, 0, ""}, - {"B1500000", Const, 0, ""}, - {"B1800", Const, 0, ""}, - {"B19200", Const, 0, ""}, - {"B200", Const, 0, ""}, - {"B2000000", Const, 0, ""}, - {"B230400", Const, 0, ""}, - {"B2400", Const, 0, ""}, - {"B2500000", Const, 0, ""}, - {"B28800", Const, 1, ""}, - {"B300", Const, 0, ""}, - {"B3000000", Const, 0, ""}, - {"B3500000", Const, 0, ""}, - {"B38400", Const, 0, ""}, - {"B4000000", Const, 0, ""}, - {"B460800", Const, 0, ""}, - {"B4800", Const, 0, ""}, - {"B50", Const, 0, ""}, - {"B500000", Const, 0, ""}, - {"B57600", Const, 0, ""}, - {"B576000", Const, 0, ""}, - {"B600", Const, 0, ""}, - {"B7200", Const, 1, ""}, - {"B75", Const, 0, ""}, - {"B76800", Const, 1, ""}, - {"B921600", Const, 0, ""}, - {"B9600", Const, 0, ""}, - {"BASE_PROTOCOL", Const, 2, ""}, - {"BIOCFEEDBACK", Const, 0, ""}, - {"BIOCFLUSH", Const, 0, ""}, - {"BIOCGBLEN", Const, 0, ""}, - {"BIOCGDIRECTION", Const, 0, ""}, - {"BIOCGDIRFILT", Const, 1, ""}, - {"BIOCGDLT", Const, 0, ""}, - {"BIOCGDLTLIST", Const, 0, ""}, - {"BIOCGETBUFMODE", Const, 0, ""}, - {"BIOCGETIF", Const, 0, ""}, - {"BIOCGETZMAX", Const, 0, ""}, - {"BIOCGFEEDBACK", Const, 1, ""}, - {"BIOCGFILDROP", Const, 1, ""}, - {"BIOCGHDRCMPLT", Const, 0, ""}, - {"BIOCGRSIG", Const, 0, ""}, - {"BIOCGRTIMEOUT", Const, 0, ""}, - {"BIOCGSEESENT", Const, 0, ""}, - {"BIOCGSTATS", Const, 0, ""}, - {"BIOCGSTATSOLD", Const, 1, ""}, - {"BIOCGTSTAMP", Const, 1, ""}, - {"BIOCIMMEDIATE", Const, 0, ""}, - {"BIOCLOCK", Const, 0, ""}, - {"BIOCPROMISC", Const, 0, ""}, - {"BIOCROTZBUF", Const, 0, ""}, - {"BIOCSBLEN", Const, 0, ""}, - {"BIOCSDIRECTION", Const, 0, ""}, - {"BIOCSDIRFILT", Const, 1, ""}, - {"BIOCSDLT", Const, 0, ""}, - {"BIOCSETBUFMODE", Const, 0, ""}, - {"BIOCSETF", Const, 0, ""}, - {"BIOCSETFNR", Const, 0, ""}, - {"BIOCSETIF", Const, 0, ""}, - {"BIOCSETWF", Const, 0, ""}, - {"BIOCSETZBUF", Const, 0, ""}, - {"BIOCSFEEDBACK", Const, 1, ""}, - {"BIOCSFILDROP", Const, 1, ""}, - {"BIOCSHDRCMPLT", Const, 0, ""}, - {"BIOCSRSIG", Const, 0, ""}, - {"BIOCSRTIMEOUT", Const, 0, ""}, - {"BIOCSSEESENT", Const, 0, ""}, - {"BIOCSTCPF", Const, 1, ""}, - {"BIOCSTSTAMP", Const, 1, ""}, - {"BIOCSUDPF", Const, 1, ""}, - {"BIOCVERSION", Const, 0, ""}, - {"BPF_A", Const, 0, ""}, - {"BPF_ABS", Const, 0, ""}, - {"BPF_ADD", Const, 0, ""}, - {"BPF_ALIGNMENT", Const, 0, ""}, - {"BPF_ALIGNMENT32", Const, 1, ""}, - {"BPF_ALU", Const, 0, ""}, - {"BPF_AND", Const, 0, ""}, - {"BPF_B", Const, 0, ""}, - {"BPF_BUFMODE_BUFFER", Const, 0, ""}, - {"BPF_BUFMODE_ZBUF", Const, 0, ""}, - {"BPF_DFLTBUFSIZE", Const, 1, ""}, - {"BPF_DIRECTION_IN", Const, 1, ""}, - {"BPF_DIRECTION_OUT", Const, 1, ""}, - {"BPF_DIV", Const, 0, ""}, - {"BPF_H", Const, 0, ""}, - {"BPF_IMM", Const, 0, ""}, - {"BPF_IND", Const, 0, ""}, - {"BPF_JA", Const, 0, ""}, - {"BPF_JEQ", Const, 0, ""}, - {"BPF_JGE", Const, 0, ""}, - {"BPF_JGT", Const, 0, ""}, - {"BPF_JMP", Const, 0, ""}, - {"BPF_JSET", Const, 0, ""}, - {"BPF_K", Const, 0, ""}, - {"BPF_LD", Const, 0, ""}, - {"BPF_LDX", Const, 0, ""}, - {"BPF_LEN", Const, 0, ""}, - {"BPF_LSH", Const, 0, ""}, - {"BPF_MAJOR_VERSION", Const, 0, ""}, - {"BPF_MAXBUFSIZE", Const, 0, ""}, - {"BPF_MAXINSNS", Const, 0, ""}, - {"BPF_MEM", Const, 0, ""}, - {"BPF_MEMWORDS", Const, 0, ""}, - {"BPF_MINBUFSIZE", Const, 0, ""}, - {"BPF_MINOR_VERSION", Const, 0, ""}, - {"BPF_MISC", Const, 0, ""}, - {"BPF_MSH", Const, 0, ""}, - {"BPF_MUL", Const, 0, ""}, - {"BPF_NEG", Const, 0, ""}, - {"BPF_OR", Const, 0, ""}, - {"BPF_RELEASE", Const, 0, ""}, - {"BPF_RET", Const, 0, ""}, - {"BPF_RSH", Const, 0, ""}, - {"BPF_ST", Const, 0, ""}, - {"BPF_STX", Const, 0, ""}, - {"BPF_SUB", Const, 0, ""}, - {"BPF_TAX", Const, 0, ""}, - {"BPF_TXA", Const, 0, ""}, - {"BPF_T_BINTIME", Const, 1, ""}, - {"BPF_T_BINTIME_FAST", Const, 1, ""}, - {"BPF_T_BINTIME_MONOTONIC", Const, 1, ""}, - {"BPF_T_BINTIME_MONOTONIC_FAST", Const, 1, ""}, - {"BPF_T_FAST", Const, 1, ""}, - {"BPF_T_FLAG_MASK", Const, 1, ""}, - {"BPF_T_FORMAT_MASK", Const, 1, ""}, - {"BPF_T_MICROTIME", Const, 1, ""}, - {"BPF_T_MICROTIME_FAST", Const, 1, ""}, - {"BPF_T_MICROTIME_MONOTONIC", Const, 1, ""}, - {"BPF_T_MICROTIME_MONOTONIC_FAST", Const, 1, ""}, - {"BPF_T_MONOTONIC", Const, 1, ""}, - {"BPF_T_MONOTONIC_FAST", Const, 1, ""}, - {"BPF_T_NANOTIME", Const, 1, ""}, - {"BPF_T_NANOTIME_FAST", Const, 1, ""}, - {"BPF_T_NANOTIME_MONOTONIC", Const, 1, ""}, - {"BPF_T_NANOTIME_MONOTONIC_FAST", Const, 1, ""}, - {"BPF_T_NONE", Const, 1, ""}, - {"BPF_T_NORMAL", Const, 1, ""}, - {"BPF_W", Const, 0, ""}, - {"BPF_X", Const, 0, ""}, - {"BRKINT", Const, 0, ""}, - {"Bind", Func, 0, "func(fd int, sa Sockaddr) (err error)"}, - {"BindToDevice", Func, 0, "func(fd int, device string) (err error)"}, - {"BpfBuflen", Func, 0, ""}, - {"BpfDatalink", Func, 0, ""}, - {"BpfHdr", Type, 0, ""}, - {"BpfHdr.Caplen", Field, 0, ""}, - {"BpfHdr.Datalen", Field, 0, ""}, - {"BpfHdr.Hdrlen", Field, 0, ""}, - {"BpfHdr.Pad_cgo_0", Field, 0, ""}, - {"BpfHdr.Tstamp", Field, 0, ""}, - {"BpfHeadercmpl", Func, 0, ""}, - {"BpfInsn", Type, 0, ""}, - {"BpfInsn.Code", Field, 0, ""}, - {"BpfInsn.Jf", Field, 0, ""}, - {"BpfInsn.Jt", Field, 0, ""}, - {"BpfInsn.K", Field, 0, ""}, - {"BpfInterface", Func, 0, ""}, - {"BpfJump", Func, 0, ""}, - {"BpfProgram", Type, 0, ""}, - {"BpfProgram.Insns", Field, 0, ""}, - {"BpfProgram.Len", Field, 0, ""}, - {"BpfProgram.Pad_cgo_0", Field, 0, ""}, - {"BpfStat", Type, 0, ""}, - {"BpfStat.Capt", Field, 2, ""}, - {"BpfStat.Drop", Field, 0, ""}, - {"BpfStat.Padding", Field, 2, ""}, - {"BpfStat.Recv", Field, 0, ""}, - {"BpfStats", Func, 0, ""}, - {"BpfStmt", Func, 0, ""}, - {"BpfTimeout", Func, 0, ""}, - {"BpfTimeval", Type, 2, ""}, - {"BpfTimeval.Sec", Field, 2, ""}, - {"BpfTimeval.Usec", Field, 2, ""}, - {"BpfVersion", Type, 0, ""}, - {"BpfVersion.Major", Field, 0, ""}, - {"BpfVersion.Minor", Field, 0, ""}, - {"BpfZbuf", Type, 0, ""}, - {"BpfZbuf.Bufa", Field, 0, ""}, - {"BpfZbuf.Bufb", Field, 0, ""}, - {"BpfZbuf.Buflen", Field, 0, ""}, - {"BpfZbufHeader", Type, 0, ""}, - {"BpfZbufHeader.Kernel_gen", Field, 0, ""}, - {"BpfZbufHeader.Kernel_len", Field, 0, ""}, - {"BpfZbufHeader.User_gen", Field, 0, ""}, - {"BpfZbufHeader.X_bzh_pad", Field, 0, ""}, - {"ByHandleFileInformation", Type, 0, ""}, - {"ByHandleFileInformation.CreationTime", Field, 0, ""}, - {"ByHandleFileInformation.FileAttributes", Field, 0, ""}, - {"ByHandleFileInformation.FileIndexHigh", Field, 0, ""}, - {"ByHandleFileInformation.FileIndexLow", Field, 0, ""}, - {"ByHandleFileInformation.FileSizeHigh", Field, 0, ""}, - {"ByHandleFileInformation.FileSizeLow", Field, 0, ""}, - {"ByHandleFileInformation.LastAccessTime", Field, 0, ""}, - {"ByHandleFileInformation.LastWriteTime", Field, 0, ""}, - {"ByHandleFileInformation.NumberOfLinks", Field, 0, ""}, - {"ByHandleFileInformation.VolumeSerialNumber", Field, 0, ""}, - {"BytePtrFromString", Func, 1, "func(s string) (*byte, error)"}, - {"ByteSliceFromString", Func, 1, "func(s string) ([]byte, error)"}, - {"CCR0_FLUSH", Const, 1, ""}, - {"CERT_CHAIN_POLICY_AUTHENTICODE", Const, 0, ""}, - {"CERT_CHAIN_POLICY_AUTHENTICODE_TS", Const, 0, ""}, - {"CERT_CHAIN_POLICY_BASE", Const, 0, ""}, - {"CERT_CHAIN_POLICY_BASIC_CONSTRAINTS", Const, 0, ""}, - {"CERT_CHAIN_POLICY_EV", Const, 0, ""}, - {"CERT_CHAIN_POLICY_MICROSOFT_ROOT", Const, 0, ""}, - {"CERT_CHAIN_POLICY_NT_AUTH", Const, 0, ""}, - {"CERT_CHAIN_POLICY_SSL", Const, 0, ""}, - {"CERT_E_CN_NO_MATCH", Const, 0, ""}, - {"CERT_E_EXPIRED", Const, 0, ""}, - {"CERT_E_PURPOSE", Const, 0, ""}, - {"CERT_E_ROLE", Const, 0, ""}, - {"CERT_E_UNTRUSTEDROOT", Const, 0, ""}, - {"CERT_STORE_ADD_ALWAYS", Const, 0, ""}, - {"CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG", Const, 0, ""}, - {"CERT_STORE_PROV_MEMORY", Const, 0, ""}, - {"CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT", Const, 0, ""}, - {"CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT", Const, 0, ""}, - {"CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT", Const, 0, ""}, - {"CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT", Const, 0, ""}, - {"CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT", Const, 0, ""}, - {"CERT_TRUST_INVALID_BASIC_CONSTRAINTS", Const, 0, ""}, - {"CERT_TRUST_INVALID_EXTENSION", Const, 0, ""}, - {"CERT_TRUST_INVALID_NAME_CONSTRAINTS", Const, 0, ""}, - {"CERT_TRUST_INVALID_POLICY_CONSTRAINTS", Const, 0, ""}, - {"CERT_TRUST_IS_CYCLIC", Const, 0, ""}, - {"CERT_TRUST_IS_EXPLICIT_DISTRUST", Const, 0, ""}, - {"CERT_TRUST_IS_NOT_SIGNATURE_VALID", Const, 0, ""}, - {"CERT_TRUST_IS_NOT_TIME_VALID", Const, 0, ""}, - {"CERT_TRUST_IS_NOT_VALID_FOR_USAGE", Const, 0, ""}, - {"CERT_TRUST_IS_OFFLINE_REVOCATION", Const, 0, ""}, - {"CERT_TRUST_IS_REVOKED", Const, 0, ""}, - {"CERT_TRUST_IS_UNTRUSTED_ROOT", Const, 0, ""}, - {"CERT_TRUST_NO_ERROR", Const, 0, ""}, - {"CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY", Const, 0, ""}, - {"CERT_TRUST_REVOCATION_STATUS_UNKNOWN", Const, 0, ""}, - {"CFLUSH", Const, 1, ""}, - {"CLOCAL", Const, 0, ""}, - {"CLONE_CHILD_CLEARTID", Const, 2, ""}, - {"CLONE_CHILD_SETTID", Const, 2, ""}, - {"CLONE_CLEAR_SIGHAND", Const, 20, ""}, - {"CLONE_CSIGNAL", Const, 3, ""}, - {"CLONE_DETACHED", Const, 2, ""}, - {"CLONE_FILES", Const, 2, ""}, - {"CLONE_FS", Const, 2, ""}, - {"CLONE_INTO_CGROUP", Const, 20, ""}, - {"CLONE_IO", Const, 2, ""}, - {"CLONE_NEWCGROUP", Const, 20, ""}, - {"CLONE_NEWIPC", Const, 2, ""}, - {"CLONE_NEWNET", Const, 2, ""}, - {"CLONE_NEWNS", Const, 2, ""}, - {"CLONE_NEWPID", Const, 2, ""}, - {"CLONE_NEWTIME", Const, 20, ""}, - {"CLONE_NEWUSER", Const, 2, ""}, - {"CLONE_NEWUTS", Const, 2, ""}, - {"CLONE_PARENT", Const, 2, ""}, - {"CLONE_PARENT_SETTID", Const, 2, ""}, - {"CLONE_PID", Const, 3, ""}, - {"CLONE_PIDFD", Const, 20, ""}, - {"CLONE_PTRACE", Const, 2, ""}, - {"CLONE_SETTLS", Const, 2, ""}, - {"CLONE_SIGHAND", Const, 2, ""}, - {"CLONE_SYSVSEM", Const, 2, ""}, - {"CLONE_THREAD", Const, 2, ""}, - {"CLONE_UNTRACED", Const, 2, ""}, - {"CLONE_VFORK", Const, 2, ""}, - {"CLONE_VM", Const, 2, ""}, - {"CPUID_CFLUSH", Const, 1, ""}, - {"CREAD", Const, 0, ""}, - {"CREATE_ALWAYS", Const, 0, ""}, - {"CREATE_NEW", Const, 0, ""}, - {"CREATE_NEW_PROCESS_GROUP", Const, 1, ""}, - {"CREATE_UNICODE_ENVIRONMENT", Const, 0, ""}, - {"CRYPT_DEFAULT_CONTAINER_OPTIONAL", Const, 0, ""}, - {"CRYPT_DELETEKEYSET", Const, 0, ""}, - {"CRYPT_MACHINE_KEYSET", Const, 0, ""}, - {"CRYPT_NEWKEYSET", Const, 0, ""}, - {"CRYPT_SILENT", Const, 0, ""}, - {"CRYPT_VERIFYCONTEXT", Const, 0, ""}, - {"CS5", Const, 0, ""}, - {"CS6", Const, 0, ""}, - {"CS7", Const, 0, ""}, - {"CS8", Const, 0, ""}, - {"CSIZE", Const, 0, ""}, - {"CSTART", Const, 1, ""}, - {"CSTATUS", Const, 1, ""}, - {"CSTOP", Const, 1, ""}, - {"CSTOPB", Const, 0, ""}, - {"CSUSP", Const, 1, ""}, - {"CTL_MAXNAME", Const, 0, ""}, - {"CTL_NET", Const, 0, ""}, - {"CTL_QUERY", Const, 1, ""}, - {"CTRL_BREAK_EVENT", Const, 1, ""}, - {"CTRL_CLOSE_EVENT", Const, 14, ""}, - {"CTRL_C_EVENT", Const, 1, ""}, - {"CTRL_LOGOFF_EVENT", Const, 14, ""}, - {"CTRL_SHUTDOWN_EVENT", Const, 14, ""}, - {"CancelIo", Func, 0, ""}, - {"CancelIoEx", Func, 1, ""}, - {"CertAddCertificateContextToStore", Func, 0, ""}, - {"CertChainContext", Type, 0, ""}, - {"CertChainContext.ChainCount", Field, 0, ""}, - {"CertChainContext.Chains", Field, 0, ""}, - {"CertChainContext.HasRevocationFreshnessTime", Field, 0, ""}, - {"CertChainContext.LowerQualityChainCount", Field, 0, ""}, - {"CertChainContext.LowerQualityChains", Field, 0, ""}, - {"CertChainContext.RevocationFreshnessTime", Field, 0, ""}, - {"CertChainContext.Size", Field, 0, ""}, - {"CertChainContext.TrustStatus", Field, 0, ""}, - {"CertChainElement", Type, 0, ""}, - {"CertChainElement.ApplicationUsage", Field, 0, ""}, - {"CertChainElement.CertContext", Field, 0, ""}, - {"CertChainElement.ExtendedErrorInfo", Field, 0, ""}, - {"CertChainElement.IssuanceUsage", Field, 0, ""}, - {"CertChainElement.RevocationInfo", Field, 0, ""}, - {"CertChainElement.Size", Field, 0, ""}, - {"CertChainElement.TrustStatus", Field, 0, ""}, - {"CertChainPara", Type, 0, ""}, - {"CertChainPara.CacheResync", Field, 0, ""}, - {"CertChainPara.CheckRevocationFreshnessTime", Field, 0, ""}, - {"CertChainPara.RequestedUsage", Field, 0, ""}, - {"CertChainPara.RequstedIssuancePolicy", Field, 0, ""}, - {"CertChainPara.RevocationFreshnessTime", Field, 0, ""}, - {"CertChainPara.Size", Field, 0, ""}, - {"CertChainPara.URLRetrievalTimeout", Field, 0, ""}, - {"CertChainPolicyPara", Type, 0, ""}, - {"CertChainPolicyPara.ExtraPolicyPara", Field, 0, ""}, - {"CertChainPolicyPara.Flags", Field, 0, ""}, - {"CertChainPolicyPara.Size", Field, 0, ""}, - {"CertChainPolicyStatus", Type, 0, ""}, - {"CertChainPolicyStatus.ChainIndex", Field, 0, ""}, - {"CertChainPolicyStatus.ElementIndex", Field, 0, ""}, - {"CertChainPolicyStatus.Error", Field, 0, ""}, - {"CertChainPolicyStatus.ExtraPolicyStatus", Field, 0, ""}, - {"CertChainPolicyStatus.Size", Field, 0, ""}, - {"CertCloseStore", Func, 0, ""}, - {"CertContext", Type, 0, ""}, - {"CertContext.CertInfo", Field, 0, ""}, - {"CertContext.EncodedCert", Field, 0, ""}, - {"CertContext.EncodingType", Field, 0, ""}, - {"CertContext.Length", Field, 0, ""}, - {"CertContext.Store", Field, 0, ""}, - {"CertCreateCertificateContext", Func, 0, ""}, - {"CertEnhKeyUsage", Type, 0, ""}, - {"CertEnhKeyUsage.Length", Field, 0, ""}, - {"CertEnhKeyUsage.UsageIdentifiers", Field, 0, ""}, - {"CertEnumCertificatesInStore", Func, 0, ""}, - {"CertFreeCertificateChain", Func, 0, ""}, - {"CertFreeCertificateContext", Func, 0, ""}, - {"CertGetCertificateChain", Func, 0, ""}, - {"CertInfo", Type, 11, ""}, - {"CertOpenStore", Func, 0, ""}, - {"CertOpenSystemStore", Func, 0, ""}, - {"CertRevocationCrlInfo", Type, 11, ""}, - {"CertRevocationInfo", Type, 0, ""}, - {"CertRevocationInfo.CrlInfo", Field, 0, ""}, - {"CertRevocationInfo.FreshnessTime", Field, 0, ""}, - {"CertRevocationInfo.HasFreshnessTime", Field, 0, ""}, - {"CertRevocationInfo.OidSpecificInfo", Field, 0, ""}, - {"CertRevocationInfo.RevocationOid", Field, 0, ""}, - {"CertRevocationInfo.RevocationResult", Field, 0, ""}, - {"CertRevocationInfo.Size", Field, 0, ""}, - {"CertSimpleChain", Type, 0, ""}, - {"CertSimpleChain.Elements", Field, 0, ""}, - {"CertSimpleChain.HasRevocationFreshnessTime", Field, 0, ""}, - {"CertSimpleChain.NumElements", Field, 0, ""}, - {"CertSimpleChain.RevocationFreshnessTime", Field, 0, ""}, - {"CertSimpleChain.Size", Field, 0, ""}, - {"CertSimpleChain.TrustListInfo", Field, 0, ""}, - {"CertSimpleChain.TrustStatus", Field, 0, ""}, - {"CertTrustListInfo", Type, 11, ""}, - {"CertTrustStatus", Type, 0, ""}, - {"CertTrustStatus.ErrorStatus", Field, 0, ""}, - {"CertTrustStatus.InfoStatus", Field, 0, ""}, - {"CertUsageMatch", Type, 0, ""}, - {"CertUsageMatch.Type", Field, 0, ""}, - {"CertUsageMatch.Usage", Field, 0, ""}, - {"CertVerifyCertificateChainPolicy", Func, 0, ""}, - {"Chdir", Func, 0, "func(path string) (err error)"}, - {"CheckBpfVersion", Func, 0, ""}, - {"Chflags", Func, 0, ""}, - {"Chmod", Func, 0, "func(path string, mode uint32) (err error)"}, - {"Chown", Func, 0, "func(path string, uid int, gid int) (err error)"}, - {"Chroot", Func, 0, "func(path string) (err error)"}, - {"Clearenv", Func, 0, "func()"}, - {"Close", Func, 0, "func(fd int) (err error)"}, - {"CloseHandle", Func, 0, ""}, - {"CloseOnExec", Func, 0, "func(fd int)"}, - {"Closesocket", Func, 0, ""}, - {"CmsgLen", Func, 0, "func(datalen int) int"}, - {"CmsgSpace", Func, 0, "func(datalen int) int"}, - {"Cmsghdr", Type, 0, ""}, - {"Cmsghdr.Len", Field, 0, ""}, - {"Cmsghdr.Level", Field, 0, ""}, - {"Cmsghdr.Type", Field, 0, ""}, - {"Cmsghdr.X__cmsg_data", Field, 0, ""}, - {"CommandLineToArgv", Func, 0, ""}, - {"ComputerName", Func, 0, ""}, - {"Conn", Type, 9, ""}, - {"Connect", Func, 0, "func(fd int, sa Sockaddr) (err error)"}, - {"ConnectEx", Func, 1, ""}, - {"ConvertSidToStringSid", Func, 0, ""}, - {"ConvertStringSidToSid", Func, 0, ""}, - {"CopySid", Func, 0, ""}, - {"Creat", Func, 0, "func(path string, mode uint32) (fd int, err error)"}, - {"CreateDirectory", Func, 0, ""}, - {"CreateFile", Func, 0, ""}, - {"CreateFileMapping", Func, 0, ""}, - {"CreateHardLink", Func, 4, ""}, - {"CreateIoCompletionPort", Func, 0, ""}, - {"CreatePipe", Func, 0, ""}, - {"CreateProcess", Func, 0, ""}, - {"CreateProcessAsUser", Func, 10, ""}, - {"CreateSymbolicLink", Func, 4, ""}, - {"CreateToolhelp32Snapshot", Func, 4, ""}, - {"Credential", Type, 0, ""}, - {"Credential.Gid", Field, 0, ""}, - {"Credential.Groups", Field, 0, ""}, - {"Credential.NoSetGroups", Field, 9, ""}, - {"Credential.Uid", Field, 0, ""}, - {"CryptAcquireContext", Func, 0, ""}, - {"CryptGenRandom", Func, 0, ""}, - {"CryptReleaseContext", Func, 0, ""}, - {"DIOCBSFLUSH", Const, 1, ""}, - {"DIOCOSFPFLUSH", Const, 1, ""}, - {"DLL", Type, 0, ""}, - {"DLL.Handle", Field, 0, ""}, - {"DLL.Name", Field, 0, ""}, - {"DLLError", Type, 0, ""}, - {"DLLError.Err", Field, 0, ""}, - {"DLLError.Msg", Field, 0, ""}, - {"DLLError.ObjName", Field, 0, ""}, - {"DLT_A429", Const, 0, ""}, - {"DLT_A653_ICM", Const, 0, ""}, - {"DLT_AIRONET_HEADER", Const, 0, ""}, - {"DLT_AOS", Const, 1, ""}, - {"DLT_APPLE_IP_OVER_IEEE1394", Const, 0, ""}, - {"DLT_ARCNET", Const, 0, ""}, - {"DLT_ARCNET_LINUX", Const, 0, ""}, - {"DLT_ATM_CLIP", Const, 0, ""}, - {"DLT_ATM_RFC1483", Const, 0, ""}, - {"DLT_AURORA", Const, 0, ""}, - {"DLT_AX25", Const, 0, ""}, - {"DLT_AX25_KISS", Const, 0, ""}, - {"DLT_BACNET_MS_TP", Const, 0, ""}, - {"DLT_BLUETOOTH_HCI_H4", Const, 0, ""}, - {"DLT_BLUETOOTH_HCI_H4_WITH_PHDR", Const, 0, ""}, - {"DLT_CAN20B", Const, 0, ""}, - {"DLT_CAN_SOCKETCAN", Const, 1, ""}, - {"DLT_CHAOS", Const, 0, ""}, - {"DLT_CHDLC", Const, 0, ""}, - {"DLT_CISCO_IOS", Const, 0, ""}, - {"DLT_C_HDLC", Const, 0, ""}, - {"DLT_C_HDLC_WITH_DIR", Const, 0, ""}, - {"DLT_DBUS", Const, 1, ""}, - {"DLT_DECT", Const, 1, ""}, - {"DLT_DOCSIS", Const, 0, ""}, - {"DLT_DVB_CI", Const, 1, ""}, - {"DLT_ECONET", Const, 0, ""}, - {"DLT_EN10MB", Const, 0, ""}, - {"DLT_EN3MB", Const, 0, ""}, - {"DLT_ENC", Const, 0, ""}, - {"DLT_ERF", Const, 0, ""}, - {"DLT_ERF_ETH", Const, 0, ""}, - {"DLT_ERF_POS", Const, 0, ""}, - {"DLT_FC_2", Const, 1, ""}, - {"DLT_FC_2_WITH_FRAME_DELIMS", Const, 1, ""}, - {"DLT_FDDI", Const, 0, ""}, - {"DLT_FLEXRAY", Const, 0, ""}, - {"DLT_FRELAY", Const, 0, ""}, - {"DLT_FRELAY_WITH_DIR", Const, 0, ""}, - {"DLT_GCOM_SERIAL", Const, 0, ""}, - {"DLT_GCOM_T1E1", Const, 0, ""}, - {"DLT_GPF_F", Const, 0, ""}, - {"DLT_GPF_T", Const, 0, ""}, - {"DLT_GPRS_LLC", Const, 0, ""}, - {"DLT_GSMTAP_ABIS", Const, 1, ""}, - {"DLT_GSMTAP_UM", Const, 1, ""}, - {"DLT_HDLC", Const, 1, ""}, - {"DLT_HHDLC", Const, 0, ""}, - {"DLT_HIPPI", Const, 1, ""}, - {"DLT_IBM_SN", Const, 0, ""}, - {"DLT_IBM_SP", Const, 0, ""}, - {"DLT_IEEE802", Const, 0, ""}, - {"DLT_IEEE802_11", Const, 0, ""}, - {"DLT_IEEE802_11_RADIO", Const, 0, ""}, - {"DLT_IEEE802_11_RADIO_AVS", Const, 0, ""}, - {"DLT_IEEE802_15_4", Const, 0, ""}, - {"DLT_IEEE802_15_4_LINUX", Const, 0, ""}, - {"DLT_IEEE802_15_4_NOFCS", Const, 1, ""}, - {"DLT_IEEE802_15_4_NONASK_PHY", Const, 0, ""}, - {"DLT_IEEE802_16_MAC_CPS", Const, 0, ""}, - {"DLT_IEEE802_16_MAC_CPS_RADIO", Const, 0, ""}, - {"DLT_IPFILTER", Const, 0, ""}, - {"DLT_IPMB", Const, 0, ""}, - {"DLT_IPMB_LINUX", Const, 0, ""}, - {"DLT_IPNET", Const, 1, ""}, - {"DLT_IPOIB", Const, 1, ""}, - {"DLT_IPV4", Const, 1, ""}, - {"DLT_IPV6", Const, 1, ""}, - {"DLT_IP_OVER_FC", Const, 0, ""}, - {"DLT_JUNIPER_ATM1", Const, 0, ""}, - {"DLT_JUNIPER_ATM2", Const, 0, ""}, - {"DLT_JUNIPER_ATM_CEMIC", Const, 1, ""}, - {"DLT_JUNIPER_CHDLC", Const, 0, ""}, - {"DLT_JUNIPER_ES", Const, 0, ""}, - {"DLT_JUNIPER_ETHER", Const, 0, ""}, - {"DLT_JUNIPER_FIBRECHANNEL", Const, 1, ""}, - {"DLT_JUNIPER_FRELAY", Const, 0, ""}, - {"DLT_JUNIPER_GGSN", Const, 0, ""}, - {"DLT_JUNIPER_ISM", Const, 0, ""}, - {"DLT_JUNIPER_MFR", Const, 0, ""}, - {"DLT_JUNIPER_MLFR", Const, 0, ""}, - {"DLT_JUNIPER_MLPPP", Const, 0, ""}, - {"DLT_JUNIPER_MONITOR", Const, 0, ""}, - {"DLT_JUNIPER_PIC_PEER", Const, 0, ""}, - {"DLT_JUNIPER_PPP", Const, 0, ""}, - {"DLT_JUNIPER_PPPOE", Const, 0, ""}, - {"DLT_JUNIPER_PPPOE_ATM", Const, 0, ""}, - {"DLT_JUNIPER_SERVICES", Const, 0, ""}, - {"DLT_JUNIPER_SRX_E2E", Const, 1, ""}, - {"DLT_JUNIPER_ST", Const, 0, ""}, - {"DLT_JUNIPER_VP", Const, 0, ""}, - {"DLT_JUNIPER_VS", Const, 1, ""}, - {"DLT_LAPB_WITH_DIR", Const, 0, ""}, - {"DLT_LAPD", Const, 0, ""}, - {"DLT_LIN", Const, 0, ""}, - {"DLT_LINUX_EVDEV", Const, 1, ""}, - {"DLT_LINUX_IRDA", Const, 0, ""}, - {"DLT_LINUX_LAPD", Const, 0, ""}, - {"DLT_LINUX_PPP_WITHDIRECTION", Const, 0, ""}, - {"DLT_LINUX_SLL", Const, 0, ""}, - {"DLT_LOOP", Const, 0, ""}, - {"DLT_LTALK", Const, 0, ""}, - {"DLT_MATCHING_MAX", Const, 1, ""}, - {"DLT_MATCHING_MIN", Const, 1, ""}, - {"DLT_MFR", Const, 0, ""}, - {"DLT_MOST", Const, 0, ""}, - {"DLT_MPEG_2_TS", Const, 1, ""}, - {"DLT_MPLS", Const, 1, ""}, - {"DLT_MTP2", Const, 0, ""}, - {"DLT_MTP2_WITH_PHDR", Const, 0, ""}, - {"DLT_MTP3", Const, 0, ""}, - {"DLT_MUX27010", Const, 1, ""}, - {"DLT_NETANALYZER", Const, 1, ""}, - {"DLT_NETANALYZER_TRANSPARENT", Const, 1, ""}, - {"DLT_NFC_LLCP", Const, 1, ""}, - {"DLT_NFLOG", Const, 1, ""}, - {"DLT_NG40", Const, 1, ""}, - {"DLT_NULL", Const, 0, ""}, - {"DLT_PCI_EXP", Const, 0, ""}, - {"DLT_PFLOG", Const, 0, ""}, - {"DLT_PFSYNC", Const, 0, ""}, - {"DLT_PPI", Const, 0, ""}, - {"DLT_PPP", Const, 0, ""}, - {"DLT_PPP_BSDOS", Const, 0, ""}, - {"DLT_PPP_ETHER", Const, 0, ""}, - {"DLT_PPP_PPPD", Const, 0, ""}, - {"DLT_PPP_SERIAL", Const, 0, ""}, - {"DLT_PPP_WITH_DIR", Const, 0, ""}, - {"DLT_PPP_WITH_DIRECTION", Const, 0, ""}, - {"DLT_PRISM_HEADER", Const, 0, ""}, - {"DLT_PRONET", Const, 0, ""}, - {"DLT_RAIF1", Const, 0, ""}, - {"DLT_RAW", Const, 0, ""}, - {"DLT_RAWAF_MASK", Const, 1, ""}, - {"DLT_RIO", Const, 0, ""}, - {"DLT_SCCP", Const, 0, ""}, - {"DLT_SITA", Const, 0, ""}, - {"DLT_SLIP", Const, 0, ""}, - {"DLT_SLIP_BSDOS", Const, 0, ""}, - {"DLT_STANAG_5066_D_PDU", Const, 1, ""}, - {"DLT_SUNATM", Const, 0, ""}, - {"DLT_SYMANTEC_FIREWALL", Const, 0, ""}, - {"DLT_TZSP", Const, 0, ""}, - {"DLT_USB", Const, 0, ""}, - {"DLT_USB_LINUX", Const, 0, ""}, - {"DLT_USB_LINUX_MMAPPED", Const, 1, ""}, - {"DLT_USER0", Const, 0, ""}, - {"DLT_USER1", Const, 0, ""}, - {"DLT_USER10", Const, 0, ""}, - {"DLT_USER11", Const, 0, ""}, - {"DLT_USER12", Const, 0, ""}, - {"DLT_USER13", Const, 0, ""}, - {"DLT_USER14", Const, 0, ""}, - {"DLT_USER15", Const, 0, ""}, - {"DLT_USER2", Const, 0, ""}, - {"DLT_USER3", Const, 0, ""}, - {"DLT_USER4", Const, 0, ""}, - {"DLT_USER5", Const, 0, ""}, - {"DLT_USER6", Const, 0, ""}, - {"DLT_USER7", Const, 0, ""}, - {"DLT_USER8", Const, 0, ""}, - {"DLT_USER9", Const, 0, ""}, - {"DLT_WIHART", Const, 1, ""}, - {"DLT_X2E_SERIAL", Const, 0, ""}, - {"DLT_X2E_XORAYA", Const, 0, ""}, - {"DNSMXData", Type, 0, ""}, - {"DNSMXData.NameExchange", Field, 0, ""}, - {"DNSMXData.Pad", Field, 0, ""}, - {"DNSMXData.Preference", Field, 0, ""}, - {"DNSPTRData", Type, 0, ""}, - {"DNSPTRData.Host", Field, 0, ""}, - {"DNSRecord", Type, 0, ""}, - {"DNSRecord.Data", Field, 0, ""}, - {"DNSRecord.Dw", Field, 0, ""}, - {"DNSRecord.Length", Field, 0, ""}, - {"DNSRecord.Name", Field, 0, ""}, - {"DNSRecord.Next", Field, 0, ""}, - {"DNSRecord.Reserved", Field, 0, ""}, - {"DNSRecord.Ttl", Field, 0, ""}, - {"DNSRecord.Type", Field, 0, ""}, - {"DNSSRVData", Type, 0, ""}, - {"DNSSRVData.Pad", Field, 0, ""}, - {"DNSSRVData.Port", Field, 0, ""}, - {"DNSSRVData.Priority", Field, 0, ""}, - {"DNSSRVData.Target", Field, 0, ""}, - {"DNSSRVData.Weight", Field, 0, ""}, - {"DNSTXTData", Type, 0, ""}, - {"DNSTXTData.StringArray", Field, 0, ""}, - {"DNSTXTData.StringCount", Field, 0, ""}, - {"DNS_INFO_NO_RECORDS", Const, 4, ""}, - {"DNS_TYPE_A", Const, 0, ""}, - {"DNS_TYPE_A6", Const, 0, ""}, - {"DNS_TYPE_AAAA", Const, 0, ""}, - {"DNS_TYPE_ADDRS", Const, 0, ""}, - {"DNS_TYPE_AFSDB", Const, 0, ""}, - {"DNS_TYPE_ALL", Const, 0, ""}, - {"DNS_TYPE_ANY", Const, 0, ""}, - {"DNS_TYPE_ATMA", Const, 0, ""}, - {"DNS_TYPE_AXFR", Const, 0, ""}, - {"DNS_TYPE_CERT", Const, 0, ""}, - {"DNS_TYPE_CNAME", Const, 0, ""}, - {"DNS_TYPE_DHCID", Const, 0, ""}, - {"DNS_TYPE_DNAME", Const, 0, ""}, - {"DNS_TYPE_DNSKEY", Const, 0, ""}, - {"DNS_TYPE_DS", Const, 0, ""}, - {"DNS_TYPE_EID", Const, 0, ""}, - {"DNS_TYPE_GID", Const, 0, ""}, - {"DNS_TYPE_GPOS", Const, 0, ""}, - {"DNS_TYPE_HINFO", Const, 0, ""}, - {"DNS_TYPE_ISDN", Const, 0, ""}, - {"DNS_TYPE_IXFR", Const, 0, ""}, - {"DNS_TYPE_KEY", Const, 0, ""}, - {"DNS_TYPE_KX", Const, 0, ""}, - {"DNS_TYPE_LOC", Const, 0, ""}, - {"DNS_TYPE_MAILA", Const, 0, ""}, - {"DNS_TYPE_MAILB", Const, 0, ""}, - {"DNS_TYPE_MB", Const, 0, ""}, - {"DNS_TYPE_MD", Const, 0, ""}, - {"DNS_TYPE_MF", Const, 0, ""}, - {"DNS_TYPE_MG", Const, 0, ""}, - {"DNS_TYPE_MINFO", Const, 0, ""}, - {"DNS_TYPE_MR", Const, 0, ""}, - {"DNS_TYPE_MX", Const, 0, ""}, - {"DNS_TYPE_NAPTR", Const, 0, ""}, - {"DNS_TYPE_NBSTAT", Const, 0, ""}, - {"DNS_TYPE_NIMLOC", Const, 0, ""}, - {"DNS_TYPE_NS", Const, 0, ""}, - {"DNS_TYPE_NSAP", Const, 0, ""}, - {"DNS_TYPE_NSAPPTR", Const, 0, ""}, - {"DNS_TYPE_NSEC", Const, 0, ""}, - {"DNS_TYPE_NULL", Const, 0, ""}, - {"DNS_TYPE_NXT", Const, 0, ""}, - {"DNS_TYPE_OPT", Const, 0, ""}, - {"DNS_TYPE_PTR", Const, 0, ""}, - {"DNS_TYPE_PX", Const, 0, ""}, - {"DNS_TYPE_RP", Const, 0, ""}, - {"DNS_TYPE_RRSIG", Const, 0, ""}, - {"DNS_TYPE_RT", Const, 0, ""}, - {"DNS_TYPE_SIG", Const, 0, ""}, - {"DNS_TYPE_SINK", Const, 0, ""}, - {"DNS_TYPE_SOA", Const, 0, ""}, - {"DNS_TYPE_SRV", Const, 0, ""}, - {"DNS_TYPE_TEXT", Const, 0, ""}, - {"DNS_TYPE_TKEY", Const, 0, ""}, - {"DNS_TYPE_TSIG", Const, 0, ""}, - {"DNS_TYPE_UID", Const, 0, ""}, - {"DNS_TYPE_UINFO", Const, 0, ""}, - {"DNS_TYPE_UNSPEC", Const, 0, ""}, - {"DNS_TYPE_WINS", Const, 0, ""}, - {"DNS_TYPE_WINSR", Const, 0, ""}, - {"DNS_TYPE_WKS", Const, 0, ""}, - {"DNS_TYPE_X25", Const, 0, ""}, - {"DT_BLK", Const, 0, ""}, - {"DT_CHR", Const, 0, ""}, - {"DT_DIR", Const, 0, ""}, - {"DT_FIFO", Const, 0, ""}, - {"DT_LNK", Const, 0, ""}, - {"DT_REG", Const, 0, ""}, - {"DT_SOCK", Const, 0, ""}, - {"DT_UNKNOWN", Const, 0, ""}, - {"DT_WHT", Const, 0, ""}, - {"DUPLICATE_CLOSE_SOURCE", Const, 0, ""}, - {"DUPLICATE_SAME_ACCESS", Const, 0, ""}, - {"DeleteFile", Func, 0, ""}, - {"DetachLsf", Func, 0, "func(fd int) error"}, - {"DeviceIoControl", Func, 4, ""}, - {"Dirent", Type, 0, ""}, - {"Dirent.Fileno", Field, 0, ""}, - {"Dirent.Ino", Field, 0, ""}, - {"Dirent.Name", Field, 0, ""}, - {"Dirent.Namlen", Field, 0, ""}, - {"Dirent.Off", Field, 0, ""}, - {"Dirent.Pad0", Field, 12, ""}, - {"Dirent.Pad1", Field, 12, ""}, - {"Dirent.Pad_cgo_0", Field, 0, ""}, - {"Dirent.Reclen", Field, 0, ""}, - {"Dirent.Seekoff", Field, 0, ""}, - {"Dirent.Type", Field, 0, ""}, - {"Dirent.X__d_padding", Field, 3, ""}, - {"DnsNameCompare", Func, 4, ""}, - {"DnsQuery", Func, 0, ""}, - {"DnsRecordListFree", Func, 0, ""}, - {"DnsSectionAdditional", Const, 4, ""}, - {"DnsSectionAnswer", Const, 4, ""}, - {"DnsSectionAuthority", Const, 4, ""}, - {"DnsSectionQuestion", Const, 4, ""}, - {"Dup", Func, 0, "func(oldfd int) (fd int, err error)"}, - {"Dup2", Func, 0, "func(oldfd int, newfd int) (err error)"}, - {"Dup3", Func, 2, "func(oldfd int, newfd int, flags int) (err error)"}, - {"DuplicateHandle", Func, 0, ""}, - {"E2BIG", Const, 0, ""}, - {"EACCES", Const, 0, ""}, - {"EADDRINUSE", Const, 0, ""}, - {"EADDRNOTAVAIL", Const, 0, ""}, - {"EADV", Const, 0, ""}, - {"EAFNOSUPPORT", Const, 0, ""}, - {"EAGAIN", Const, 0, ""}, - {"EALREADY", Const, 0, ""}, - {"EAUTH", Const, 0, ""}, - {"EBADARCH", Const, 0, ""}, - {"EBADE", Const, 0, ""}, - {"EBADEXEC", Const, 0, ""}, - {"EBADF", Const, 0, ""}, - {"EBADFD", Const, 0, ""}, - {"EBADMACHO", Const, 0, ""}, - {"EBADMSG", Const, 0, ""}, - {"EBADR", Const, 0, ""}, - {"EBADRPC", Const, 0, ""}, - {"EBADRQC", Const, 0, ""}, - {"EBADSLT", Const, 0, ""}, - {"EBFONT", Const, 0, ""}, - {"EBUSY", Const, 0, ""}, - {"ECANCELED", Const, 0, ""}, - {"ECAPMODE", Const, 1, ""}, - {"ECHILD", Const, 0, ""}, - {"ECHO", Const, 0, ""}, - {"ECHOCTL", Const, 0, ""}, - {"ECHOE", Const, 0, ""}, - {"ECHOK", Const, 0, ""}, - {"ECHOKE", Const, 0, ""}, - {"ECHONL", Const, 0, ""}, - {"ECHOPRT", Const, 0, ""}, - {"ECHRNG", Const, 0, ""}, - {"ECOMM", Const, 0, ""}, - {"ECONNABORTED", Const, 0, ""}, - {"ECONNREFUSED", Const, 0, ""}, - {"ECONNRESET", Const, 0, ""}, - {"EDEADLK", Const, 0, ""}, - {"EDEADLOCK", Const, 0, ""}, - {"EDESTADDRREQ", Const, 0, ""}, - {"EDEVERR", Const, 0, ""}, - {"EDOM", Const, 0, ""}, - {"EDOOFUS", Const, 0, ""}, - {"EDOTDOT", Const, 0, ""}, - {"EDQUOT", Const, 0, ""}, - {"EEXIST", Const, 0, ""}, - {"EFAULT", Const, 0, ""}, - {"EFBIG", Const, 0, ""}, - {"EFER_LMA", Const, 1, ""}, - {"EFER_LME", Const, 1, ""}, - {"EFER_NXE", Const, 1, ""}, - {"EFER_SCE", Const, 1, ""}, - {"EFTYPE", Const, 0, ""}, - {"EHOSTDOWN", Const, 0, ""}, - {"EHOSTUNREACH", Const, 0, ""}, - {"EHWPOISON", Const, 0, ""}, - {"EIDRM", Const, 0, ""}, - {"EILSEQ", Const, 0, ""}, - {"EINPROGRESS", Const, 0, ""}, - {"EINTR", Const, 0, ""}, - {"EINVAL", Const, 0, ""}, - {"EIO", Const, 0, ""}, - {"EIPSEC", Const, 1, ""}, - {"EISCONN", Const, 0, ""}, - {"EISDIR", Const, 0, ""}, - {"EISNAM", Const, 0, ""}, - {"EKEYEXPIRED", Const, 0, ""}, - {"EKEYREJECTED", Const, 0, ""}, - {"EKEYREVOKED", Const, 0, ""}, - {"EL2HLT", Const, 0, ""}, - {"EL2NSYNC", Const, 0, ""}, - {"EL3HLT", Const, 0, ""}, - {"EL3RST", Const, 0, ""}, - {"ELAST", Const, 0, ""}, - {"ELF_NGREG", Const, 0, ""}, - {"ELF_PRARGSZ", Const, 0, ""}, - {"ELIBACC", Const, 0, ""}, - {"ELIBBAD", Const, 0, ""}, - {"ELIBEXEC", Const, 0, ""}, - {"ELIBMAX", Const, 0, ""}, - {"ELIBSCN", Const, 0, ""}, - {"ELNRNG", Const, 0, ""}, - {"ELOOP", Const, 0, ""}, - {"EMEDIUMTYPE", Const, 0, ""}, - {"EMFILE", Const, 0, ""}, - {"EMLINK", Const, 0, ""}, - {"EMSGSIZE", Const, 0, ""}, - {"EMT_TAGOVF", Const, 1, ""}, - {"EMULTIHOP", Const, 0, ""}, - {"EMUL_ENABLED", Const, 1, ""}, - {"EMUL_LINUX", Const, 1, ""}, - {"EMUL_LINUX32", Const, 1, ""}, - {"EMUL_MAXID", Const, 1, ""}, - {"EMUL_NATIVE", Const, 1, ""}, - {"ENAMETOOLONG", Const, 0, ""}, - {"ENAVAIL", Const, 0, ""}, - {"ENDRUNDISC", Const, 1, ""}, - {"ENEEDAUTH", Const, 0, ""}, - {"ENETDOWN", Const, 0, ""}, - {"ENETRESET", Const, 0, ""}, - {"ENETUNREACH", Const, 0, ""}, - {"ENFILE", Const, 0, ""}, - {"ENOANO", Const, 0, ""}, - {"ENOATTR", Const, 0, ""}, - {"ENOBUFS", Const, 0, ""}, - {"ENOCSI", Const, 0, ""}, - {"ENODATA", Const, 0, ""}, - {"ENODEV", Const, 0, ""}, - {"ENOENT", Const, 0, ""}, - {"ENOEXEC", Const, 0, ""}, - {"ENOKEY", Const, 0, ""}, - {"ENOLCK", Const, 0, ""}, - {"ENOLINK", Const, 0, ""}, - {"ENOMEDIUM", Const, 0, ""}, - {"ENOMEM", Const, 0, ""}, - {"ENOMSG", Const, 0, ""}, - {"ENONET", Const, 0, ""}, - {"ENOPKG", Const, 0, ""}, - {"ENOPOLICY", Const, 0, ""}, - {"ENOPROTOOPT", Const, 0, ""}, - {"ENOSPC", Const, 0, ""}, - {"ENOSR", Const, 0, ""}, - {"ENOSTR", Const, 0, ""}, - {"ENOSYS", Const, 0, ""}, - {"ENOTBLK", Const, 0, ""}, - {"ENOTCAPABLE", Const, 0, ""}, - {"ENOTCONN", Const, 0, ""}, - {"ENOTDIR", Const, 0, ""}, - {"ENOTEMPTY", Const, 0, ""}, - {"ENOTNAM", Const, 0, ""}, - {"ENOTRECOVERABLE", Const, 0, ""}, - {"ENOTSOCK", Const, 0, ""}, - {"ENOTSUP", Const, 0, ""}, - {"ENOTTY", Const, 0, ""}, - {"ENOTUNIQ", Const, 0, ""}, - {"ENXIO", Const, 0, ""}, - {"EN_SW_CTL_INF", Const, 1, ""}, - {"EN_SW_CTL_PREC", Const, 1, ""}, - {"EN_SW_CTL_ROUND", Const, 1, ""}, - {"EN_SW_DATACHAIN", Const, 1, ""}, - {"EN_SW_DENORM", Const, 1, ""}, - {"EN_SW_INVOP", Const, 1, ""}, - {"EN_SW_OVERFLOW", Const, 1, ""}, - {"EN_SW_PRECLOSS", Const, 1, ""}, - {"EN_SW_UNDERFLOW", Const, 1, ""}, - {"EN_SW_ZERODIV", Const, 1, ""}, - {"EOPNOTSUPP", Const, 0, ""}, - {"EOVERFLOW", Const, 0, ""}, - {"EOWNERDEAD", Const, 0, ""}, - {"EPERM", Const, 0, ""}, - {"EPFNOSUPPORT", Const, 0, ""}, - {"EPIPE", Const, 0, ""}, - {"EPOLLERR", Const, 0, ""}, - {"EPOLLET", Const, 0, ""}, - {"EPOLLHUP", Const, 0, ""}, - {"EPOLLIN", Const, 0, ""}, - {"EPOLLMSG", Const, 0, ""}, - {"EPOLLONESHOT", Const, 0, ""}, - {"EPOLLOUT", Const, 0, ""}, - {"EPOLLPRI", Const, 0, ""}, - {"EPOLLRDBAND", Const, 0, ""}, - {"EPOLLRDHUP", Const, 0, ""}, - {"EPOLLRDNORM", Const, 0, ""}, - {"EPOLLWRBAND", Const, 0, ""}, - {"EPOLLWRNORM", Const, 0, ""}, - {"EPOLL_CLOEXEC", Const, 0, ""}, - {"EPOLL_CTL_ADD", Const, 0, ""}, - {"EPOLL_CTL_DEL", Const, 0, ""}, - {"EPOLL_CTL_MOD", Const, 0, ""}, - {"EPOLL_NONBLOCK", Const, 0, ""}, - {"EPROCLIM", Const, 0, ""}, - {"EPROCUNAVAIL", Const, 0, ""}, - {"EPROGMISMATCH", Const, 0, ""}, - {"EPROGUNAVAIL", Const, 0, ""}, - {"EPROTO", Const, 0, ""}, - {"EPROTONOSUPPORT", Const, 0, ""}, - {"EPROTOTYPE", Const, 0, ""}, - {"EPWROFF", Const, 0, ""}, - {"EQFULL", Const, 16, ""}, - {"ERANGE", Const, 0, ""}, - {"EREMCHG", Const, 0, ""}, - {"EREMOTE", Const, 0, ""}, - {"EREMOTEIO", Const, 0, ""}, - {"ERESTART", Const, 0, ""}, - {"ERFKILL", Const, 0, ""}, - {"EROFS", Const, 0, ""}, - {"ERPCMISMATCH", Const, 0, ""}, - {"ERROR_ACCESS_DENIED", Const, 0, ""}, - {"ERROR_ALREADY_EXISTS", Const, 0, ""}, - {"ERROR_BROKEN_PIPE", Const, 0, ""}, - {"ERROR_BUFFER_OVERFLOW", Const, 0, ""}, - {"ERROR_DIR_NOT_EMPTY", Const, 8, ""}, - {"ERROR_ENVVAR_NOT_FOUND", Const, 0, ""}, - {"ERROR_FILE_EXISTS", Const, 0, ""}, - {"ERROR_FILE_NOT_FOUND", Const, 0, ""}, - {"ERROR_HANDLE_EOF", Const, 2, ""}, - {"ERROR_INSUFFICIENT_BUFFER", Const, 0, ""}, - {"ERROR_IO_PENDING", Const, 0, ""}, - {"ERROR_MOD_NOT_FOUND", Const, 0, ""}, - {"ERROR_MORE_DATA", Const, 3, ""}, - {"ERROR_NETNAME_DELETED", Const, 3, ""}, - {"ERROR_NOT_FOUND", Const, 1, ""}, - {"ERROR_NO_MORE_FILES", Const, 0, ""}, - {"ERROR_OPERATION_ABORTED", Const, 0, ""}, - {"ERROR_PATH_NOT_FOUND", Const, 0, ""}, - {"ERROR_PRIVILEGE_NOT_HELD", Const, 4, ""}, - {"ERROR_PROC_NOT_FOUND", Const, 0, ""}, - {"ESHLIBVERS", Const, 0, ""}, - {"ESHUTDOWN", Const, 0, ""}, - {"ESOCKTNOSUPPORT", Const, 0, ""}, - {"ESPIPE", Const, 0, ""}, - {"ESRCH", Const, 0, ""}, - {"ESRMNT", Const, 0, ""}, - {"ESTALE", Const, 0, ""}, - {"ESTRPIPE", Const, 0, ""}, - {"ETHERCAP_JUMBO_MTU", Const, 1, ""}, - {"ETHERCAP_VLAN_HWTAGGING", Const, 1, ""}, - {"ETHERCAP_VLAN_MTU", Const, 1, ""}, - {"ETHERMIN", Const, 1, ""}, - {"ETHERMTU", Const, 1, ""}, - {"ETHERMTU_JUMBO", Const, 1, ""}, - {"ETHERTYPE_8023", Const, 1, ""}, - {"ETHERTYPE_AARP", Const, 1, ""}, - {"ETHERTYPE_ACCTON", Const, 1, ""}, - {"ETHERTYPE_AEONIC", Const, 1, ""}, - {"ETHERTYPE_ALPHA", Const, 1, ""}, - {"ETHERTYPE_AMBER", Const, 1, ""}, - {"ETHERTYPE_AMOEBA", Const, 1, ""}, - {"ETHERTYPE_AOE", Const, 1, ""}, - {"ETHERTYPE_APOLLO", Const, 1, ""}, - {"ETHERTYPE_APOLLODOMAIN", Const, 1, ""}, - {"ETHERTYPE_APPLETALK", Const, 1, ""}, - {"ETHERTYPE_APPLITEK", Const, 1, ""}, - {"ETHERTYPE_ARGONAUT", Const, 1, ""}, - {"ETHERTYPE_ARP", Const, 1, ""}, - {"ETHERTYPE_AT", Const, 1, ""}, - {"ETHERTYPE_ATALK", Const, 1, ""}, - {"ETHERTYPE_ATOMIC", Const, 1, ""}, - {"ETHERTYPE_ATT", Const, 1, ""}, - {"ETHERTYPE_ATTSTANFORD", Const, 1, ""}, - {"ETHERTYPE_AUTOPHON", Const, 1, ""}, - {"ETHERTYPE_AXIS", Const, 1, ""}, - {"ETHERTYPE_BCLOOP", Const, 1, ""}, - {"ETHERTYPE_BOFL", Const, 1, ""}, - {"ETHERTYPE_CABLETRON", Const, 1, ""}, - {"ETHERTYPE_CHAOS", Const, 1, ""}, - {"ETHERTYPE_COMDESIGN", Const, 1, ""}, - {"ETHERTYPE_COMPUGRAPHIC", Const, 1, ""}, - {"ETHERTYPE_COUNTERPOINT", Const, 1, ""}, - {"ETHERTYPE_CRONUS", Const, 1, ""}, - {"ETHERTYPE_CRONUSVLN", Const, 1, ""}, - {"ETHERTYPE_DCA", Const, 1, ""}, - {"ETHERTYPE_DDE", Const, 1, ""}, - {"ETHERTYPE_DEBNI", Const, 1, ""}, - {"ETHERTYPE_DECAM", Const, 1, ""}, - {"ETHERTYPE_DECCUST", Const, 1, ""}, - {"ETHERTYPE_DECDIAG", Const, 1, ""}, - {"ETHERTYPE_DECDNS", Const, 1, ""}, - {"ETHERTYPE_DECDTS", Const, 1, ""}, - {"ETHERTYPE_DECEXPER", Const, 1, ""}, - {"ETHERTYPE_DECLAST", Const, 1, ""}, - {"ETHERTYPE_DECLTM", Const, 1, ""}, - {"ETHERTYPE_DECMUMPS", Const, 1, ""}, - {"ETHERTYPE_DECNETBIOS", Const, 1, ""}, - {"ETHERTYPE_DELTACON", Const, 1, ""}, - {"ETHERTYPE_DIDDLE", Const, 1, ""}, - {"ETHERTYPE_DLOG1", Const, 1, ""}, - {"ETHERTYPE_DLOG2", Const, 1, ""}, - {"ETHERTYPE_DN", Const, 1, ""}, - {"ETHERTYPE_DOGFIGHT", Const, 1, ""}, - {"ETHERTYPE_DSMD", Const, 1, ""}, - {"ETHERTYPE_ECMA", Const, 1, ""}, - {"ETHERTYPE_ENCRYPT", Const, 1, ""}, - {"ETHERTYPE_ES", Const, 1, ""}, - {"ETHERTYPE_EXCELAN", Const, 1, ""}, - {"ETHERTYPE_EXPERDATA", Const, 1, ""}, - {"ETHERTYPE_FLIP", Const, 1, ""}, - {"ETHERTYPE_FLOWCONTROL", Const, 1, ""}, - {"ETHERTYPE_FRARP", Const, 1, ""}, - {"ETHERTYPE_GENDYN", Const, 1, ""}, - {"ETHERTYPE_HAYES", Const, 1, ""}, - {"ETHERTYPE_HIPPI_FP", Const, 1, ""}, - {"ETHERTYPE_HITACHI", Const, 1, ""}, - {"ETHERTYPE_HP", Const, 1, ""}, - {"ETHERTYPE_IEEEPUP", Const, 1, ""}, - {"ETHERTYPE_IEEEPUPAT", Const, 1, ""}, - {"ETHERTYPE_IMLBL", Const, 1, ""}, - {"ETHERTYPE_IMLBLDIAG", Const, 1, ""}, - {"ETHERTYPE_IP", Const, 1, ""}, - {"ETHERTYPE_IPAS", Const, 1, ""}, - {"ETHERTYPE_IPV6", Const, 1, ""}, - {"ETHERTYPE_IPX", Const, 1, ""}, - {"ETHERTYPE_IPXNEW", Const, 1, ""}, - {"ETHERTYPE_KALPANA", Const, 1, ""}, - {"ETHERTYPE_LANBRIDGE", Const, 1, ""}, - {"ETHERTYPE_LANPROBE", Const, 1, ""}, - {"ETHERTYPE_LAT", Const, 1, ""}, - {"ETHERTYPE_LBACK", Const, 1, ""}, - {"ETHERTYPE_LITTLE", Const, 1, ""}, - {"ETHERTYPE_LLDP", Const, 1, ""}, - {"ETHERTYPE_LOGICRAFT", Const, 1, ""}, - {"ETHERTYPE_LOOPBACK", Const, 1, ""}, - {"ETHERTYPE_MATRA", Const, 1, ""}, - {"ETHERTYPE_MAX", Const, 1, ""}, - {"ETHERTYPE_MERIT", Const, 1, ""}, - {"ETHERTYPE_MICP", Const, 1, ""}, - {"ETHERTYPE_MOPDL", Const, 1, ""}, - {"ETHERTYPE_MOPRC", Const, 1, ""}, - {"ETHERTYPE_MOTOROLA", Const, 1, ""}, - {"ETHERTYPE_MPLS", Const, 1, ""}, - {"ETHERTYPE_MPLS_MCAST", Const, 1, ""}, - {"ETHERTYPE_MUMPS", Const, 1, ""}, - {"ETHERTYPE_NBPCC", Const, 1, ""}, - {"ETHERTYPE_NBPCLAIM", Const, 1, ""}, - {"ETHERTYPE_NBPCLREQ", Const, 1, ""}, - {"ETHERTYPE_NBPCLRSP", Const, 1, ""}, - {"ETHERTYPE_NBPCREQ", Const, 1, ""}, - {"ETHERTYPE_NBPCRSP", Const, 1, ""}, - {"ETHERTYPE_NBPDG", Const, 1, ""}, - {"ETHERTYPE_NBPDGB", Const, 1, ""}, - {"ETHERTYPE_NBPDLTE", Const, 1, ""}, - {"ETHERTYPE_NBPRAR", Const, 1, ""}, - {"ETHERTYPE_NBPRAS", Const, 1, ""}, - {"ETHERTYPE_NBPRST", Const, 1, ""}, - {"ETHERTYPE_NBPSCD", Const, 1, ""}, - {"ETHERTYPE_NBPVCD", Const, 1, ""}, - {"ETHERTYPE_NBS", Const, 1, ""}, - {"ETHERTYPE_NCD", Const, 1, ""}, - {"ETHERTYPE_NESTAR", Const, 1, ""}, - {"ETHERTYPE_NETBEUI", Const, 1, ""}, - {"ETHERTYPE_NOVELL", Const, 1, ""}, - {"ETHERTYPE_NS", Const, 1, ""}, - {"ETHERTYPE_NSAT", Const, 1, ""}, - {"ETHERTYPE_NSCOMPAT", Const, 1, ""}, - {"ETHERTYPE_NTRAILER", Const, 1, ""}, - {"ETHERTYPE_OS9", Const, 1, ""}, - {"ETHERTYPE_OS9NET", Const, 1, ""}, - {"ETHERTYPE_PACER", Const, 1, ""}, - {"ETHERTYPE_PAE", Const, 1, ""}, - {"ETHERTYPE_PCS", Const, 1, ""}, - {"ETHERTYPE_PLANNING", Const, 1, ""}, - {"ETHERTYPE_PPP", Const, 1, ""}, - {"ETHERTYPE_PPPOE", Const, 1, ""}, - {"ETHERTYPE_PPPOEDISC", Const, 1, ""}, - {"ETHERTYPE_PRIMENTS", Const, 1, ""}, - {"ETHERTYPE_PUP", Const, 1, ""}, - {"ETHERTYPE_PUPAT", Const, 1, ""}, - {"ETHERTYPE_QINQ", Const, 1, ""}, - {"ETHERTYPE_RACAL", Const, 1, ""}, - {"ETHERTYPE_RATIONAL", Const, 1, ""}, - {"ETHERTYPE_RAWFR", Const, 1, ""}, - {"ETHERTYPE_RCL", Const, 1, ""}, - {"ETHERTYPE_RDP", Const, 1, ""}, - {"ETHERTYPE_RETIX", Const, 1, ""}, - {"ETHERTYPE_REVARP", Const, 1, ""}, - {"ETHERTYPE_SCA", Const, 1, ""}, - {"ETHERTYPE_SECTRA", Const, 1, ""}, - {"ETHERTYPE_SECUREDATA", Const, 1, ""}, - {"ETHERTYPE_SGITW", Const, 1, ""}, - {"ETHERTYPE_SG_BOUNCE", Const, 1, ""}, - {"ETHERTYPE_SG_DIAG", Const, 1, ""}, - {"ETHERTYPE_SG_NETGAMES", Const, 1, ""}, - {"ETHERTYPE_SG_RESV", Const, 1, ""}, - {"ETHERTYPE_SIMNET", Const, 1, ""}, - {"ETHERTYPE_SLOW", Const, 1, ""}, - {"ETHERTYPE_SLOWPROTOCOLS", Const, 1, ""}, - {"ETHERTYPE_SNA", Const, 1, ""}, - {"ETHERTYPE_SNMP", Const, 1, ""}, - {"ETHERTYPE_SONIX", Const, 1, ""}, - {"ETHERTYPE_SPIDER", Const, 1, ""}, - {"ETHERTYPE_SPRITE", Const, 1, ""}, - {"ETHERTYPE_STP", Const, 1, ""}, - {"ETHERTYPE_TALARIS", Const, 1, ""}, - {"ETHERTYPE_TALARISMC", Const, 1, ""}, - {"ETHERTYPE_TCPCOMP", Const, 1, ""}, - {"ETHERTYPE_TCPSM", Const, 1, ""}, - {"ETHERTYPE_TEC", Const, 1, ""}, - {"ETHERTYPE_TIGAN", Const, 1, ""}, - {"ETHERTYPE_TRAIL", Const, 1, ""}, - {"ETHERTYPE_TRANSETHER", Const, 1, ""}, - {"ETHERTYPE_TYMSHARE", Const, 1, ""}, - {"ETHERTYPE_UBBST", Const, 1, ""}, - {"ETHERTYPE_UBDEBUG", Const, 1, ""}, - {"ETHERTYPE_UBDIAGLOOP", Const, 1, ""}, - {"ETHERTYPE_UBDL", Const, 1, ""}, - {"ETHERTYPE_UBNIU", Const, 1, ""}, - {"ETHERTYPE_UBNMC", Const, 1, ""}, - {"ETHERTYPE_VALID", Const, 1, ""}, - {"ETHERTYPE_VARIAN", Const, 1, ""}, - {"ETHERTYPE_VAXELN", Const, 1, ""}, - {"ETHERTYPE_VEECO", Const, 1, ""}, - {"ETHERTYPE_VEXP", Const, 1, ""}, - {"ETHERTYPE_VGLAB", Const, 1, ""}, - {"ETHERTYPE_VINES", Const, 1, ""}, - {"ETHERTYPE_VINESECHO", Const, 1, ""}, - {"ETHERTYPE_VINESLOOP", Const, 1, ""}, - {"ETHERTYPE_VITAL", Const, 1, ""}, - {"ETHERTYPE_VLAN", Const, 1, ""}, - {"ETHERTYPE_VLTLMAN", Const, 1, ""}, - {"ETHERTYPE_VPROD", Const, 1, ""}, - {"ETHERTYPE_VURESERVED", Const, 1, ""}, - {"ETHERTYPE_WATERLOO", Const, 1, ""}, - {"ETHERTYPE_WELLFLEET", Const, 1, ""}, - {"ETHERTYPE_X25", Const, 1, ""}, - {"ETHERTYPE_X75", Const, 1, ""}, - {"ETHERTYPE_XNSSM", Const, 1, ""}, - {"ETHERTYPE_XTP", Const, 1, ""}, - {"ETHER_ADDR_LEN", Const, 1, ""}, - {"ETHER_ALIGN", Const, 1, ""}, - {"ETHER_CRC_LEN", Const, 1, ""}, - {"ETHER_CRC_POLY_BE", Const, 1, ""}, - {"ETHER_CRC_POLY_LE", Const, 1, ""}, - {"ETHER_HDR_LEN", Const, 1, ""}, - {"ETHER_MAX_DIX_LEN", Const, 1, ""}, - {"ETHER_MAX_LEN", Const, 1, ""}, - {"ETHER_MAX_LEN_JUMBO", Const, 1, ""}, - {"ETHER_MIN_LEN", Const, 1, ""}, - {"ETHER_PPPOE_ENCAP_LEN", Const, 1, ""}, - {"ETHER_TYPE_LEN", Const, 1, ""}, - {"ETHER_VLAN_ENCAP_LEN", Const, 1, ""}, - {"ETH_P_1588", Const, 0, ""}, - {"ETH_P_8021Q", Const, 0, ""}, - {"ETH_P_802_2", Const, 0, ""}, - {"ETH_P_802_3", Const, 0, ""}, - {"ETH_P_AARP", Const, 0, ""}, - {"ETH_P_ALL", Const, 0, ""}, - {"ETH_P_AOE", Const, 0, ""}, - {"ETH_P_ARCNET", Const, 0, ""}, - {"ETH_P_ARP", Const, 0, ""}, - {"ETH_P_ATALK", Const, 0, ""}, - {"ETH_P_ATMFATE", Const, 0, ""}, - {"ETH_P_ATMMPOA", Const, 0, ""}, - {"ETH_P_AX25", Const, 0, ""}, - {"ETH_P_BPQ", Const, 0, ""}, - {"ETH_P_CAIF", Const, 0, ""}, - {"ETH_P_CAN", Const, 0, ""}, - {"ETH_P_CONTROL", Const, 0, ""}, - {"ETH_P_CUST", Const, 0, ""}, - {"ETH_P_DDCMP", Const, 0, ""}, - {"ETH_P_DEC", Const, 0, ""}, - {"ETH_P_DIAG", Const, 0, ""}, - {"ETH_P_DNA_DL", Const, 0, ""}, - {"ETH_P_DNA_RC", Const, 0, ""}, - {"ETH_P_DNA_RT", Const, 0, ""}, - {"ETH_P_DSA", Const, 0, ""}, - {"ETH_P_ECONET", Const, 0, ""}, - {"ETH_P_EDSA", Const, 0, ""}, - {"ETH_P_FCOE", Const, 0, ""}, - {"ETH_P_FIP", Const, 0, ""}, - {"ETH_P_HDLC", Const, 0, ""}, - {"ETH_P_IEEE802154", Const, 0, ""}, - {"ETH_P_IEEEPUP", Const, 0, ""}, - {"ETH_P_IEEEPUPAT", Const, 0, ""}, - {"ETH_P_IP", Const, 0, ""}, - {"ETH_P_IPV6", Const, 0, ""}, - {"ETH_P_IPX", Const, 0, ""}, - {"ETH_P_IRDA", Const, 0, ""}, - {"ETH_P_LAT", Const, 0, ""}, - {"ETH_P_LINK_CTL", Const, 0, ""}, - {"ETH_P_LOCALTALK", Const, 0, ""}, - {"ETH_P_LOOP", Const, 0, ""}, - {"ETH_P_MOBITEX", Const, 0, ""}, - {"ETH_P_MPLS_MC", Const, 0, ""}, - {"ETH_P_MPLS_UC", Const, 0, ""}, - {"ETH_P_PAE", Const, 0, ""}, - {"ETH_P_PAUSE", Const, 0, ""}, - {"ETH_P_PHONET", Const, 0, ""}, - {"ETH_P_PPPTALK", Const, 0, ""}, - {"ETH_P_PPP_DISC", Const, 0, ""}, - {"ETH_P_PPP_MP", Const, 0, ""}, - {"ETH_P_PPP_SES", Const, 0, ""}, - {"ETH_P_PUP", Const, 0, ""}, - {"ETH_P_PUPAT", Const, 0, ""}, - {"ETH_P_RARP", Const, 0, ""}, - {"ETH_P_SCA", Const, 0, ""}, - {"ETH_P_SLOW", Const, 0, ""}, - {"ETH_P_SNAP", Const, 0, ""}, - {"ETH_P_TEB", Const, 0, ""}, - {"ETH_P_TIPC", Const, 0, ""}, - {"ETH_P_TRAILER", Const, 0, ""}, - {"ETH_P_TR_802_2", Const, 0, ""}, - {"ETH_P_WAN_PPP", Const, 0, ""}, - {"ETH_P_WCCP", Const, 0, ""}, - {"ETH_P_X25", Const, 0, ""}, - {"ETIME", Const, 0, ""}, - {"ETIMEDOUT", Const, 0, ""}, - {"ETOOMANYREFS", Const, 0, ""}, - {"ETXTBSY", Const, 0, ""}, - {"EUCLEAN", Const, 0, ""}, - {"EUNATCH", Const, 0, ""}, - {"EUSERS", Const, 0, ""}, - {"EVFILT_AIO", Const, 0, ""}, - {"EVFILT_FS", Const, 0, ""}, - {"EVFILT_LIO", Const, 0, ""}, - {"EVFILT_MACHPORT", Const, 0, ""}, - {"EVFILT_PROC", Const, 0, ""}, - {"EVFILT_READ", Const, 0, ""}, - {"EVFILT_SIGNAL", Const, 0, ""}, - {"EVFILT_SYSCOUNT", Const, 0, ""}, - {"EVFILT_THREADMARKER", Const, 0, ""}, - {"EVFILT_TIMER", Const, 0, ""}, - {"EVFILT_USER", Const, 0, ""}, - {"EVFILT_VM", Const, 0, ""}, - {"EVFILT_VNODE", Const, 0, ""}, - {"EVFILT_WRITE", Const, 0, ""}, - {"EV_ADD", Const, 0, ""}, - {"EV_CLEAR", Const, 0, ""}, - {"EV_DELETE", Const, 0, ""}, - {"EV_DISABLE", Const, 0, ""}, - {"EV_DISPATCH", Const, 0, ""}, - {"EV_DROP", Const, 3, ""}, - {"EV_ENABLE", Const, 0, ""}, - {"EV_EOF", Const, 0, ""}, - {"EV_ERROR", Const, 0, ""}, - {"EV_FLAG0", Const, 0, ""}, - {"EV_FLAG1", Const, 0, ""}, - {"EV_ONESHOT", Const, 0, ""}, - {"EV_OOBAND", Const, 0, ""}, - {"EV_POLL", Const, 0, ""}, - {"EV_RECEIPT", Const, 0, ""}, - {"EV_SYSFLAGS", Const, 0, ""}, - {"EWINDOWS", Const, 0, ""}, - {"EWOULDBLOCK", Const, 0, ""}, - {"EXDEV", Const, 0, ""}, - {"EXFULL", Const, 0, ""}, - {"EXTA", Const, 0, ""}, - {"EXTB", Const, 0, ""}, - {"EXTPROC", Const, 0, ""}, - {"Environ", Func, 0, "func() []string"}, - {"EpollCreate", Func, 0, "func(size int) (fd int, err error)"}, - {"EpollCreate1", Func, 0, "func(flag int) (fd int, err error)"}, - {"EpollCtl", Func, 0, "func(epfd int, op int, fd int, event *EpollEvent) (err error)"}, - {"EpollEvent", Type, 0, ""}, - {"EpollEvent.Events", Field, 0, ""}, - {"EpollEvent.Fd", Field, 0, ""}, - {"EpollEvent.Pad", Field, 0, ""}, - {"EpollEvent.PadFd", Field, 0, ""}, - {"EpollWait", Func, 0, "func(epfd int, events []EpollEvent, msec int) (n int, err error)"}, - {"Errno", Type, 0, ""}, - {"EscapeArg", Func, 0, ""}, - {"Exchangedata", Func, 0, ""}, - {"Exec", Func, 0, "func(argv0 string, argv []string, envv []string) (err error)"}, - {"Exit", Func, 0, "func(code int)"}, - {"ExitProcess", Func, 0, ""}, - {"FD_CLOEXEC", Const, 0, ""}, - {"FD_SETSIZE", Const, 0, ""}, - {"FILE_ACTION_ADDED", Const, 0, ""}, - {"FILE_ACTION_MODIFIED", Const, 0, ""}, - {"FILE_ACTION_REMOVED", Const, 0, ""}, - {"FILE_ACTION_RENAMED_NEW_NAME", Const, 0, ""}, - {"FILE_ACTION_RENAMED_OLD_NAME", Const, 0, ""}, - {"FILE_APPEND_DATA", Const, 0, ""}, - {"FILE_ATTRIBUTE_ARCHIVE", Const, 0, ""}, - {"FILE_ATTRIBUTE_DIRECTORY", Const, 0, ""}, - {"FILE_ATTRIBUTE_HIDDEN", Const, 0, ""}, - {"FILE_ATTRIBUTE_NORMAL", Const, 0, ""}, - {"FILE_ATTRIBUTE_READONLY", Const, 0, ""}, - {"FILE_ATTRIBUTE_REPARSE_POINT", Const, 4, ""}, - {"FILE_ATTRIBUTE_SYSTEM", Const, 0, ""}, - {"FILE_BEGIN", Const, 0, ""}, - {"FILE_CURRENT", Const, 0, ""}, - {"FILE_END", Const, 0, ""}, - {"FILE_FLAG_BACKUP_SEMANTICS", Const, 0, ""}, - {"FILE_FLAG_OPEN_REPARSE_POINT", Const, 4, ""}, - {"FILE_FLAG_OVERLAPPED", Const, 0, ""}, - {"FILE_LIST_DIRECTORY", Const, 0, ""}, - {"FILE_MAP_COPY", Const, 0, ""}, - {"FILE_MAP_EXECUTE", Const, 0, ""}, - {"FILE_MAP_READ", Const, 0, ""}, - {"FILE_MAP_WRITE", Const, 0, ""}, - {"FILE_NOTIFY_CHANGE_ATTRIBUTES", Const, 0, ""}, - {"FILE_NOTIFY_CHANGE_CREATION", Const, 0, ""}, - {"FILE_NOTIFY_CHANGE_DIR_NAME", Const, 0, ""}, - {"FILE_NOTIFY_CHANGE_FILE_NAME", Const, 0, ""}, - {"FILE_NOTIFY_CHANGE_LAST_ACCESS", Const, 0, ""}, - {"FILE_NOTIFY_CHANGE_LAST_WRITE", Const, 0, ""}, - {"FILE_NOTIFY_CHANGE_SIZE", Const, 0, ""}, - {"FILE_SHARE_DELETE", Const, 0, ""}, - {"FILE_SHARE_READ", Const, 0, ""}, - {"FILE_SHARE_WRITE", Const, 0, ""}, - {"FILE_SKIP_COMPLETION_PORT_ON_SUCCESS", Const, 2, ""}, - {"FILE_SKIP_SET_EVENT_ON_HANDLE", Const, 2, ""}, - {"FILE_TYPE_CHAR", Const, 0, ""}, - {"FILE_TYPE_DISK", Const, 0, ""}, - {"FILE_TYPE_PIPE", Const, 0, ""}, - {"FILE_TYPE_REMOTE", Const, 0, ""}, - {"FILE_TYPE_UNKNOWN", Const, 0, ""}, - {"FILE_WRITE_ATTRIBUTES", Const, 0, ""}, - {"FLUSHO", Const, 0, ""}, - {"FORMAT_MESSAGE_ALLOCATE_BUFFER", Const, 0, ""}, - {"FORMAT_MESSAGE_ARGUMENT_ARRAY", Const, 0, ""}, - {"FORMAT_MESSAGE_FROM_HMODULE", Const, 0, ""}, - {"FORMAT_MESSAGE_FROM_STRING", Const, 0, ""}, - {"FORMAT_MESSAGE_FROM_SYSTEM", Const, 0, ""}, - {"FORMAT_MESSAGE_IGNORE_INSERTS", Const, 0, ""}, - {"FORMAT_MESSAGE_MAX_WIDTH_MASK", Const, 0, ""}, - {"FSCTL_GET_REPARSE_POINT", Const, 4, ""}, - {"F_ADDFILESIGS", Const, 0, ""}, - {"F_ADDSIGS", Const, 0, ""}, - {"F_ALLOCATEALL", Const, 0, ""}, - {"F_ALLOCATECONTIG", Const, 0, ""}, - {"F_CANCEL", Const, 0, ""}, - {"F_CHKCLEAN", Const, 0, ""}, - {"F_CLOSEM", Const, 1, ""}, - {"F_DUP2FD", Const, 0, ""}, - {"F_DUP2FD_CLOEXEC", Const, 1, ""}, - {"F_DUPFD", Const, 0, ""}, - {"F_DUPFD_CLOEXEC", Const, 0, ""}, - {"F_EXLCK", Const, 0, ""}, - {"F_FINDSIGS", Const, 16, ""}, - {"F_FLUSH_DATA", Const, 0, ""}, - {"F_FREEZE_FS", Const, 0, ""}, - {"F_FSCTL", Const, 1, ""}, - {"F_FSDIRMASK", Const, 1, ""}, - {"F_FSIN", Const, 1, ""}, - {"F_FSINOUT", Const, 1, ""}, - {"F_FSOUT", Const, 1, ""}, - {"F_FSPRIV", Const, 1, ""}, - {"F_FSVOID", Const, 1, ""}, - {"F_FULLFSYNC", Const, 0, ""}, - {"F_GETCODEDIR", Const, 16, ""}, - {"F_GETFD", Const, 0, ""}, - {"F_GETFL", Const, 0, ""}, - {"F_GETLEASE", Const, 0, ""}, - {"F_GETLK", Const, 0, ""}, - {"F_GETLK64", Const, 0, ""}, - {"F_GETLKPID", Const, 0, ""}, - {"F_GETNOSIGPIPE", Const, 0, ""}, - {"F_GETOWN", Const, 0, ""}, - {"F_GETOWN_EX", Const, 0, ""}, - {"F_GETPATH", Const, 0, ""}, - {"F_GETPATH_MTMINFO", Const, 0, ""}, - {"F_GETPIPE_SZ", Const, 0, ""}, - {"F_GETPROTECTIONCLASS", Const, 0, ""}, - {"F_GETPROTECTIONLEVEL", Const, 16, ""}, - {"F_GETSIG", Const, 0, ""}, - {"F_GLOBAL_NOCACHE", Const, 0, ""}, - {"F_LOCK", Const, 0, ""}, - {"F_LOG2PHYS", Const, 0, ""}, - {"F_LOG2PHYS_EXT", Const, 0, ""}, - {"F_MARKDEPENDENCY", Const, 0, ""}, - {"F_MAXFD", Const, 1, ""}, - {"F_NOCACHE", Const, 0, ""}, - {"F_NODIRECT", Const, 0, ""}, - {"F_NOTIFY", Const, 0, ""}, - {"F_OGETLK", Const, 0, ""}, - {"F_OK", Const, 0, ""}, - {"F_OSETLK", Const, 0, ""}, - {"F_OSETLKW", Const, 0, ""}, - {"F_PARAM_MASK", Const, 1, ""}, - {"F_PARAM_MAX", Const, 1, ""}, - {"F_PATHPKG_CHECK", Const, 0, ""}, - {"F_PEOFPOSMODE", Const, 0, ""}, - {"F_PREALLOCATE", Const, 0, ""}, - {"F_RDADVISE", Const, 0, ""}, - {"F_RDAHEAD", Const, 0, ""}, - {"F_RDLCK", Const, 0, ""}, - {"F_READAHEAD", Const, 0, ""}, - {"F_READBOOTSTRAP", Const, 0, ""}, - {"F_SETBACKINGSTORE", Const, 0, ""}, - {"F_SETFD", Const, 0, ""}, - {"F_SETFL", Const, 0, ""}, - {"F_SETLEASE", Const, 0, ""}, - {"F_SETLK", Const, 0, ""}, - {"F_SETLK64", Const, 0, ""}, - {"F_SETLKW", Const, 0, ""}, - {"F_SETLKW64", Const, 0, ""}, - {"F_SETLKWTIMEOUT", Const, 16, ""}, - {"F_SETLK_REMOTE", Const, 0, ""}, - {"F_SETNOSIGPIPE", Const, 0, ""}, - {"F_SETOWN", Const, 0, ""}, - {"F_SETOWN_EX", Const, 0, ""}, - {"F_SETPIPE_SZ", Const, 0, ""}, - {"F_SETPROTECTIONCLASS", Const, 0, ""}, - {"F_SETSIG", Const, 0, ""}, - {"F_SETSIZE", Const, 0, ""}, - {"F_SHLCK", Const, 0, ""}, - {"F_SINGLE_WRITER", Const, 16, ""}, - {"F_TEST", Const, 0, ""}, - {"F_THAW_FS", Const, 0, ""}, - {"F_TLOCK", Const, 0, ""}, - {"F_TRANSCODEKEY", Const, 16, ""}, - {"F_ULOCK", Const, 0, ""}, - {"F_UNLCK", Const, 0, ""}, - {"F_UNLCKSYS", Const, 0, ""}, - {"F_VOLPOSMODE", Const, 0, ""}, - {"F_WRITEBOOTSTRAP", Const, 0, ""}, - {"F_WRLCK", Const, 0, ""}, - {"Faccessat", Func, 0, "func(dirfd int, path string, mode uint32, flags int) (err error)"}, - {"Fallocate", Func, 0, "func(fd int, mode uint32, off int64, len int64) (err error)"}, - {"Fbootstraptransfer_t", Type, 0, ""}, - {"Fbootstraptransfer_t.Buffer", Field, 0, ""}, - {"Fbootstraptransfer_t.Length", Field, 0, ""}, - {"Fbootstraptransfer_t.Offset", Field, 0, ""}, - {"Fchdir", Func, 0, "func(fd int) (err error)"}, - {"Fchflags", Func, 0, ""}, - {"Fchmod", Func, 0, "func(fd int, mode uint32) (err error)"}, - {"Fchmodat", Func, 0, "func(dirfd int, path string, mode uint32, flags int) error"}, - {"Fchown", Func, 0, "func(fd int, uid int, gid int) (err error)"}, - {"Fchownat", Func, 0, "func(dirfd int, path string, uid int, gid int, flags int) (err error)"}, - {"FcntlFlock", Func, 3, "func(fd uintptr, cmd int, lk *Flock_t) error"}, - {"FdSet", Type, 0, ""}, - {"FdSet.Bits", Field, 0, ""}, - {"FdSet.X__fds_bits", Field, 0, ""}, - {"Fdatasync", Func, 0, "func(fd int) (err error)"}, - {"FileNotifyInformation", Type, 0, ""}, - {"FileNotifyInformation.Action", Field, 0, ""}, - {"FileNotifyInformation.FileName", Field, 0, ""}, - {"FileNotifyInformation.FileNameLength", Field, 0, ""}, - {"FileNotifyInformation.NextEntryOffset", Field, 0, ""}, - {"Filetime", Type, 0, ""}, - {"Filetime.HighDateTime", Field, 0, ""}, - {"Filetime.LowDateTime", Field, 0, ""}, - {"FindClose", Func, 0, ""}, - {"FindFirstFile", Func, 0, ""}, - {"FindNextFile", Func, 0, ""}, - {"Flock", Func, 0, "func(fd int, how int) (err error)"}, - {"Flock_t", Type, 0, ""}, - {"Flock_t.Len", Field, 0, ""}, - {"Flock_t.Pad_cgo_0", Field, 0, ""}, - {"Flock_t.Pad_cgo_1", Field, 3, ""}, - {"Flock_t.Pid", Field, 0, ""}, - {"Flock_t.Start", Field, 0, ""}, - {"Flock_t.Sysid", Field, 0, ""}, - {"Flock_t.Type", Field, 0, ""}, - {"Flock_t.Whence", Field, 0, ""}, - {"FlushBpf", Func, 0, ""}, - {"FlushFileBuffers", Func, 0, ""}, - {"FlushViewOfFile", Func, 0, ""}, - {"ForkExec", Func, 0, "func(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)"}, - {"ForkLock", Var, 0, ""}, - {"FormatMessage", Func, 0, ""}, - {"Fpathconf", Func, 0, ""}, - {"FreeAddrInfoW", Func, 1, ""}, - {"FreeEnvironmentStrings", Func, 0, ""}, - {"FreeLibrary", Func, 0, ""}, - {"Fsid", Type, 0, ""}, - {"Fsid.Val", Field, 0, ""}, - {"Fsid.X__fsid_val", Field, 2, ""}, - {"Fsid.X__val", Field, 0, ""}, - {"Fstat", Func, 0, "func(fd int, stat *Stat_t) (err error)"}, - {"Fstatat", Func, 12, ""}, - {"Fstatfs", Func, 0, "func(fd int, buf *Statfs_t) (err error)"}, - {"Fstore_t", Type, 0, ""}, - {"Fstore_t.Bytesalloc", Field, 0, ""}, - {"Fstore_t.Flags", Field, 0, ""}, - {"Fstore_t.Length", Field, 0, ""}, - {"Fstore_t.Offset", Field, 0, ""}, - {"Fstore_t.Posmode", Field, 0, ""}, - {"Fsync", Func, 0, "func(fd int) (err error)"}, - {"Ftruncate", Func, 0, "func(fd int, length int64) (err error)"}, - {"FullPath", Func, 4, ""}, - {"Futimes", Func, 0, "func(fd int, tv []Timeval) (err error)"}, - {"Futimesat", Func, 0, "func(dirfd int, path string, tv []Timeval) (err error)"}, - {"GENERIC_ALL", Const, 0, ""}, - {"GENERIC_EXECUTE", Const, 0, ""}, - {"GENERIC_READ", Const, 0, ""}, - {"GENERIC_WRITE", Const, 0, ""}, - {"GUID", Type, 1, ""}, - {"GUID.Data1", Field, 1, ""}, - {"GUID.Data2", Field, 1, ""}, - {"GUID.Data3", Field, 1, ""}, - {"GUID.Data4", Field, 1, ""}, - {"GetAcceptExSockaddrs", Func, 0, ""}, - {"GetAdaptersInfo", Func, 0, ""}, - {"GetAddrInfoW", Func, 1, ""}, - {"GetCommandLine", Func, 0, ""}, - {"GetComputerName", Func, 0, ""}, - {"GetConsoleMode", Func, 1, ""}, - {"GetCurrentDirectory", Func, 0, ""}, - {"GetCurrentProcess", Func, 0, ""}, - {"GetEnvironmentStrings", Func, 0, ""}, - {"GetEnvironmentVariable", Func, 0, ""}, - {"GetExitCodeProcess", Func, 0, ""}, - {"GetFileAttributes", Func, 0, ""}, - {"GetFileAttributesEx", Func, 0, ""}, - {"GetFileExInfoStandard", Const, 0, ""}, - {"GetFileExMaxInfoLevel", Const, 0, ""}, - {"GetFileInformationByHandle", Func, 0, ""}, - {"GetFileType", Func, 0, ""}, - {"GetFullPathName", Func, 0, ""}, - {"GetHostByName", Func, 0, ""}, - {"GetIfEntry", Func, 0, ""}, - {"GetLastError", Func, 0, ""}, - {"GetLengthSid", Func, 0, ""}, - {"GetLongPathName", Func, 0, ""}, - {"GetProcAddress", Func, 0, ""}, - {"GetProcessTimes", Func, 0, ""}, - {"GetProtoByName", Func, 0, ""}, - {"GetQueuedCompletionStatus", Func, 0, ""}, - {"GetServByName", Func, 0, ""}, - {"GetShortPathName", Func, 0, ""}, - {"GetStartupInfo", Func, 0, ""}, - {"GetStdHandle", Func, 0, ""}, - {"GetSystemTimeAsFileTime", Func, 0, ""}, - {"GetTempPath", Func, 0, ""}, - {"GetTimeZoneInformation", Func, 0, ""}, - {"GetTokenInformation", Func, 0, ""}, - {"GetUserNameEx", Func, 0, ""}, - {"GetUserProfileDirectory", Func, 0, ""}, - {"GetVersion", Func, 0, ""}, - {"Getcwd", Func, 0, "func(buf []byte) (n int, err error)"}, - {"Getdents", Func, 0, "func(fd int, buf []byte) (n int, err error)"}, - {"Getdirentries", Func, 0, ""}, - {"Getdtablesize", Func, 0, ""}, - {"Getegid", Func, 0, "func() (egid int)"}, - {"Getenv", Func, 0, "func(key string) (value string, found bool)"}, - {"Geteuid", Func, 0, "func() (euid int)"}, - {"Getfsstat", Func, 0, ""}, - {"Getgid", Func, 0, "func() (gid int)"}, - {"Getgroups", Func, 0, "func() (gids []int, err error)"}, - {"Getpagesize", Func, 0, "func() int"}, - {"Getpeername", Func, 0, "func(fd int) (sa Sockaddr, err error)"}, - {"Getpgid", Func, 0, "func(pid int) (pgid int, err error)"}, - {"Getpgrp", Func, 0, "func() (pid int)"}, - {"Getpid", Func, 0, "func() (pid int)"}, - {"Getppid", Func, 0, "func() (ppid int)"}, - {"Getpriority", Func, 0, "func(which int, who int) (prio int, err error)"}, - {"Getrlimit", Func, 0, "func(resource int, rlim *Rlimit) (err error)"}, - {"Getrusage", Func, 0, "func(who int, rusage *Rusage) (err error)"}, - {"Getsid", Func, 0, ""}, - {"Getsockname", Func, 0, "func(fd int) (sa Sockaddr, err error)"}, - {"Getsockopt", Func, 1, ""}, - {"GetsockoptByte", Func, 0, ""}, - {"GetsockoptICMPv6Filter", Func, 2, "func(fd int, level int, opt int) (*ICMPv6Filter, error)"}, - {"GetsockoptIPMreq", Func, 0, "func(fd int, level int, opt int) (*IPMreq, error)"}, - {"GetsockoptIPMreqn", Func, 0, "func(fd int, level int, opt int) (*IPMreqn, error)"}, - {"GetsockoptIPv6MTUInfo", Func, 2, "func(fd int, level int, opt int) (*IPv6MTUInfo, error)"}, - {"GetsockoptIPv6Mreq", Func, 0, "func(fd int, level int, opt int) (*IPv6Mreq, error)"}, - {"GetsockoptInet4Addr", Func, 0, "func(fd int, level int, opt int) (value [4]byte, err error)"}, - {"GetsockoptInt", Func, 0, "func(fd int, level int, opt int) (value int, err error)"}, - {"GetsockoptUcred", Func, 1, "func(fd int, level int, opt int) (*Ucred, error)"}, - {"Gettid", Func, 0, "func() (tid int)"}, - {"Gettimeofday", Func, 0, "func(tv *Timeval) (err error)"}, - {"Getuid", Func, 0, "func() (uid int)"}, - {"Getwd", Func, 0, "func() (wd string, err error)"}, - {"Getxattr", Func, 1, "func(path string, attr string, dest []byte) (sz int, err error)"}, - {"HANDLE_FLAG_INHERIT", Const, 0, ""}, - {"HKEY_CLASSES_ROOT", Const, 0, ""}, - {"HKEY_CURRENT_CONFIG", Const, 0, ""}, - {"HKEY_CURRENT_USER", Const, 0, ""}, - {"HKEY_DYN_DATA", Const, 0, ""}, - {"HKEY_LOCAL_MACHINE", Const, 0, ""}, - {"HKEY_PERFORMANCE_DATA", Const, 0, ""}, - {"HKEY_USERS", Const, 0, ""}, - {"HUPCL", Const, 0, ""}, - {"Handle", Type, 0, ""}, - {"Hostent", Type, 0, ""}, - {"Hostent.AddrList", Field, 0, ""}, - {"Hostent.AddrType", Field, 0, ""}, - {"Hostent.Aliases", Field, 0, ""}, - {"Hostent.Length", Field, 0, ""}, - {"Hostent.Name", Field, 0, ""}, - {"ICANON", Const, 0, ""}, - {"ICMP6_FILTER", Const, 2, ""}, - {"ICMPV6_FILTER", Const, 2, ""}, - {"ICMPv6Filter", Type, 2, ""}, - {"ICMPv6Filter.Data", Field, 2, ""}, - {"ICMPv6Filter.Filt", Field, 2, ""}, - {"ICRNL", Const, 0, ""}, - {"IEXTEN", Const, 0, ""}, - {"IFAN_ARRIVAL", Const, 1, ""}, - {"IFAN_DEPARTURE", Const, 1, ""}, - {"IFA_ADDRESS", Const, 0, ""}, - {"IFA_ANYCAST", Const, 0, ""}, - {"IFA_BROADCAST", Const, 0, ""}, - {"IFA_CACHEINFO", Const, 0, ""}, - {"IFA_F_DADFAILED", Const, 0, ""}, - {"IFA_F_DEPRECATED", Const, 0, ""}, - {"IFA_F_HOMEADDRESS", Const, 0, ""}, - {"IFA_F_NODAD", Const, 0, ""}, - {"IFA_F_OPTIMISTIC", Const, 0, ""}, - {"IFA_F_PERMANENT", Const, 0, ""}, - {"IFA_F_SECONDARY", Const, 0, ""}, - {"IFA_F_TEMPORARY", Const, 0, ""}, - {"IFA_F_TENTATIVE", Const, 0, ""}, - {"IFA_LABEL", Const, 0, ""}, - {"IFA_LOCAL", Const, 0, ""}, - {"IFA_MAX", Const, 0, ""}, - {"IFA_MULTICAST", Const, 0, ""}, - {"IFA_ROUTE", Const, 1, ""}, - {"IFA_UNSPEC", Const, 0, ""}, - {"IFF_ALLMULTI", Const, 0, ""}, - {"IFF_ALTPHYS", Const, 0, ""}, - {"IFF_AUTOMEDIA", Const, 0, ""}, - {"IFF_BROADCAST", Const, 0, ""}, - {"IFF_CANTCHANGE", Const, 0, ""}, - {"IFF_CANTCONFIG", Const, 1, ""}, - {"IFF_DEBUG", Const, 0, ""}, - {"IFF_DRV_OACTIVE", Const, 0, ""}, - {"IFF_DRV_RUNNING", Const, 0, ""}, - {"IFF_DYING", Const, 0, ""}, - {"IFF_DYNAMIC", Const, 0, ""}, - {"IFF_LINK0", Const, 0, ""}, - {"IFF_LINK1", Const, 0, ""}, - {"IFF_LINK2", Const, 0, ""}, - {"IFF_LOOPBACK", Const, 0, ""}, - {"IFF_MASTER", Const, 0, ""}, - {"IFF_MONITOR", Const, 0, ""}, - {"IFF_MULTICAST", Const, 0, ""}, - {"IFF_NOARP", Const, 0, ""}, - {"IFF_NOTRAILERS", Const, 0, ""}, - {"IFF_NO_PI", Const, 0, ""}, - {"IFF_OACTIVE", Const, 0, ""}, - {"IFF_ONE_QUEUE", Const, 0, ""}, - {"IFF_POINTOPOINT", Const, 0, ""}, - {"IFF_POINTTOPOINT", Const, 0, ""}, - {"IFF_PORTSEL", Const, 0, ""}, - {"IFF_PPROMISC", Const, 0, ""}, - {"IFF_PROMISC", Const, 0, ""}, - {"IFF_RENAMING", Const, 0, ""}, - {"IFF_RUNNING", Const, 0, ""}, - {"IFF_SIMPLEX", Const, 0, ""}, - {"IFF_SLAVE", Const, 0, ""}, - {"IFF_SMART", Const, 0, ""}, - {"IFF_STATICARP", Const, 0, ""}, - {"IFF_TAP", Const, 0, ""}, - {"IFF_TUN", Const, 0, ""}, - {"IFF_TUN_EXCL", Const, 0, ""}, - {"IFF_UP", Const, 0, ""}, - {"IFF_VNET_HDR", Const, 0, ""}, - {"IFLA_ADDRESS", Const, 0, ""}, - {"IFLA_BROADCAST", Const, 0, ""}, - {"IFLA_COST", Const, 0, ""}, - {"IFLA_IFALIAS", Const, 0, ""}, - {"IFLA_IFNAME", Const, 0, ""}, - {"IFLA_LINK", Const, 0, ""}, - {"IFLA_LINKINFO", Const, 0, ""}, - {"IFLA_LINKMODE", Const, 0, ""}, - {"IFLA_MAP", Const, 0, ""}, - {"IFLA_MASTER", Const, 0, ""}, - {"IFLA_MAX", Const, 0, ""}, - {"IFLA_MTU", Const, 0, ""}, - {"IFLA_NET_NS_PID", Const, 0, ""}, - {"IFLA_OPERSTATE", Const, 0, ""}, - {"IFLA_PRIORITY", Const, 0, ""}, - {"IFLA_PROTINFO", Const, 0, ""}, - {"IFLA_QDISC", Const, 0, ""}, - {"IFLA_STATS", Const, 0, ""}, - {"IFLA_TXQLEN", Const, 0, ""}, - {"IFLA_UNSPEC", Const, 0, ""}, - {"IFLA_WEIGHT", Const, 0, ""}, - {"IFLA_WIRELESS", Const, 0, ""}, - {"IFNAMSIZ", Const, 0, ""}, - {"IFT_1822", Const, 0, ""}, - {"IFT_A12MPPSWITCH", Const, 0, ""}, - {"IFT_AAL2", Const, 0, ""}, - {"IFT_AAL5", Const, 0, ""}, - {"IFT_ADSL", Const, 0, ""}, - {"IFT_AFLANE8023", Const, 0, ""}, - {"IFT_AFLANE8025", Const, 0, ""}, - {"IFT_ARAP", Const, 0, ""}, - {"IFT_ARCNET", Const, 0, ""}, - {"IFT_ARCNETPLUS", Const, 0, ""}, - {"IFT_ASYNC", Const, 0, ""}, - {"IFT_ATM", Const, 0, ""}, - {"IFT_ATMDXI", Const, 0, ""}, - {"IFT_ATMFUNI", Const, 0, ""}, - {"IFT_ATMIMA", Const, 0, ""}, - {"IFT_ATMLOGICAL", Const, 0, ""}, - {"IFT_ATMRADIO", Const, 0, ""}, - {"IFT_ATMSUBINTERFACE", Const, 0, ""}, - {"IFT_ATMVCIENDPT", Const, 0, ""}, - {"IFT_ATMVIRTUAL", Const, 0, ""}, - {"IFT_BGPPOLICYACCOUNTING", Const, 0, ""}, - {"IFT_BLUETOOTH", Const, 1, ""}, - {"IFT_BRIDGE", Const, 0, ""}, - {"IFT_BSC", Const, 0, ""}, - {"IFT_CARP", Const, 0, ""}, - {"IFT_CCTEMUL", Const, 0, ""}, - {"IFT_CELLULAR", Const, 0, ""}, - {"IFT_CEPT", Const, 0, ""}, - {"IFT_CES", Const, 0, ""}, - {"IFT_CHANNEL", Const, 0, ""}, - {"IFT_CNR", Const, 0, ""}, - {"IFT_COFFEE", Const, 0, ""}, - {"IFT_COMPOSITELINK", Const, 0, ""}, - {"IFT_DCN", Const, 0, ""}, - {"IFT_DIGITALPOWERLINE", Const, 0, ""}, - {"IFT_DIGITALWRAPPEROVERHEADCHANNEL", Const, 0, ""}, - {"IFT_DLSW", Const, 0, ""}, - {"IFT_DOCSCABLEDOWNSTREAM", Const, 0, ""}, - {"IFT_DOCSCABLEMACLAYER", Const, 0, ""}, - {"IFT_DOCSCABLEUPSTREAM", Const, 0, ""}, - {"IFT_DOCSCABLEUPSTREAMCHANNEL", Const, 1, ""}, - {"IFT_DS0", Const, 0, ""}, - {"IFT_DS0BUNDLE", Const, 0, ""}, - {"IFT_DS1FDL", Const, 0, ""}, - {"IFT_DS3", Const, 0, ""}, - {"IFT_DTM", Const, 0, ""}, - {"IFT_DUMMY", Const, 1, ""}, - {"IFT_DVBASILN", Const, 0, ""}, - {"IFT_DVBASIOUT", Const, 0, ""}, - {"IFT_DVBRCCDOWNSTREAM", Const, 0, ""}, - {"IFT_DVBRCCMACLAYER", Const, 0, ""}, - {"IFT_DVBRCCUPSTREAM", Const, 0, ""}, - {"IFT_ECONET", Const, 1, ""}, - {"IFT_ENC", Const, 0, ""}, - {"IFT_EON", Const, 0, ""}, - {"IFT_EPLRS", Const, 0, ""}, - {"IFT_ESCON", Const, 0, ""}, - {"IFT_ETHER", Const, 0, ""}, - {"IFT_FAITH", Const, 0, ""}, - {"IFT_FAST", Const, 0, ""}, - {"IFT_FASTETHER", Const, 0, ""}, - {"IFT_FASTETHERFX", Const, 0, ""}, - {"IFT_FDDI", Const, 0, ""}, - {"IFT_FIBRECHANNEL", Const, 0, ""}, - {"IFT_FRAMERELAYINTERCONNECT", Const, 0, ""}, - {"IFT_FRAMERELAYMPI", Const, 0, ""}, - {"IFT_FRDLCIENDPT", Const, 0, ""}, - {"IFT_FRELAY", Const, 0, ""}, - {"IFT_FRELAYDCE", Const, 0, ""}, - {"IFT_FRF16MFRBUNDLE", Const, 0, ""}, - {"IFT_FRFORWARD", Const, 0, ""}, - {"IFT_G703AT2MB", Const, 0, ""}, - {"IFT_G703AT64K", Const, 0, ""}, - {"IFT_GIF", Const, 0, ""}, - {"IFT_GIGABITETHERNET", Const, 0, ""}, - {"IFT_GR303IDT", Const, 0, ""}, - {"IFT_GR303RDT", Const, 0, ""}, - {"IFT_H323GATEKEEPER", Const, 0, ""}, - {"IFT_H323PROXY", Const, 0, ""}, - {"IFT_HDH1822", Const, 0, ""}, - {"IFT_HDLC", Const, 0, ""}, - {"IFT_HDSL2", Const, 0, ""}, - {"IFT_HIPERLAN2", Const, 0, ""}, - {"IFT_HIPPI", Const, 0, ""}, - {"IFT_HIPPIINTERFACE", Const, 0, ""}, - {"IFT_HOSTPAD", Const, 0, ""}, - {"IFT_HSSI", Const, 0, ""}, - {"IFT_HY", Const, 0, ""}, - {"IFT_IBM370PARCHAN", Const, 0, ""}, - {"IFT_IDSL", Const, 0, ""}, - {"IFT_IEEE1394", Const, 0, ""}, - {"IFT_IEEE80211", Const, 0, ""}, - {"IFT_IEEE80212", Const, 0, ""}, - {"IFT_IEEE8023ADLAG", Const, 0, ""}, - {"IFT_IFGSN", Const, 0, ""}, - {"IFT_IMT", Const, 0, ""}, - {"IFT_INFINIBAND", Const, 1, ""}, - {"IFT_INTERLEAVE", Const, 0, ""}, - {"IFT_IP", Const, 0, ""}, - {"IFT_IPFORWARD", Const, 0, ""}, - {"IFT_IPOVERATM", Const, 0, ""}, - {"IFT_IPOVERCDLC", Const, 0, ""}, - {"IFT_IPOVERCLAW", Const, 0, ""}, - {"IFT_IPSWITCH", Const, 0, ""}, - {"IFT_IPXIP", Const, 0, ""}, - {"IFT_ISDN", Const, 0, ""}, - {"IFT_ISDNBASIC", Const, 0, ""}, - {"IFT_ISDNPRIMARY", Const, 0, ""}, - {"IFT_ISDNS", Const, 0, ""}, - {"IFT_ISDNU", Const, 0, ""}, - {"IFT_ISO88022LLC", Const, 0, ""}, - {"IFT_ISO88023", Const, 0, ""}, - {"IFT_ISO88024", Const, 0, ""}, - {"IFT_ISO88025", Const, 0, ""}, - {"IFT_ISO88025CRFPINT", Const, 0, ""}, - {"IFT_ISO88025DTR", Const, 0, ""}, - {"IFT_ISO88025FIBER", Const, 0, ""}, - {"IFT_ISO88026", Const, 0, ""}, - {"IFT_ISUP", Const, 0, ""}, - {"IFT_L2VLAN", Const, 0, ""}, - {"IFT_L3IPVLAN", Const, 0, ""}, - {"IFT_L3IPXVLAN", Const, 0, ""}, - {"IFT_LAPB", Const, 0, ""}, - {"IFT_LAPD", Const, 0, ""}, - {"IFT_LAPF", Const, 0, ""}, - {"IFT_LINEGROUP", Const, 1, ""}, - {"IFT_LOCALTALK", Const, 0, ""}, - {"IFT_LOOP", Const, 0, ""}, - {"IFT_MEDIAMAILOVERIP", Const, 0, ""}, - {"IFT_MFSIGLINK", Const, 0, ""}, - {"IFT_MIOX25", Const, 0, ""}, - {"IFT_MODEM", Const, 0, ""}, - {"IFT_MPC", Const, 0, ""}, - {"IFT_MPLS", Const, 0, ""}, - {"IFT_MPLSTUNNEL", Const, 0, ""}, - {"IFT_MSDSL", Const, 0, ""}, - {"IFT_MVL", Const, 0, ""}, - {"IFT_MYRINET", Const, 0, ""}, - {"IFT_NFAS", Const, 0, ""}, - {"IFT_NSIP", Const, 0, ""}, - {"IFT_OPTICALCHANNEL", Const, 0, ""}, - {"IFT_OPTICALTRANSPORT", Const, 0, ""}, - {"IFT_OTHER", Const, 0, ""}, - {"IFT_P10", Const, 0, ""}, - {"IFT_P80", Const, 0, ""}, - {"IFT_PARA", Const, 0, ""}, - {"IFT_PDP", Const, 0, ""}, - {"IFT_PFLOG", Const, 0, ""}, - {"IFT_PFLOW", Const, 1, ""}, - {"IFT_PFSYNC", Const, 0, ""}, - {"IFT_PLC", Const, 0, ""}, - {"IFT_PON155", Const, 1, ""}, - {"IFT_PON622", Const, 1, ""}, - {"IFT_POS", Const, 0, ""}, - {"IFT_PPP", Const, 0, ""}, - {"IFT_PPPMULTILINKBUNDLE", Const, 0, ""}, - {"IFT_PROPATM", Const, 1, ""}, - {"IFT_PROPBWAP2MP", Const, 0, ""}, - {"IFT_PROPCNLS", Const, 0, ""}, - {"IFT_PROPDOCSWIRELESSDOWNSTREAM", Const, 0, ""}, - {"IFT_PROPDOCSWIRELESSMACLAYER", Const, 0, ""}, - {"IFT_PROPDOCSWIRELESSUPSTREAM", Const, 0, ""}, - {"IFT_PROPMUX", Const, 0, ""}, - {"IFT_PROPVIRTUAL", Const, 0, ""}, - {"IFT_PROPWIRELESSP2P", Const, 0, ""}, - {"IFT_PTPSERIAL", Const, 0, ""}, - {"IFT_PVC", Const, 0, ""}, - {"IFT_Q2931", Const, 1, ""}, - {"IFT_QLLC", Const, 0, ""}, - {"IFT_RADIOMAC", Const, 0, ""}, - {"IFT_RADSL", Const, 0, ""}, - {"IFT_REACHDSL", Const, 0, ""}, - {"IFT_RFC1483", Const, 0, ""}, - {"IFT_RS232", Const, 0, ""}, - {"IFT_RSRB", Const, 0, ""}, - {"IFT_SDLC", Const, 0, ""}, - {"IFT_SDSL", Const, 0, ""}, - {"IFT_SHDSL", Const, 0, ""}, - {"IFT_SIP", Const, 0, ""}, - {"IFT_SIPSIG", Const, 1, ""}, - {"IFT_SIPTG", Const, 1, ""}, - {"IFT_SLIP", Const, 0, ""}, - {"IFT_SMDSDXI", Const, 0, ""}, - {"IFT_SMDSICIP", Const, 0, ""}, - {"IFT_SONET", Const, 0, ""}, - {"IFT_SONETOVERHEADCHANNEL", Const, 0, ""}, - {"IFT_SONETPATH", Const, 0, ""}, - {"IFT_SONETVT", Const, 0, ""}, - {"IFT_SRP", Const, 0, ""}, - {"IFT_SS7SIGLINK", Const, 0, ""}, - {"IFT_STACKTOSTACK", Const, 0, ""}, - {"IFT_STARLAN", Const, 0, ""}, - {"IFT_STF", Const, 0, ""}, - {"IFT_T1", Const, 0, ""}, - {"IFT_TDLC", Const, 0, ""}, - {"IFT_TELINK", Const, 1, ""}, - {"IFT_TERMPAD", Const, 0, ""}, - {"IFT_TR008", Const, 0, ""}, - {"IFT_TRANSPHDLC", Const, 0, ""}, - {"IFT_TUNNEL", Const, 0, ""}, - {"IFT_ULTRA", Const, 0, ""}, - {"IFT_USB", Const, 0, ""}, - {"IFT_V11", Const, 0, ""}, - {"IFT_V35", Const, 0, ""}, - {"IFT_V36", Const, 0, ""}, - {"IFT_V37", Const, 0, ""}, - {"IFT_VDSL", Const, 0, ""}, - {"IFT_VIRTUALIPADDRESS", Const, 0, ""}, - {"IFT_VIRTUALTG", Const, 1, ""}, - {"IFT_VOICEDID", Const, 1, ""}, - {"IFT_VOICEEM", Const, 0, ""}, - {"IFT_VOICEEMFGD", Const, 1, ""}, - {"IFT_VOICEENCAP", Const, 0, ""}, - {"IFT_VOICEFGDEANA", Const, 1, ""}, - {"IFT_VOICEFXO", Const, 0, ""}, - {"IFT_VOICEFXS", Const, 0, ""}, - {"IFT_VOICEOVERATM", Const, 0, ""}, - {"IFT_VOICEOVERCABLE", Const, 1, ""}, - {"IFT_VOICEOVERFRAMERELAY", Const, 0, ""}, - {"IFT_VOICEOVERIP", Const, 0, ""}, - {"IFT_X213", Const, 0, ""}, - {"IFT_X25", Const, 0, ""}, - {"IFT_X25DDN", Const, 0, ""}, - {"IFT_X25HUNTGROUP", Const, 0, ""}, - {"IFT_X25MLP", Const, 0, ""}, - {"IFT_X25PLE", Const, 0, ""}, - {"IFT_XETHER", Const, 0, ""}, - {"IGNBRK", Const, 0, ""}, - {"IGNCR", Const, 0, ""}, - {"IGNORE", Const, 0, ""}, - {"IGNPAR", Const, 0, ""}, - {"IMAXBEL", Const, 0, ""}, - {"INFINITE", Const, 0, ""}, - {"INLCR", Const, 0, ""}, - {"INPCK", Const, 0, ""}, - {"INVALID_FILE_ATTRIBUTES", Const, 0, ""}, - {"IN_ACCESS", Const, 0, ""}, - {"IN_ALL_EVENTS", Const, 0, ""}, - {"IN_ATTRIB", Const, 0, ""}, - {"IN_CLASSA_HOST", Const, 0, ""}, - {"IN_CLASSA_MAX", Const, 0, ""}, - {"IN_CLASSA_NET", Const, 0, ""}, - {"IN_CLASSA_NSHIFT", Const, 0, ""}, - {"IN_CLASSB_HOST", Const, 0, ""}, - {"IN_CLASSB_MAX", Const, 0, ""}, - {"IN_CLASSB_NET", Const, 0, ""}, - {"IN_CLASSB_NSHIFT", Const, 0, ""}, - {"IN_CLASSC_HOST", Const, 0, ""}, - {"IN_CLASSC_NET", Const, 0, ""}, - {"IN_CLASSC_NSHIFT", Const, 0, ""}, - {"IN_CLASSD_HOST", Const, 0, ""}, - {"IN_CLASSD_NET", Const, 0, ""}, - {"IN_CLASSD_NSHIFT", Const, 0, ""}, - {"IN_CLOEXEC", Const, 0, ""}, - {"IN_CLOSE", Const, 0, ""}, - {"IN_CLOSE_NOWRITE", Const, 0, ""}, - {"IN_CLOSE_WRITE", Const, 0, ""}, - {"IN_CREATE", Const, 0, ""}, - {"IN_DELETE", Const, 0, ""}, - {"IN_DELETE_SELF", Const, 0, ""}, - {"IN_DONT_FOLLOW", Const, 0, ""}, - {"IN_EXCL_UNLINK", Const, 0, ""}, - {"IN_IGNORED", Const, 0, ""}, - {"IN_ISDIR", Const, 0, ""}, - {"IN_LINKLOCALNETNUM", Const, 0, ""}, - {"IN_LOOPBACKNET", Const, 0, ""}, - {"IN_MASK_ADD", Const, 0, ""}, - {"IN_MODIFY", Const, 0, ""}, - {"IN_MOVE", Const, 0, ""}, - {"IN_MOVED_FROM", Const, 0, ""}, - {"IN_MOVED_TO", Const, 0, ""}, - {"IN_MOVE_SELF", Const, 0, ""}, - {"IN_NONBLOCK", Const, 0, ""}, - {"IN_ONESHOT", Const, 0, ""}, - {"IN_ONLYDIR", Const, 0, ""}, - {"IN_OPEN", Const, 0, ""}, - {"IN_Q_OVERFLOW", Const, 0, ""}, - {"IN_RFC3021_HOST", Const, 1, ""}, - {"IN_RFC3021_MASK", Const, 1, ""}, - {"IN_RFC3021_NET", Const, 1, ""}, - {"IN_RFC3021_NSHIFT", Const, 1, ""}, - {"IN_UNMOUNT", Const, 0, ""}, - {"IOC_IN", Const, 1, ""}, - {"IOC_INOUT", Const, 1, ""}, - {"IOC_OUT", Const, 1, ""}, - {"IOC_VENDOR", Const, 3, ""}, - {"IOC_WS2", Const, 1, ""}, - {"IO_REPARSE_TAG_SYMLINK", Const, 4, ""}, - {"IPMreq", Type, 0, ""}, - {"IPMreq.Interface", Field, 0, ""}, - {"IPMreq.Multiaddr", Field, 0, ""}, - {"IPMreqn", Type, 0, ""}, - {"IPMreqn.Address", Field, 0, ""}, - {"IPMreqn.Ifindex", Field, 0, ""}, - {"IPMreqn.Multiaddr", Field, 0, ""}, - {"IPPROTO_3PC", Const, 0, ""}, - {"IPPROTO_ADFS", Const, 0, ""}, - {"IPPROTO_AH", Const, 0, ""}, - {"IPPROTO_AHIP", Const, 0, ""}, - {"IPPROTO_APES", Const, 0, ""}, - {"IPPROTO_ARGUS", Const, 0, ""}, - {"IPPROTO_AX25", Const, 0, ""}, - {"IPPROTO_BHA", Const, 0, ""}, - {"IPPROTO_BLT", Const, 0, ""}, - {"IPPROTO_BRSATMON", Const, 0, ""}, - {"IPPROTO_CARP", Const, 0, ""}, - {"IPPROTO_CFTP", Const, 0, ""}, - {"IPPROTO_CHAOS", Const, 0, ""}, - {"IPPROTO_CMTP", Const, 0, ""}, - {"IPPROTO_COMP", Const, 0, ""}, - {"IPPROTO_CPHB", Const, 0, ""}, - {"IPPROTO_CPNX", Const, 0, ""}, - {"IPPROTO_DCCP", Const, 0, ""}, - {"IPPROTO_DDP", Const, 0, ""}, - {"IPPROTO_DGP", Const, 0, ""}, - {"IPPROTO_DIVERT", Const, 0, ""}, - {"IPPROTO_DIVERT_INIT", Const, 3, ""}, - {"IPPROTO_DIVERT_RESP", Const, 3, ""}, - {"IPPROTO_DONE", Const, 0, ""}, - {"IPPROTO_DSTOPTS", Const, 0, ""}, - {"IPPROTO_EGP", Const, 0, ""}, - {"IPPROTO_EMCON", Const, 0, ""}, - {"IPPROTO_ENCAP", Const, 0, ""}, - {"IPPROTO_EON", Const, 0, ""}, - {"IPPROTO_ESP", Const, 0, ""}, - {"IPPROTO_ETHERIP", Const, 0, ""}, - {"IPPROTO_FRAGMENT", Const, 0, ""}, - {"IPPROTO_GGP", Const, 0, ""}, - {"IPPROTO_GMTP", Const, 0, ""}, - {"IPPROTO_GRE", Const, 0, ""}, - {"IPPROTO_HELLO", Const, 0, ""}, - {"IPPROTO_HMP", Const, 0, ""}, - {"IPPROTO_HOPOPTS", Const, 0, ""}, - {"IPPROTO_ICMP", Const, 0, ""}, - {"IPPROTO_ICMPV6", Const, 0, ""}, - {"IPPROTO_IDP", Const, 0, ""}, - {"IPPROTO_IDPR", Const, 0, ""}, - {"IPPROTO_IDRP", Const, 0, ""}, - {"IPPROTO_IGMP", Const, 0, ""}, - {"IPPROTO_IGP", Const, 0, ""}, - {"IPPROTO_IGRP", Const, 0, ""}, - {"IPPROTO_IL", Const, 0, ""}, - {"IPPROTO_INLSP", Const, 0, ""}, - {"IPPROTO_INP", Const, 0, ""}, - {"IPPROTO_IP", Const, 0, ""}, - {"IPPROTO_IPCOMP", Const, 0, ""}, - {"IPPROTO_IPCV", Const, 0, ""}, - {"IPPROTO_IPEIP", Const, 0, ""}, - {"IPPROTO_IPIP", Const, 0, ""}, - {"IPPROTO_IPPC", Const, 0, ""}, - {"IPPROTO_IPV4", Const, 0, ""}, - {"IPPROTO_IPV6", Const, 0, ""}, - {"IPPROTO_IPV6_ICMP", Const, 1, ""}, - {"IPPROTO_IRTP", Const, 0, ""}, - {"IPPROTO_KRYPTOLAN", Const, 0, ""}, - {"IPPROTO_LARP", Const, 0, ""}, - {"IPPROTO_LEAF1", Const, 0, ""}, - {"IPPROTO_LEAF2", Const, 0, ""}, - {"IPPROTO_MAX", Const, 0, ""}, - {"IPPROTO_MAXID", Const, 0, ""}, - {"IPPROTO_MEAS", Const, 0, ""}, - {"IPPROTO_MH", Const, 1, ""}, - {"IPPROTO_MHRP", Const, 0, ""}, - {"IPPROTO_MICP", Const, 0, ""}, - {"IPPROTO_MOBILE", Const, 0, ""}, - {"IPPROTO_MPLS", Const, 1, ""}, - {"IPPROTO_MTP", Const, 0, ""}, - {"IPPROTO_MUX", Const, 0, ""}, - {"IPPROTO_ND", Const, 0, ""}, - {"IPPROTO_NHRP", Const, 0, ""}, - {"IPPROTO_NONE", Const, 0, ""}, - {"IPPROTO_NSP", Const, 0, ""}, - {"IPPROTO_NVPII", Const, 0, ""}, - {"IPPROTO_OLD_DIVERT", Const, 0, ""}, - {"IPPROTO_OSPFIGP", Const, 0, ""}, - {"IPPROTO_PFSYNC", Const, 0, ""}, - {"IPPROTO_PGM", Const, 0, ""}, - {"IPPROTO_PIGP", Const, 0, ""}, - {"IPPROTO_PIM", Const, 0, ""}, - {"IPPROTO_PRM", Const, 0, ""}, - {"IPPROTO_PUP", Const, 0, ""}, - {"IPPROTO_PVP", Const, 0, ""}, - {"IPPROTO_RAW", Const, 0, ""}, - {"IPPROTO_RCCMON", Const, 0, ""}, - {"IPPROTO_RDP", Const, 0, ""}, - {"IPPROTO_ROUTING", Const, 0, ""}, - {"IPPROTO_RSVP", Const, 0, ""}, - {"IPPROTO_RVD", Const, 0, ""}, - {"IPPROTO_SATEXPAK", Const, 0, ""}, - {"IPPROTO_SATMON", Const, 0, ""}, - {"IPPROTO_SCCSP", Const, 0, ""}, - {"IPPROTO_SCTP", Const, 0, ""}, - {"IPPROTO_SDRP", Const, 0, ""}, - {"IPPROTO_SEND", Const, 1, ""}, - {"IPPROTO_SEP", Const, 0, ""}, - {"IPPROTO_SKIP", Const, 0, ""}, - {"IPPROTO_SPACER", Const, 0, ""}, - {"IPPROTO_SRPC", Const, 0, ""}, - {"IPPROTO_ST", Const, 0, ""}, - {"IPPROTO_SVMTP", Const, 0, ""}, - {"IPPROTO_SWIPE", Const, 0, ""}, - {"IPPROTO_TCF", Const, 0, ""}, - {"IPPROTO_TCP", Const, 0, ""}, - {"IPPROTO_TLSP", Const, 0, ""}, - {"IPPROTO_TP", Const, 0, ""}, - {"IPPROTO_TPXX", Const, 0, ""}, - {"IPPROTO_TRUNK1", Const, 0, ""}, - {"IPPROTO_TRUNK2", Const, 0, ""}, - {"IPPROTO_TTP", Const, 0, ""}, - {"IPPROTO_UDP", Const, 0, ""}, - {"IPPROTO_UDPLITE", Const, 0, ""}, - {"IPPROTO_VINES", Const, 0, ""}, - {"IPPROTO_VISA", Const, 0, ""}, - {"IPPROTO_VMTP", Const, 0, ""}, - {"IPPROTO_VRRP", Const, 1, ""}, - {"IPPROTO_WBEXPAK", Const, 0, ""}, - {"IPPROTO_WBMON", Const, 0, ""}, - {"IPPROTO_WSN", Const, 0, ""}, - {"IPPROTO_XNET", Const, 0, ""}, - {"IPPROTO_XTP", Const, 0, ""}, - {"IPV6_2292DSTOPTS", Const, 0, ""}, - {"IPV6_2292HOPLIMIT", Const, 0, ""}, - {"IPV6_2292HOPOPTS", Const, 0, ""}, - {"IPV6_2292NEXTHOP", Const, 0, ""}, - {"IPV6_2292PKTINFO", Const, 0, ""}, - {"IPV6_2292PKTOPTIONS", Const, 0, ""}, - {"IPV6_2292RTHDR", Const, 0, ""}, - {"IPV6_ADDRFORM", Const, 0, ""}, - {"IPV6_ADD_MEMBERSHIP", Const, 0, ""}, - {"IPV6_AUTHHDR", Const, 0, ""}, - {"IPV6_AUTH_LEVEL", Const, 1, ""}, - {"IPV6_AUTOFLOWLABEL", Const, 0, ""}, - {"IPV6_BINDANY", Const, 0, ""}, - {"IPV6_BINDV6ONLY", Const, 0, ""}, - {"IPV6_BOUND_IF", Const, 0, ""}, - {"IPV6_CHECKSUM", Const, 0, ""}, - {"IPV6_DEFAULT_MULTICAST_HOPS", Const, 0, ""}, - {"IPV6_DEFAULT_MULTICAST_LOOP", Const, 0, ""}, - {"IPV6_DEFHLIM", Const, 0, ""}, - {"IPV6_DONTFRAG", Const, 0, ""}, - {"IPV6_DROP_MEMBERSHIP", Const, 0, ""}, - {"IPV6_DSTOPTS", Const, 0, ""}, - {"IPV6_ESP_NETWORK_LEVEL", Const, 1, ""}, - {"IPV6_ESP_TRANS_LEVEL", Const, 1, ""}, - {"IPV6_FAITH", Const, 0, ""}, - {"IPV6_FLOWINFO_MASK", Const, 0, ""}, - {"IPV6_FLOWLABEL_MASK", Const, 0, ""}, - {"IPV6_FRAGTTL", Const, 0, ""}, - {"IPV6_FW_ADD", Const, 0, ""}, - {"IPV6_FW_DEL", Const, 0, ""}, - {"IPV6_FW_FLUSH", Const, 0, ""}, - {"IPV6_FW_GET", Const, 0, ""}, - {"IPV6_FW_ZERO", Const, 0, ""}, - {"IPV6_HLIMDEC", Const, 0, ""}, - {"IPV6_HOPLIMIT", Const, 0, ""}, - {"IPV6_HOPOPTS", Const, 0, ""}, - {"IPV6_IPCOMP_LEVEL", Const, 1, ""}, - {"IPV6_IPSEC_POLICY", Const, 0, ""}, - {"IPV6_JOIN_ANYCAST", Const, 0, ""}, - {"IPV6_JOIN_GROUP", Const, 0, ""}, - {"IPV6_LEAVE_ANYCAST", Const, 0, ""}, - {"IPV6_LEAVE_GROUP", Const, 0, ""}, - {"IPV6_MAXHLIM", Const, 0, ""}, - {"IPV6_MAXOPTHDR", Const, 0, ""}, - {"IPV6_MAXPACKET", Const, 0, ""}, - {"IPV6_MAX_GROUP_SRC_FILTER", Const, 0, ""}, - {"IPV6_MAX_MEMBERSHIPS", Const, 0, ""}, - {"IPV6_MAX_SOCK_SRC_FILTER", Const, 0, ""}, - {"IPV6_MIN_MEMBERSHIPS", Const, 0, ""}, - {"IPV6_MMTU", Const, 0, ""}, - {"IPV6_MSFILTER", Const, 0, ""}, - {"IPV6_MTU", Const, 0, ""}, - {"IPV6_MTU_DISCOVER", Const, 0, ""}, - {"IPV6_MULTICAST_HOPS", Const, 0, ""}, - {"IPV6_MULTICAST_IF", Const, 0, ""}, - {"IPV6_MULTICAST_LOOP", Const, 0, ""}, - {"IPV6_NEXTHOP", Const, 0, ""}, - {"IPV6_OPTIONS", Const, 1, ""}, - {"IPV6_PATHMTU", Const, 0, ""}, - {"IPV6_PIPEX", Const, 1, ""}, - {"IPV6_PKTINFO", Const, 0, ""}, - {"IPV6_PMTUDISC_DO", Const, 0, ""}, - {"IPV6_PMTUDISC_DONT", Const, 0, ""}, - {"IPV6_PMTUDISC_PROBE", Const, 0, ""}, - {"IPV6_PMTUDISC_WANT", Const, 0, ""}, - {"IPV6_PORTRANGE", Const, 0, ""}, - {"IPV6_PORTRANGE_DEFAULT", Const, 0, ""}, - {"IPV6_PORTRANGE_HIGH", Const, 0, ""}, - {"IPV6_PORTRANGE_LOW", Const, 0, ""}, - {"IPV6_PREFER_TEMPADDR", Const, 0, ""}, - {"IPV6_RECVDSTOPTS", Const, 0, ""}, - {"IPV6_RECVDSTPORT", Const, 3, ""}, - {"IPV6_RECVERR", Const, 0, ""}, - {"IPV6_RECVHOPLIMIT", Const, 0, ""}, - {"IPV6_RECVHOPOPTS", Const, 0, ""}, - {"IPV6_RECVPATHMTU", Const, 0, ""}, - {"IPV6_RECVPKTINFO", Const, 0, ""}, - {"IPV6_RECVRTHDR", Const, 0, ""}, - {"IPV6_RECVTCLASS", Const, 0, ""}, - {"IPV6_ROUTER_ALERT", Const, 0, ""}, - {"IPV6_RTABLE", Const, 1, ""}, - {"IPV6_RTHDR", Const, 0, ""}, - {"IPV6_RTHDRDSTOPTS", Const, 0, ""}, - {"IPV6_RTHDR_LOOSE", Const, 0, ""}, - {"IPV6_RTHDR_STRICT", Const, 0, ""}, - {"IPV6_RTHDR_TYPE_0", Const, 0, ""}, - {"IPV6_RXDSTOPTS", Const, 0, ""}, - {"IPV6_RXHOPOPTS", Const, 0, ""}, - {"IPV6_SOCKOPT_RESERVED1", Const, 0, ""}, - {"IPV6_TCLASS", Const, 0, ""}, - {"IPV6_UNICAST_HOPS", Const, 0, ""}, - {"IPV6_USE_MIN_MTU", Const, 0, ""}, - {"IPV6_V6ONLY", Const, 0, ""}, - {"IPV6_VERSION", Const, 0, ""}, - {"IPV6_VERSION_MASK", Const, 0, ""}, - {"IPV6_XFRM_POLICY", Const, 0, ""}, - {"IP_ADD_MEMBERSHIP", Const, 0, ""}, - {"IP_ADD_SOURCE_MEMBERSHIP", Const, 0, ""}, - {"IP_AUTH_LEVEL", Const, 1, ""}, - {"IP_BINDANY", Const, 0, ""}, - {"IP_BLOCK_SOURCE", Const, 0, ""}, - {"IP_BOUND_IF", Const, 0, ""}, - {"IP_DEFAULT_MULTICAST_LOOP", Const, 0, ""}, - {"IP_DEFAULT_MULTICAST_TTL", Const, 0, ""}, - {"IP_DF", Const, 0, ""}, - {"IP_DIVERTFL", Const, 3, ""}, - {"IP_DONTFRAG", Const, 0, ""}, - {"IP_DROP_MEMBERSHIP", Const, 0, ""}, - {"IP_DROP_SOURCE_MEMBERSHIP", Const, 0, ""}, - {"IP_DUMMYNET3", Const, 0, ""}, - {"IP_DUMMYNET_CONFIGURE", Const, 0, ""}, - {"IP_DUMMYNET_DEL", Const, 0, ""}, - {"IP_DUMMYNET_FLUSH", Const, 0, ""}, - {"IP_DUMMYNET_GET", Const, 0, ""}, - {"IP_EF", Const, 1, ""}, - {"IP_ERRORMTU", Const, 1, ""}, - {"IP_ESP_NETWORK_LEVEL", Const, 1, ""}, - {"IP_ESP_TRANS_LEVEL", Const, 1, ""}, - {"IP_FAITH", Const, 0, ""}, - {"IP_FREEBIND", Const, 0, ""}, - {"IP_FW3", Const, 0, ""}, - {"IP_FW_ADD", Const, 0, ""}, - {"IP_FW_DEL", Const, 0, ""}, - {"IP_FW_FLUSH", Const, 0, ""}, - {"IP_FW_GET", Const, 0, ""}, - {"IP_FW_NAT_CFG", Const, 0, ""}, - {"IP_FW_NAT_DEL", Const, 0, ""}, - {"IP_FW_NAT_GET_CONFIG", Const, 0, ""}, - {"IP_FW_NAT_GET_LOG", Const, 0, ""}, - {"IP_FW_RESETLOG", Const, 0, ""}, - {"IP_FW_TABLE_ADD", Const, 0, ""}, - {"IP_FW_TABLE_DEL", Const, 0, ""}, - {"IP_FW_TABLE_FLUSH", Const, 0, ""}, - {"IP_FW_TABLE_GETSIZE", Const, 0, ""}, - {"IP_FW_TABLE_LIST", Const, 0, ""}, - {"IP_FW_ZERO", Const, 0, ""}, - {"IP_HDRINCL", Const, 0, ""}, - {"IP_IPCOMP_LEVEL", Const, 1, ""}, - {"IP_IPSECFLOWINFO", Const, 1, ""}, - {"IP_IPSEC_LOCAL_AUTH", Const, 1, ""}, - {"IP_IPSEC_LOCAL_CRED", Const, 1, ""}, - {"IP_IPSEC_LOCAL_ID", Const, 1, ""}, - {"IP_IPSEC_POLICY", Const, 0, ""}, - {"IP_IPSEC_REMOTE_AUTH", Const, 1, ""}, - {"IP_IPSEC_REMOTE_CRED", Const, 1, ""}, - {"IP_IPSEC_REMOTE_ID", Const, 1, ""}, - {"IP_MAXPACKET", Const, 0, ""}, - {"IP_MAX_GROUP_SRC_FILTER", Const, 0, ""}, - {"IP_MAX_MEMBERSHIPS", Const, 0, ""}, - {"IP_MAX_SOCK_MUTE_FILTER", Const, 0, ""}, - {"IP_MAX_SOCK_SRC_FILTER", Const, 0, ""}, - {"IP_MAX_SOURCE_FILTER", Const, 0, ""}, - {"IP_MF", Const, 0, ""}, - {"IP_MINFRAGSIZE", Const, 1, ""}, - {"IP_MINTTL", Const, 0, ""}, - {"IP_MIN_MEMBERSHIPS", Const, 0, ""}, - {"IP_MSFILTER", Const, 0, ""}, - {"IP_MSS", Const, 0, ""}, - {"IP_MTU", Const, 0, ""}, - {"IP_MTU_DISCOVER", Const, 0, ""}, - {"IP_MULTICAST_IF", Const, 0, ""}, - {"IP_MULTICAST_IFINDEX", Const, 0, ""}, - {"IP_MULTICAST_LOOP", Const, 0, ""}, - {"IP_MULTICAST_TTL", Const, 0, ""}, - {"IP_MULTICAST_VIF", Const, 0, ""}, - {"IP_NAT__XXX", Const, 0, ""}, - {"IP_OFFMASK", Const, 0, ""}, - {"IP_OLD_FW_ADD", Const, 0, ""}, - {"IP_OLD_FW_DEL", Const, 0, ""}, - {"IP_OLD_FW_FLUSH", Const, 0, ""}, - {"IP_OLD_FW_GET", Const, 0, ""}, - {"IP_OLD_FW_RESETLOG", Const, 0, ""}, - {"IP_OLD_FW_ZERO", Const, 0, ""}, - {"IP_ONESBCAST", Const, 0, ""}, - {"IP_OPTIONS", Const, 0, ""}, - {"IP_ORIGDSTADDR", Const, 0, ""}, - {"IP_PASSSEC", Const, 0, ""}, - {"IP_PIPEX", Const, 1, ""}, - {"IP_PKTINFO", Const, 0, ""}, - {"IP_PKTOPTIONS", Const, 0, ""}, - {"IP_PMTUDISC", Const, 0, ""}, - {"IP_PMTUDISC_DO", Const, 0, ""}, - {"IP_PMTUDISC_DONT", Const, 0, ""}, - {"IP_PMTUDISC_PROBE", Const, 0, ""}, - {"IP_PMTUDISC_WANT", Const, 0, ""}, - {"IP_PORTRANGE", Const, 0, ""}, - {"IP_PORTRANGE_DEFAULT", Const, 0, ""}, - {"IP_PORTRANGE_HIGH", Const, 0, ""}, - {"IP_PORTRANGE_LOW", Const, 0, ""}, - {"IP_RECVDSTADDR", Const, 0, ""}, - {"IP_RECVDSTPORT", Const, 1, ""}, - {"IP_RECVERR", Const, 0, ""}, - {"IP_RECVIF", Const, 0, ""}, - {"IP_RECVOPTS", Const, 0, ""}, - {"IP_RECVORIGDSTADDR", Const, 0, ""}, - {"IP_RECVPKTINFO", Const, 0, ""}, - {"IP_RECVRETOPTS", Const, 0, ""}, - {"IP_RECVRTABLE", Const, 1, ""}, - {"IP_RECVTOS", Const, 0, ""}, - {"IP_RECVTTL", Const, 0, ""}, - {"IP_RETOPTS", Const, 0, ""}, - {"IP_RF", Const, 0, ""}, - {"IP_ROUTER_ALERT", Const, 0, ""}, - {"IP_RSVP_OFF", Const, 0, ""}, - {"IP_RSVP_ON", Const, 0, ""}, - {"IP_RSVP_VIF_OFF", Const, 0, ""}, - {"IP_RSVP_VIF_ON", Const, 0, ""}, - {"IP_RTABLE", Const, 1, ""}, - {"IP_SENDSRCADDR", Const, 0, ""}, - {"IP_STRIPHDR", Const, 0, ""}, - {"IP_TOS", Const, 0, ""}, - {"IP_TRAFFIC_MGT_BACKGROUND", Const, 0, ""}, - {"IP_TRANSPARENT", Const, 0, ""}, - {"IP_TTL", Const, 0, ""}, - {"IP_UNBLOCK_SOURCE", Const, 0, ""}, - {"IP_XFRM_POLICY", Const, 0, ""}, - {"IPv6MTUInfo", Type, 2, ""}, - {"IPv6MTUInfo.Addr", Field, 2, ""}, - {"IPv6MTUInfo.Mtu", Field, 2, ""}, - {"IPv6Mreq", Type, 0, ""}, - {"IPv6Mreq.Interface", Field, 0, ""}, - {"IPv6Mreq.Multiaddr", Field, 0, ""}, - {"ISIG", Const, 0, ""}, - {"ISTRIP", Const, 0, ""}, - {"IUCLC", Const, 0, ""}, - {"IUTF8", Const, 0, ""}, - {"IXANY", Const, 0, ""}, - {"IXOFF", Const, 0, ""}, - {"IXON", Const, 0, ""}, - {"IfAddrmsg", Type, 0, ""}, - {"IfAddrmsg.Family", Field, 0, ""}, - {"IfAddrmsg.Flags", Field, 0, ""}, - {"IfAddrmsg.Index", Field, 0, ""}, - {"IfAddrmsg.Prefixlen", Field, 0, ""}, - {"IfAddrmsg.Scope", Field, 0, ""}, - {"IfAnnounceMsghdr", Type, 1, ""}, - {"IfAnnounceMsghdr.Hdrlen", Field, 2, ""}, - {"IfAnnounceMsghdr.Index", Field, 1, ""}, - {"IfAnnounceMsghdr.Msglen", Field, 1, ""}, - {"IfAnnounceMsghdr.Name", Field, 1, ""}, - {"IfAnnounceMsghdr.Type", Field, 1, ""}, - {"IfAnnounceMsghdr.Version", Field, 1, ""}, - {"IfAnnounceMsghdr.What", Field, 1, ""}, - {"IfData", Type, 0, ""}, - {"IfData.Addrlen", Field, 0, ""}, - {"IfData.Baudrate", Field, 0, ""}, - {"IfData.Capabilities", Field, 2, ""}, - {"IfData.Collisions", Field, 0, ""}, - {"IfData.Datalen", Field, 0, ""}, - {"IfData.Epoch", Field, 0, ""}, - {"IfData.Hdrlen", Field, 0, ""}, - {"IfData.Hwassist", Field, 0, ""}, - {"IfData.Ibytes", Field, 0, ""}, - {"IfData.Ierrors", Field, 0, ""}, - {"IfData.Imcasts", Field, 0, ""}, - {"IfData.Ipackets", Field, 0, ""}, - {"IfData.Iqdrops", Field, 0, ""}, - {"IfData.Lastchange", Field, 0, ""}, - {"IfData.Link_state", Field, 0, ""}, - {"IfData.Mclpool", Field, 2, ""}, - {"IfData.Metric", Field, 0, ""}, - {"IfData.Mtu", Field, 0, ""}, - {"IfData.Noproto", Field, 0, ""}, - {"IfData.Obytes", Field, 0, ""}, - {"IfData.Oerrors", Field, 0, ""}, - {"IfData.Omcasts", Field, 0, ""}, - {"IfData.Opackets", Field, 0, ""}, - {"IfData.Pad", Field, 2, ""}, - {"IfData.Pad_cgo_0", Field, 2, ""}, - {"IfData.Pad_cgo_1", Field, 2, ""}, - {"IfData.Physical", Field, 0, ""}, - {"IfData.Recvquota", Field, 0, ""}, - {"IfData.Recvtiming", Field, 0, ""}, - {"IfData.Reserved1", Field, 0, ""}, - {"IfData.Reserved2", Field, 0, ""}, - {"IfData.Spare_char1", Field, 0, ""}, - {"IfData.Spare_char2", Field, 0, ""}, - {"IfData.Type", Field, 0, ""}, - {"IfData.Typelen", Field, 0, ""}, - {"IfData.Unused1", Field, 0, ""}, - {"IfData.Unused2", Field, 0, ""}, - {"IfData.Xmitquota", Field, 0, ""}, - {"IfData.Xmittiming", Field, 0, ""}, - {"IfInfomsg", Type, 0, ""}, - {"IfInfomsg.Change", Field, 0, ""}, - {"IfInfomsg.Family", Field, 0, ""}, - {"IfInfomsg.Flags", Field, 0, ""}, - {"IfInfomsg.Index", Field, 0, ""}, - {"IfInfomsg.Type", Field, 0, ""}, - {"IfInfomsg.X__ifi_pad", Field, 0, ""}, - {"IfMsghdr", Type, 0, ""}, - {"IfMsghdr.Addrs", Field, 0, ""}, - {"IfMsghdr.Data", Field, 0, ""}, - {"IfMsghdr.Flags", Field, 0, ""}, - {"IfMsghdr.Hdrlen", Field, 2, ""}, - {"IfMsghdr.Index", Field, 0, ""}, - {"IfMsghdr.Msglen", Field, 0, ""}, - {"IfMsghdr.Pad1", Field, 2, ""}, - {"IfMsghdr.Pad2", Field, 2, ""}, - {"IfMsghdr.Pad_cgo_0", Field, 0, ""}, - {"IfMsghdr.Pad_cgo_1", Field, 2, ""}, - {"IfMsghdr.Tableid", Field, 2, ""}, - {"IfMsghdr.Type", Field, 0, ""}, - {"IfMsghdr.Version", Field, 0, ""}, - {"IfMsghdr.Xflags", Field, 2, ""}, - {"IfaMsghdr", Type, 0, ""}, - {"IfaMsghdr.Addrs", Field, 0, ""}, - {"IfaMsghdr.Flags", Field, 0, ""}, - {"IfaMsghdr.Hdrlen", Field, 2, ""}, - {"IfaMsghdr.Index", Field, 0, ""}, - {"IfaMsghdr.Metric", Field, 0, ""}, - {"IfaMsghdr.Msglen", Field, 0, ""}, - {"IfaMsghdr.Pad1", Field, 2, ""}, - {"IfaMsghdr.Pad2", Field, 2, ""}, - {"IfaMsghdr.Pad_cgo_0", Field, 0, ""}, - {"IfaMsghdr.Tableid", Field, 2, ""}, - {"IfaMsghdr.Type", Field, 0, ""}, - {"IfaMsghdr.Version", Field, 0, ""}, - {"IfmaMsghdr", Type, 0, ""}, - {"IfmaMsghdr.Addrs", Field, 0, ""}, - {"IfmaMsghdr.Flags", Field, 0, ""}, - {"IfmaMsghdr.Index", Field, 0, ""}, - {"IfmaMsghdr.Msglen", Field, 0, ""}, - {"IfmaMsghdr.Pad_cgo_0", Field, 0, ""}, - {"IfmaMsghdr.Type", Field, 0, ""}, - {"IfmaMsghdr.Version", Field, 0, ""}, - {"IfmaMsghdr2", Type, 0, ""}, - {"IfmaMsghdr2.Addrs", Field, 0, ""}, - {"IfmaMsghdr2.Flags", Field, 0, ""}, - {"IfmaMsghdr2.Index", Field, 0, ""}, - {"IfmaMsghdr2.Msglen", Field, 0, ""}, - {"IfmaMsghdr2.Pad_cgo_0", Field, 0, ""}, - {"IfmaMsghdr2.Refcount", Field, 0, ""}, - {"IfmaMsghdr2.Type", Field, 0, ""}, - {"IfmaMsghdr2.Version", Field, 0, ""}, - {"ImplementsGetwd", Const, 0, ""}, - {"Inet4Pktinfo", Type, 0, ""}, - {"Inet4Pktinfo.Addr", Field, 0, ""}, - {"Inet4Pktinfo.Ifindex", Field, 0, ""}, - {"Inet4Pktinfo.Spec_dst", Field, 0, ""}, - {"Inet6Pktinfo", Type, 0, ""}, - {"Inet6Pktinfo.Addr", Field, 0, ""}, - {"Inet6Pktinfo.Ifindex", Field, 0, ""}, - {"InotifyAddWatch", Func, 0, "func(fd int, pathname string, mask uint32) (watchdesc int, err error)"}, - {"InotifyEvent", Type, 0, ""}, - {"InotifyEvent.Cookie", Field, 0, ""}, - {"InotifyEvent.Len", Field, 0, ""}, - {"InotifyEvent.Mask", Field, 0, ""}, - {"InotifyEvent.Name", Field, 0, ""}, - {"InotifyEvent.Wd", Field, 0, ""}, - {"InotifyInit", Func, 0, "func() (fd int, err error)"}, - {"InotifyInit1", Func, 0, "func(flags int) (fd int, err error)"}, - {"InotifyRmWatch", Func, 0, "func(fd int, watchdesc uint32) (success int, err error)"}, - {"InterfaceAddrMessage", Type, 0, ""}, - {"InterfaceAddrMessage.Data", Field, 0, ""}, - {"InterfaceAddrMessage.Header", Field, 0, ""}, - {"InterfaceAnnounceMessage", Type, 1, ""}, - {"InterfaceAnnounceMessage.Header", Field, 1, ""}, - {"InterfaceInfo", Type, 0, ""}, - {"InterfaceInfo.Address", Field, 0, ""}, - {"InterfaceInfo.BroadcastAddress", Field, 0, ""}, - {"InterfaceInfo.Flags", Field, 0, ""}, - {"InterfaceInfo.Netmask", Field, 0, ""}, - {"InterfaceMessage", Type, 0, ""}, - {"InterfaceMessage.Data", Field, 0, ""}, - {"InterfaceMessage.Header", Field, 0, ""}, - {"InterfaceMulticastAddrMessage", Type, 0, ""}, - {"InterfaceMulticastAddrMessage.Data", Field, 0, ""}, - {"InterfaceMulticastAddrMessage.Header", Field, 0, ""}, - {"InvalidHandle", Const, 0, ""}, - {"Ioperm", Func, 0, "func(from int, num int, on int) (err error)"}, - {"Iopl", Func, 0, "func(level int) (err error)"}, - {"Iovec", Type, 0, ""}, - {"Iovec.Base", Field, 0, ""}, - {"Iovec.Len", Field, 0, ""}, - {"IpAdapterInfo", Type, 0, ""}, - {"IpAdapterInfo.AdapterName", Field, 0, ""}, - {"IpAdapterInfo.Address", Field, 0, ""}, - {"IpAdapterInfo.AddressLength", Field, 0, ""}, - {"IpAdapterInfo.ComboIndex", Field, 0, ""}, - {"IpAdapterInfo.CurrentIpAddress", Field, 0, ""}, - {"IpAdapterInfo.Description", Field, 0, ""}, - {"IpAdapterInfo.DhcpEnabled", Field, 0, ""}, - {"IpAdapterInfo.DhcpServer", Field, 0, ""}, - {"IpAdapterInfo.GatewayList", Field, 0, ""}, - {"IpAdapterInfo.HaveWins", Field, 0, ""}, - {"IpAdapterInfo.Index", Field, 0, ""}, - {"IpAdapterInfo.IpAddressList", Field, 0, ""}, - {"IpAdapterInfo.LeaseExpires", Field, 0, ""}, - {"IpAdapterInfo.LeaseObtained", Field, 0, ""}, - {"IpAdapterInfo.Next", Field, 0, ""}, - {"IpAdapterInfo.PrimaryWinsServer", Field, 0, ""}, - {"IpAdapterInfo.SecondaryWinsServer", Field, 0, ""}, - {"IpAdapterInfo.Type", Field, 0, ""}, - {"IpAddrString", Type, 0, ""}, - {"IpAddrString.Context", Field, 0, ""}, - {"IpAddrString.IpAddress", Field, 0, ""}, - {"IpAddrString.IpMask", Field, 0, ""}, - {"IpAddrString.Next", Field, 0, ""}, - {"IpAddressString", Type, 0, ""}, - {"IpAddressString.String", Field, 0, ""}, - {"IpMaskString", Type, 0, ""}, - {"IpMaskString.String", Field, 2, ""}, - {"Issetugid", Func, 0, ""}, - {"KEY_ALL_ACCESS", Const, 0, ""}, - {"KEY_CREATE_LINK", Const, 0, ""}, - {"KEY_CREATE_SUB_KEY", Const, 0, ""}, - {"KEY_ENUMERATE_SUB_KEYS", Const, 0, ""}, - {"KEY_EXECUTE", Const, 0, ""}, - {"KEY_NOTIFY", Const, 0, ""}, - {"KEY_QUERY_VALUE", Const, 0, ""}, - {"KEY_READ", Const, 0, ""}, - {"KEY_SET_VALUE", Const, 0, ""}, - {"KEY_WOW64_32KEY", Const, 0, ""}, - {"KEY_WOW64_64KEY", Const, 0, ""}, - {"KEY_WRITE", Const, 0, ""}, - {"Kevent", Func, 0, ""}, - {"Kevent_t", Type, 0, ""}, - {"Kevent_t.Data", Field, 0, ""}, - {"Kevent_t.Fflags", Field, 0, ""}, - {"Kevent_t.Filter", Field, 0, ""}, - {"Kevent_t.Flags", Field, 0, ""}, - {"Kevent_t.Ident", Field, 0, ""}, - {"Kevent_t.Pad_cgo_0", Field, 2, ""}, - {"Kevent_t.Udata", Field, 0, ""}, - {"Kill", Func, 0, "func(pid int, sig Signal) (err error)"}, - {"Klogctl", Func, 0, "func(typ int, buf []byte) (n int, err error)"}, - {"Kqueue", Func, 0, ""}, - {"LANG_ENGLISH", Const, 0, ""}, - {"LAYERED_PROTOCOL", Const, 2, ""}, - {"LCNT_OVERLOAD_FLUSH", Const, 1, ""}, - {"LINUX_REBOOT_CMD_CAD_OFF", Const, 0, ""}, - {"LINUX_REBOOT_CMD_CAD_ON", Const, 0, ""}, - {"LINUX_REBOOT_CMD_HALT", Const, 0, ""}, - {"LINUX_REBOOT_CMD_KEXEC", Const, 0, ""}, - {"LINUX_REBOOT_CMD_POWER_OFF", Const, 0, ""}, - {"LINUX_REBOOT_CMD_RESTART", Const, 0, ""}, - {"LINUX_REBOOT_CMD_RESTART2", Const, 0, ""}, - {"LINUX_REBOOT_CMD_SW_SUSPEND", Const, 0, ""}, - {"LINUX_REBOOT_MAGIC1", Const, 0, ""}, - {"LINUX_REBOOT_MAGIC2", Const, 0, ""}, - {"LOCK_EX", Const, 0, ""}, - {"LOCK_NB", Const, 0, ""}, - {"LOCK_SH", Const, 0, ""}, - {"LOCK_UN", Const, 0, ""}, - {"LazyDLL", Type, 0, ""}, - {"LazyDLL.Name", Field, 0, ""}, - {"LazyProc", Type, 0, ""}, - {"LazyProc.Name", Field, 0, ""}, - {"Lchown", Func, 0, "func(path string, uid int, gid int) (err error)"}, - {"Linger", Type, 0, ""}, - {"Linger.Linger", Field, 0, ""}, - {"Linger.Onoff", Field, 0, ""}, - {"Link", Func, 0, "func(oldpath string, newpath string) (err error)"}, - {"Listen", Func, 0, "func(s int, n int) (err error)"}, - {"Listxattr", Func, 1, "func(path string, dest []byte) (sz int, err error)"}, - {"LoadCancelIoEx", Func, 1, ""}, - {"LoadConnectEx", Func, 1, ""}, - {"LoadCreateSymbolicLink", Func, 4, ""}, - {"LoadDLL", Func, 0, ""}, - {"LoadGetAddrInfo", Func, 1, ""}, - {"LoadLibrary", Func, 0, ""}, - {"LoadSetFileCompletionNotificationModes", Func, 2, ""}, - {"LocalFree", Func, 0, ""}, - {"Log2phys_t", Type, 0, ""}, - {"Log2phys_t.Contigbytes", Field, 0, ""}, - {"Log2phys_t.Devoffset", Field, 0, ""}, - {"Log2phys_t.Flags", Field, 0, ""}, - {"LookupAccountName", Func, 0, ""}, - {"LookupAccountSid", Func, 0, ""}, - {"LookupSID", Func, 0, ""}, - {"LsfJump", Func, 0, "func(code int, k int, jt int, jf int) *SockFilter"}, - {"LsfSocket", Func, 0, "func(ifindex int, proto int) (int, error)"}, - {"LsfStmt", Func, 0, "func(code int, k int) *SockFilter"}, - {"Lstat", Func, 0, "func(path string, stat *Stat_t) (err error)"}, - {"MADV_AUTOSYNC", Const, 1, ""}, - {"MADV_CAN_REUSE", Const, 0, ""}, - {"MADV_CORE", Const, 1, ""}, - {"MADV_DOFORK", Const, 0, ""}, - {"MADV_DONTFORK", Const, 0, ""}, - {"MADV_DONTNEED", Const, 0, ""}, - {"MADV_FREE", Const, 0, ""}, - {"MADV_FREE_REUSABLE", Const, 0, ""}, - {"MADV_FREE_REUSE", Const, 0, ""}, - {"MADV_HUGEPAGE", Const, 0, ""}, - {"MADV_HWPOISON", Const, 0, ""}, - {"MADV_MERGEABLE", Const, 0, ""}, - {"MADV_NOCORE", Const, 1, ""}, - {"MADV_NOHUGEPAGE", Const, 0, ""}, - {"MADV_NORMAL", Const, 0, ""}, - {"MADV_NOSYNC", Const, 1, ""}, - {"MADV_PROTECT", Const, 1, ""}, - {"MADV_RANDOM", Const, 0, ""}, - {"MADV_REMOVE", Const, 0, ""}, - {"MADV_SEQUENTIAL", Const, 0, ""}, - {"MADV_SPACEAVAIL", Const, 3, ""}, - {"MADV_UNMERGEABLE", Const, 0, ""}, - {"MADV_WILLNEED", Const, 0, ""}, - {"MADV_ZERO_WIRED_PAGES", Const, 0, ""}, - {"MAP_32BIT", Const, 0, ""}, - {"MAP_ALIGNED_SUPER", Const, 3, ""}, - {"MAP_ALIGNMENT_16MB", Const, 3, ""}, - {"MAP_ALIGNMENT_1TB", Const, 3, ""}, - {"MAP_ALIGNMENT_256TB", Const, 3, ""}, - {"MAP_ALIGNMENT_4GB", Const, 3, ""}, - {"MAP_ALIGNMENT_64KB", Const, 3, ""}, - {"MAP_ALIGNMENT_64PB", Const, 3, ""}, - {"MAP_ALIGNMENT_MASK", Const, 3, ""}, - {"MAP_ALIGNMENT_SHIFT", Const, 3, ""}, - {"MAP_ANON", Const, 0, ""}, - {"MAP_ANONYMOUS", Const, 0, ""}, - {"MAP_COPY", Const, 0, ""}, - {"MAP_DENYWRITE", Const, 0, ""}, - {"MAP_EXECUTABLE", Const, 0, ""}, - {"MAP_FILE", Const, 0, ""}, - {"MAP_FIXED", Const, 0, ""}, - {"MAP_FLAGMASK", Const, 3, ""}, - {"MAP_GROWSDOWN", Const, 0, ""}, - {"MAP_HASSEMAPHORE", Const, 0, ""}, - {"MAP_HUGETLB", Const, 0, ""}, - {"MAP_INHERIT", Const, 3, ""}, - {"MAP_INHERIT_COPY", Const, 3, ""}, - {"MAP_INHERIT_DEFAULT", Const, 3, ""}, - {"MAP_INHERIT_DONATE_COPY", Const, 3, ""}, - {"MAP_INHERIT_NONE", Const, 3, ""}, - {"MAP_INHERIT_SHARE", Const, 3, ""}, - {"MAP_JIT", Const, 0, ""}, - {"MAP_LOCKED", Const, 0, ""}, - {"MAP_NOCACHE", Const, 0, ""}, - {"MAP_NOCORE", Const, 1, ""}, - {"MAP_NOEXTEND", Const, 0, ""}, - {"MAP_NONBLOCK", Const, 0, ""}, - {"MAP_NORESERVE", Const, 0, ""}, - {"MAP_NOSYNC", Const, 1, ""}, - {"MAP_POPULATE", Const, 0, ""}, - {"MAP_PREFAULT_READ", Const, 1, ""}, - {"MAP_PRIVATE", Const, 0, ""}, - {"MAP_RENAME", Const, 0, ""}, - {"MAP_RESERVED0080", Const, 0, ""}, - {"MAP_RESERVED0100", Const, 1, ""}, - {"MAP_SHARED", Const, 0, ""}, - {"MAP_STACK", Const, 0, ""}, - {"MAP_TRYFIXED", Const, 3, ""}, - {"MAP_TYPE", Const, 0, ""}, - {"MAP_WIRED", Const, 3, ""}, - {"MAXIMUM_REPARSE_DATA_BUFFER_SIZE", Const, 4, ""}, - {"MAXLEN_IFDESCR", Const, 0, ""}, - {"MAXLEN_PHYSADDR", Const, 0, ""}, - {"MAX_ADAPTER_ADDRESS_LENGTH", Const, 0, ""}, - {"MAX_ADAPTER_DESCRIPTION_LENGTH", Const, 0, ""}, - {"MAX_ADAPTER_NAME_LENGTH", Const, 0, ""}, - {"MAX_COMPUTERNAME_LENGTH", Const, 0, ""}, - {"MAX_INTERFACE_NAME_LEN", Const, 0, ""}, - {"MAX_LONG_PATH", Const, 0, ""}, - {"MAX_PATH", Const, 0, ""}, - {"MAX_PROTOCOL_CHAIN", Const, 2, ""}, - {"MCL_CURRENT", Const, 0, ""}, - {"MCL_FUTURE", Const, 0, ""}, - {"MNT_DETACH", Const, 0, ""}, - {"MNT_EXPIRE", Const, 0, ""}, - {"MNT_FORCE", Const, 0, ""}, - {"MSG_BCAST", Const, 1, ""}, - {"MSG_CMSG_CLOEXEC", Const, 0, ""}, - {"MSG_COMPAT", Const, 0, ""}, - {"MSG_CONFIRM", Const, 0, ""}, - {"MSG_CONTROLMBUF", Const, 1, ""}, - {"MSG_CTRUNC", Const, 0, ""}, - {"MSG_DONTROUTE", Const, 0, ""}, - {"MSG_DONTWAIT", Const, 0, ""}, - {"MSG_EOF", Const, 0, ""}, - {"MSG_EOR", Const, 0, ""}, - {"MSG_ERRQUEUE", Const, 0, ""}, - {"MSG_FASTOPEN", Const, 1, ""}, - {"MSG_FIN", Const, 0, ""}, - {"MSG_FLUSH", Const, 0, ""}, - {"MSG_HAVEMORE", Const, 0, ""}, - {"MSG_HOLD", Const, 0, ""}, - {"MSG_IOVUSRSPACE", Const, 1, ""}, - {"MSG_LENUSRSPACE", Const, 1, ""}, - {"MSG_MCAST", Const, 1, ""}, - {"MSG_MORE", Const, 0, ""}, - {"MSG_NAMEMBUF", Const, 1, ""}, - {"MSG_NBIO", Const, 0, ""}, - {"MSG_NEEDSA", Const, 0, ""}, - {"MSG_NOSIGNAL", Const, 0, ""}, - {"MSG_NOTIFICATION", Const, 0, ""}, - {"MSG_OOB", Const, 0, ""}, - {"MSG_PEEK", Const, 0, ""}, - {"MSG_PROXY", Const, 0, ""}, - {"MSG_RCVMORE", Const, 0, ""}, - {"MSG_RST", Const, 0, ""}, - {"MSG_SEND", Const, 0, ""}, - {"MSG_SYN", Const, 0, ""}, - {"MSG_TRUNC", Const, 0, ""}, - {"MSG_TRYHARD", Const, 0, ""}, - {"MSG_USERFLAGS", Const, 1, ""}, - {"MSG_WAITALL", Const, 0, ""}, - {"MSG_WAITFORONE", Const, 0, ""}, - {"MSG_WAITSTREAM", Const, 0, ""}, - {"MS_ACTIVE", Const, 0, ""}, - {"MS_ASYNC", Const, 0, ""}, - {"MS_BIND", Const, 0, ""}, - {"MS_DEACTIVATE", Const, 0, ""}, - {"MS_DIRSYNC", Const, 0, ""}, - {"MS_INVALIDATE", Const, 0, ""}, - {"MS_I_VERSION", Const, 0, ""}, - {"MS_KERNMOUNT", Const, 0, ""}, - {"MS_KILLPAGES", Const, 0, ""}, - {"MS_MANDLOCK", Const, 0, ""}, - {"MS_MGC_MSK", Const, 0, ""}, - {"MS_MGC_VAL", Const, 0, ""}, - {"MS_MOVE", Const, 0, ""}, - {"MS_NOATIME", Const, 0, ""}, - {"MS_NODEV", Const, 0, ""}, - {"MS_NODIRATIME", Const, 0, ""}, - {"MS_NOEXEC", Const, 0, ""}, - {"MS_NOSUID", Const, 0, ""}, - {"MS_NOUSER", Const, 0, ""}, - {"MS_POSIXACL", Const, 0, ""}, - {"MS_PRIVATE", Const, 0, ""}, - {"MS_RDONLY", Const, 0, ""}, - {"MS_REC", Const, 0, ""}, - {"MS_RELATIME", Const, 0, ""}, - {"MS_REMOUNT", Const, 0, ""}, - {"MS_RMT_MASK", Const, 0, ""}, - {"MS_SHARED", Const, 0, ""}, - {"MS_SILENT", Const, 0, ""}, - {"MS_SLAVE", Const, 0, ""}, - {"MS_STRICTATIME", Const, 0, ""}, - {"MS_SYNC", Const, 0, ""}, - {"MS_SYNCHRONOUS", Const, 0, ""}, - {"MS_UNBINDABLE", Const, 0, ""}, - {"Madvise", Func, 0, "func(b []byte, advice int) (err error)"}, - {"MapViewOfFile", Func, 0, ""}, - {"MaxTokenInfoClass", Const, 0, ""}, - {"Mclpool", Type, 2, ""}, - {"Mclpool.Alive", Field, 2, ""}, - {"Mclpool.Cwm", Field, 2, ""}, - {"Mclpool.Grown", Field, 2, ""}, - {"Mclpool.Hwm", Field, 2, ""}, - {"Mclpool.Lwm", Field, 2, ""}, - {"MibIfRow", Type, 0, ""}, - {"MibIfRow.AdminStatus", Field, 0, ""}, - {"MibIfRow.Descr", Field, 0, ""}, - {"MibIfRow.DescrLen", Field, 0, ""}, - {"MibIfRow.InDiscards", Field, 0, ""}, - {"MibIfRow.InErrors", Field, 0, ""}, - {"MibIfRow.InNUcastPkts", Field, 0, ""}, - {"MibIfRow.InOctets", Field, 0, ""}, - {"MibIfRow.InUcastPkts", Field, 0, ""}, - {"MibIfRow.InUnknownProtos", Field, 0, ""}, - {"MibIfRow.Index", Field, 0, ""}, - {"MibIfRow.LastChange", Field, 0, ""}, - {"MibIfRow.Mtu", Field, 0, ""}, - {"MibIfRow.Name", Field, 0, ""}, - {"MibIfRow.OperStatus", Field, 0, ""}, - {"MibIfRow.OutDiscards", Field, 0, ""}, - {"MibIfRow.OutErrors", Field, 0, ""}, - {"MibIfRow.OutNUcastPkts", Field, 0, ""}, - {"MibIfRow.OutOctets", Field, 0, ""}, - {"MibIfRow.OutQLen", Field, 0, ""}, - {"MibIfRow.OutUcastPkts", Field, 0, ""}, - {"MibIfRow.PhysAddr", Field, 0, ""}, - {"MibIfRow.PhysAddrLen", Field, 0, ""}, - {"MibIfRow.Speed", Field, 0, ""}, - {"MibIfRow.Type", Field, 0, ""}, - {"Mkdir", Func, 0, "func(path string, mode uint32) (err error)"}, - {"Mkdirat", Func, 0, "func(dirfd int, path string, mode uint32) (err error)"}, - {"Mkfifo", Func, 0, "func(path string, mode uint32) (err error)"}, - {"Mknod", Func, 0, "func(path string, mode uint32, dev int) (err error)"}, - {"Mknodat", Func, 0, "func(dirfd int, path string, mode uint32, dev int) (err error)"}, - {"Mlock", Func, 0, "func(b []byte) (err error)"}, - {"Mlockall", Func, 0, "func(flags int) (err error)"}, - {"Mmap", Func, 0, "func(fd int, offset int64, length int, prot int, flags int) (data []byte, err error)"}, - {"Mount", Func, 0, "func(source string, target string, fstype string, flags uintptr, data string) (err error)"}, - {"MoveFile", Func, 0, ""}, - {"Mprotect", Func, 0, "func(b []byte, prot int) (err error)"}, - {"Msghdr", Type, 0, ""}, - {"Msghdr.Control", Field, 0, ""}, - {"Msghdr.Controllen", Field, 0, ""}, - {"Msghdr.Flags", Field, 0, ""}, - {"Msghdr.Iov", Field, 0, ""}, - {"Msghdr.Iovlen", Field, 0, ""}, - {"Msghdr.Name", Field, 0, ""}, - {"Msghdr.Namelen", Field, 0, ""}, - {"Msghdr.Pad_cgo_0", Field, 0, ""}, - {"Msghdr.Pad_cgo_1", Field, 0, ""}, - {"Munlock", Func, 0, "func(b []byte) (err error)"}, - {"Munlockall", Func, 0, "func() (err error)"}, - {"Munmap", Func, 0, "func(b []byte) (err error)"}, - {"MustLoadDLL", Func, 0, ""}, - {"NAME_MAX", Const, 0, ""}, - {"NETLINK_ADD_MEMBERSHIP", Const, 0, ""}, - {"NETLINK_AUDIT", Const, 0, ""}, - {"NETLINK_BROADCAST_ERROR", Const, 0, ""}, - {"NETLINK_CONNECTOR", Const, 0, ""}, - {"NETLINK_DNRTMSG", Const, 0, ""}, - {"NETLINK_DROP_MEMBERSHIP", Const, 0, ""}, - {"NETLINK_ECRYPTFS", Const, 0, ""}, - {"NETLINK_FIB_LOOKUP", Const, 0, ""}, - {"NETLINK_FIREWALL", Const, 0, ""}, - {"NETLINK_GENERIC", Const, 0, ""}, - {"NETLINK_INET_DIAG", Const, 0, ""}, - {"NETLINK_IP6_FW", Const, 0, ""}, - {"NETLINK_ISCSI", Const, 0, ""}, - {"NETLINK_KOBJECT_UEVENT", Const, 0, ""}, - {"NETLINK_NETFILTER", Const, 0, ""}, - {"NETLINK_NFLOG", Const, 0, ""}, - {"NETLINK_NO_ENOBUFS", Const, 0, ""}, - {"NETLINK_PKTINFO", Const, 0, ""}, - {"NETLINK_RDMA", Const, 0, ""}, - {"NETLINK_ROUTE", Const, 0, ""}, - {"NETLINK_SCSITRANSPORT", Const, 0, ""}, - {"NETLINK_SELINUX", Const, 0, ""}, - {"NETLINK_UNUSED", Const, 0, ""}, - {"NETLINK_USERSOCK", Const, 0, ""}, - {"NETLINK_XFRM", Const, 0, ""}, - {"NET_RT_DUMP", Const, 0, ""}, - {"NET_RT_DUMP2", Const, 0, ""}, - {"NET_RT_FLAGS", Const, 0, ""}, - {"NET_RT_IFLIST", Const, 0, ""}, - {"NET_RT_IFLIST2", Const, 0, ""}, - {"NET_RT_IFLISTL", Const, 1, ""}, - {"NET_RT_IFMALIST", Const, 0, ""}, - {"NET_RT_MAXID", Const, 0, ""}, - {"NET_RT_OIFLIST", Const, 1, ""}, - {"NET_RT_OOIFLIST", Const, 1, ""}, - {"NET_RT_STAT", Const, 0, ""}, - {"NET_RT_STATS", Const, 1, ""}, - {"NET_RT_TABLE", Const, 1, ""}, - {"NET_RT_TRASH", Const, 0, ""}, - {"NLA_ALIGNTO", Const, 0, ""}, - {"NLA_F_NESTED", Const, 0, ""}, - {"NLA_F_NET_BYTEORDER", Const, 0, ""}, - {"NLA_HDRLEN", Const, 0, ""}, - {"NLMSG_ALIGNTO", Const, 0, ""}, - {"NLMSG_DONE", Const, 0, ""}, - {"NLMSG_ERROR", Const, 0, ""}, - {"NLMSG_HDRLEN", Const, 0, ""}, - {"NLMSG_MIN_TYPE", Const, 0, ""}, - {"NLMSG_NOOP", Const, 0, ""}, - {"NLMSG_OVERRUN", Const, 0, ""}, - {"NLM_F_ACK", Const, 0, ""}, - {"NLM_F_APPEND", Const, 0, ""}, - {"NLM_F_ATOMIC", Const, 0, ""}, - {"NLM_F_CREATE", Const, 0, ""}, - {"NLM_F_DUMP", Const, 0, ""}, - {"NLM_F_ECHO", Const, 0, ""}, - {"NLM_F_EXCL", Const, 0, ""}, - {"NLM_F_MATCH", Const, 0, ""}, - {"NLM_F_MULTI", Const, 0, ""}, - {"NLM_F_REPLACE", Const, 0, ""}, - {"NLM_F_REQUEST", Const, 0, ""}, - {"NLM_F_ROOT", Const, 0, ""}, - {"NOFLSH", Const, 0, ""}, - {"NOTE_ABSOLUTE", Const, 0, ""}, - {"NOTE_ATTRIB", Const, 0, ""}, - {"NOTE_BACKGROUND", Const, 16, ""}, - {"NOTE_CHILD", Const, 0, ""}, - {"NOTE_CRITICAL", Const, 16, ""}, - {"NOTE_DELETE", Const, 0, ""}, - {"NOTE_EOF", Const, 1, ""}, - {"NOTE_EXEC", Const, 0, ""}, - {"NOTE_EXIT", Const, 0, ""}, - {"NOTE_EXITSTATUS", Const, 0, ""}, - {"NOTE_EXIT_CSERROR", Const, 16, ""}, - {"NOTE_EXIT_DECRYPTFAIL", Const, 16, ""}, - {"NOTE_EXIT_DETAIL", Const, 16, ""}, - {"NOTE_EXIT_DETAIL_MASK", Const, 16, ""}, - {"NOTE_EXIT_MEMORY", Const, 16, ""}, - {"NOTE_EXIT_REPARENTED", Const, 16, ""}, - {"NOTE_EXTEND", Const, 0, ""}, - {"NOTE_FFAND", Const, 0, ""}, - {"NOTE_FFCOPY", Const, 0, ""}, - {"NOTE_FFCTRLMASK", Const, 0, ""}, - {"NOTE_FFLAGSMASK", Const, 0, ""}, - {"NOTE_FFNOP", Const, 0, ""}, - {"NOTE_FFOR", Const, 0, ""}, - {"NOTE_FORK", Const, 0, ""}, - {"NOTE_LEEWAY", Const, 16, ""}, - {"NOTE_LINK", Const, 0, ""}, - {"NOTE_LOWAT", Const, 0, ""}, - {"NOTE_NONE", Const, 0, ""}, - {"NOTE_NSECONDS", Const, 0, ""}, - {"NOTE_PCTRLMASK", Const, 0, ""}, - {"NOTE_PDATAMASK", Const, 0, ""}, - {"NOTE_REAP", Const, 0, ""}, - {"NOTE_RENAME", Const, 0, ""}, - {"NOTE_RESOURCEEND", Const, 0, ""}, - {"NOTE_REVOKE", Const, 0, ""}, - {"NOTE_SECONDS", Const, 0, ""}, - {"NOTE_SIGNAL", Const, 0, ""}, - {"NOTE_TRACK", Const, 0, ""}, - {"NOTE_TRACKERR", Const, 0, ""}, - {"NOTE_TRIGGER", Const, 0, ""}, - {"NOTE_TRUNCATE", Const, 1, ""}, - {"NOTE_USECONDS", Const, 0, ""}, - {"NOTE_VM_ERROR", Const, 0, ""}, - {"NOTE_VM_PRESSURE", Const, 0, ""}, - {"NOTE_VM_PRESSURE_SUDDEN_TERMINATE", Const, 0, ""}, - {"NOTE_VM_PRESSURE_TERMINATE", Const, 0, ""}, - {"NOTE_WRITE", Const, 0, ""}, - {"NameCanonical", Const, 0, ""}, - {"NameCanonicalEx", Const, 0, ""}, - {"NameDisplay", Const, 0, ""}, - {"NameDnsDomain", Const, 0, ""}, - {"NameFullyQualifiedDN", Const, 0, ""}, - {"NameSamCompatible", Const, 0, ""}, - {"NameServicePrincipal", Const, 0, ""}, - {"NameUniqueId", Const, 0, ""}, - {"NameUnknown", Const, 0, ""}, - {"NameUserPrincipal", Const, 0, ""}, - {"Nanosleep", Func, 0, "func(time *Timespec, leftover *Timespec) (err error)"}, - {"NetApiBufferFree", Func, 0, ""}, - {"NetGetJoinInformation", Func, 2, ""}, - {"NetSetupDomainName", Const, 2, ""}, - {"NetSetupUnjoined", Const, 2, ""}, - {"NetSetupUnknownStatus", Const, 2, ""}, - {"NetSetupWorkgroupName", Const, 2, ""}, - {"NetUserGetInfo", Func, 0, ""}, - {"NetlinkMessage", Type, 0, ""}, - {"NetlinkMessage.Data", Field, 0, ""}, - {"NetlinkMessage.Header", Field, 0, ""}, - {"NetlinkRIB", Func, 0, "func(proto int, family int) ([]byte, error)"}, - {"NetlinkRouteAttr", Type, 0, ""}, - {"NetlinkRouteAttr.Attr", Field, 0, ""}, - {"NetlinkRouteAttr.Value", Field, 0, ""}, - {"NetlinkRouteRequest", Type, 0, ""}, - {"NetlinkRouteRequest.Data", Field, 0, ""}, - {"NetlinkRouteRequest.Header", Field, 0, ""}, - {"NewCallback", Func, 0, ""}, - {"NewCallbackCDecl", Func, 3, ""}, - {"NewLazyDLL", Func, 0, ""}, - {"NlAttr", Type, 0, ""}, - {"NlAttr.Len", Field, 0, ""}, - {"NlAttr.Type", Field, 0, ""}, - {"NlMsgerr", Type, 0, ""}, - {"NlMsgerr.Error", Field, 0, ""}, - {"NlMsgerr.Msg", Field, 0, ""}, - {"NlMsghdr", Type, 0, ""}, - {"NlMsghdr.Flags", Field, 0, ""}, - {"NlMsghdr.Len", Field, 0, ""}, - {"NlMsghdr.Pid", Field, 0, ""}, - {"NlMsghdr.Seq", Field, 0, ""}, - {"NlMsghdr.Type", Field, 0, ""}, - {"NsecToFiletime", Func, 0, ""}, - {"NsecToTimespec", Func, 0, "func(nsec int64) Timespec"}, - {"NsecToTimeval", Func, 0, "func(nsec int64) Timeval"}, - {"Ntohs", Func, 0, ""}, - {"OCRNL", Const, 0, ""}, - {"OFDEL", Const, 0, ""}, - {"OFILL", Const, 0, ""}, - {"OFIOGETBMAP", Const, 1, ""}, - {"OID_PKIX_KP_SERVER_AUTH", Var, 0, ""}, - {"OID_SERVER_GATED_CRYPTO", Var, 0, ""}, - {"OID_SGC_NETSCAPE", Var, 0, ""}, - {"OLCUC", Const, 0, ""}, - {"ONLCR", Const, 0, ""}, - {"ONLRET", Const, 0, ""}, - {"ONOCR", Const, 0, ""}, - {"ONOEOT", Const, 1, ""}, - {"OPEN_ALWAYS", Const, 0, ""}, - {"OPEN_EXISTING", Const, 0, ""}, - {"OPOST", Const, 0, ""}, - {"O_ACCMODE", Const, 0, ""}, - {"O_ALERT", Const, 0, ""}, - {"O_ALT_IO", Const, 1, ""}, - {"O_APPEND", Const, 0, ""}, - {"O_ASYNC", Const, 0, ""}, - {"O_CLOEXEC", Const, 0, ""}, - {"O_CREAT", Const, 0, ""}, - {"O_DIRECT", Const, 0, ""}, - {"O_DIRECTORY", Const, 0, ""}, - {"O_DP_GETRAWENCRYPTED", Const, 16, ""}, - {"O_DSYNC", Const, 0, ""}, - {"O_EVTONLY", Const, 0, ""}, - {"O_EXCL", Const, 0, ""}, - {"O_EXEC", Const, 0, ""}, - {"O_EXLOCK", Const, 0, ""}, - {"O_FSYNC", Const, 0, ""}, - {"O_LARGEFILE", Const, 0, ""}, - {"O_NDELAY", Const, 0, ""}, - {"O_NOATIME", Const, 0, ""}, - {"O_NOCTTY", Const, 0, ""}, - {"O_NOFOLLOW", Const, 0, ""}, - {"O_NONBLOCK", Const, 0, ""}, - {"O_NOSIGPIPE", Const, 1, ""}, - {"O_POPUP", Const, 0, ""}, - {"O_RDONLY", Const, 0, ""}, - {"O_RDWR", Const, 0, ""}, - {"O_RSYNC", Const, 0, ""}, - {"O_SHLOCK", Const, 0, ""}, - {"O_SYMLINK", Const, 0, ""}, - {"O_SYNC", Const, 0, ""}, - {"O_TRUNC", Const, 0, ""}, - {"O_TTY_INIT", Const, 0, ""}, - {"O_WRONLY", Const, 0, ""}, - {"Open", Func, 0, "func(path string, mode int, perm uint32) (fd int, err error)"}, - {"OpenCurrentProcessToken", Func, 0, ""}, - {"OpenProcess", Func, 0, ""}, - {"OpenProcessToken", Func, 0, ""}, - {"Openat", Func, 0, "func(dirfd int, path string, flags int, mode uint32) (fd int, err error)"}, - {"Overlapped", Type, 0, ""}, - {"Overlapped.HEvent", Field, 0, ""}, - {"Overlapped.Internal", Field, 0, ""}, - {"Overlapped.InternalHigh", Field, 0, ""}, - {"Overlapped.Offset", Field, 0, ""}, - {"Overlapped.OffsetHigh", Field, 0, ""}, - {"PACKET_ADD_MEMBERSHIP", Const, 0, ""}, - {"PACKET_BROADCAST", Const, 0, ""}, - {"PACKET_DROP_MEMBERSHIP", Const, 0, ""}, - {"PACKET_FASTROUTE", Const, 0, ""}, - {"PACKET_HOST", Const, 0, ""}, - {"PACKET_LOOPBACK", Const, 0, ""}, - {"PACKET_MR_ALLMULTI", Const, 0, ""}, - {"PACKET_MR_MULTICAST", Const, 0, ""}, - {"PACKET_MR_PROMISC", Const, 0, ""}, - {"PACKET_MULTICAST", Const, 0, ""}, - {"PACKET_OTHERHOST", Const, 0, ""}, - {"PACKET_OUTGOING", Const, 0, ""}, - {"PACKET_RECV_OUTPUT", Const, 0, ""}, - {"PACKET_RX_RING", Const, 0, ""}, - {"PACKET_STATISTICS", Const, 0, ""}, - {"PAGE_EXECUTE_READ", Const, 0, ""}, - {"PAGE_EXECUTE_READWRITE", Const, 0, ""}, - {"PAGE_EXECUTE_WRITECOPY", Const, 0, ""}, - {"PAGE_READONLY", Const, 0, ""}, - {"PAGE_READWRITE", Const, 0, ""}, - {"PAGE_WRITECOPY", Const, 0, ""}, - {"PARENB", Const, 0, ""}, - {"PARMRK", Const, 0, ""}, - {"PARODD", Const, 0, ""}, - {"PENDIN", Const, 0, ""}, - {"PFL_HIDDEN", Const, 2, ""}, - {"PFL_MATCHES_PROTOCOL_ZERO", Const, 2, ""}, - {"PFL_MULTIPLE_PROTO_ENTRIES", Const, 2, ""}, - {"PFL_NETWORKDIRECT_PROVIDER", Const, 2, ""}, - {"PFL_RECOMMENDED_PROTO_ENTRY", Const, 2, ""}, - {"PF_FLUSH", Const, 1, ""}, - {"PKCS_7_ASN_ENCODING", Const, 0, ""}, - {"PMC5_PIPELINE_FLUSH", Const, 1, ""}, - {"PRIO_PGRP", Const, 2, ""}, - {"PRIO_PROCESS", Const, 2, ""}, - {"PRIO_USER", Const, 2, ""}, - {"PRI_IOFLUSH", Const, 1, ""}, - {"PROCESS_QUERY_INFORMATION", Const, 0, ""}, - {"PROCESS_TERMINATE", Const, 2, ""}, - {"PROT_EXEC", Const, 0, ""}, - {"PROT_GROWSDOWN", Const, 0, ""}, - {"PROT_GROWSUP", Const, 0, ""}, - {"PROT_NONE", Const, 0, ""}, - {"PROT_READ", Const, 0, ""}, - {"PROT_WRITE", Const, 0, ""}, - {"PROV_DH_SCHANNEL", Const, 0, ""}, - {"PROV_DSS", Const, 0, ""}, - {"PROV_DSS_DH", Const, 0, ""}, - {"PROV_EC_ECDSA_FULL", Const, 0, ""}, - {"PROV_EC_ECDSA_SIG", Const, 0, ""}, - {"PROV_EC_ECNRA_FULL", Const, 0, ""}, - {"PROV_EC_ECNRA_SIG", Const, 0, ""}, - {"PROV_FORTEZZA", Const, 0, ""}, - {"PROV_INTEL_SEC", Const, 0, ""}, - {"PROV_MS_EXCHANGE", Const, 0, ""}, - {"PROV_REPLACE_OWF", Const, 0, ""}, - {"PROV_RNG", Const, 0, ""}, - {"PROV_RSA_AES", Const, 0, ""}, - {"PROV_RSA_FULL", Const, 0, ""}, - {"PROV_RSA_SCHANNEL", Const, 0, ""}, - {"PROV_RSA_SIG", Const, 0, ""}, - {"PROV_SPYRUS_LYNKS", Const, 0, ""}, - {"PROV_SSL", Const, 0, ""}, - {"PR_CAPBSET_DROP", Const, 0, ""}, - {"PR_CAPBSET_READ", Const, 0, ""}, - {"PR_CLEAR_SECCOMP_FILTER", Const, 0, ""}, - {"PR_ENDIAN_BIG", Const, 0, ""}, - {"PR_ENDIAN_LITTLE", Const, 0, ""}, - {"PR_ENDIAN_PPC_LITTLE", Const, 0, ""}, - {"PR_FPEMU_NOPRINT", Const, 0, ""}, - {"PR_FPEMU_SIGFPE", Const, 0, ""}, - {"PR_FP_EXC_ASYNC", Const, 0, ""}, - {"PR_FP_EXC_DISABLED", Const, 0, ""}, - {"PR_FP_EXC_DIV", Const, 0, ""}, - {"PR_FP_EXC_INV", Const, 0, ""}, - {"PR_FP_EXC_NONRECOV", Const, 0, ""}, - {"PR_FP_EXC_OVF", Const, 0, ""}, - {"PR_FP_EXC_PRECISE", Const, 0, ""}, - {"PR_FP_EXC_RES", Const, 0, ""}, - {"PR_FP_EXC_SW_ENABLE", Const, 0, ""}, - {"PR_FP_EXC_UND", Const, 0, ""}, - {"PR_GET_DUMPABLE", Const, 0, ""}, - {"PR_GET_ENDIAN", Const, 0, ""}, - {"PR_GET_FPEMU", Const, 0, ""}, - {"PR_GET_FPEXC", Const, 0, ""}, - {"PR_GET_KEEPCAPS", Const, 0, ""}, - {"PR_GET_NAME", Const, 0, ""}, - {"PR_GET_PDEATHSIG", Const, 0, ""}, - {"PR_GET_SECCOMP", Const, 0, ""}, - {"PR_GET_SECCOMP_FILTER", Const, 0, ""}, - {"PR_GET_SECUREBITS", Const, 0, ""}, - {"PR_GET_TIMERSLACK", Const, 0, ""}, - {"PR_GET_TIMING", Const, 0, ""}, - {"PR_GET_TSC", Const, 0, ""}, - {"PR_GET_UNALIGN", Const, 0, ""}, - {"PR_MCE_KILL", Const, 0, ""}, - {"PR_MCE_KILL_CLEAR", Const, 0, ""}, - {"PR_MCE_KILL_DEFAULT", Const, 0, ""}, - {"PR_MCE_KILL_EARLY", Const, 0, ""}, - {"PR_MCE_KILL_GET", Const, 0, ""}, - {"PR_MCE_KILL_LATE", Const, 0, ""}, - {"PR_MCE_KILL_SET", Const, 0, ""}, - {"PR_SECCOMP_FILTER_EVENT", Const, 0, ""}, - {"PR_SECCOMP_FILTER_SYSCALL", Const, 0, ""}, - {"PR_SET_DUMPABLE", Const, 0, ""}, - {"PR_SET_ENDIAN", Const, 0, ""}, - {"PR_SET_FPEMU", Const, 0, ""}, - {"PR_SET_FPEXC", Const, 0, ""}, - {"PR_SET_KEEPCAPS", Const, 0, ""}, - {"PR_SET_NAME", Const, 0, ""}, - {"PR_SET_PDEATHSIG", Const, 0, ""}, - {"PR_SET_PTRACER", Const, 0, ""}, - {"PR_SET_SECCOMP", Const, 0, ""}, - {"PR_SET_SECCOMP_FILTER", Const, 0, ""}, - {"PR_SET_SECUREBITS", Const, 0, ""}, - {"PR_SET_TIMERSLACK", Const, 0, ""}, - {"PR_SET_TIMING", Const, 0, ""}, - {"PR_SET_TSC", Const, 0, ""}, - {"PR_SET_UNALIGN", Const, 0, ""}, - {"PR_TASK_PERF_EVENTS_DISABLE", Const, 0, ""}, - {"PR_TASK_PERF_EVENTS_ENABLE", Const, 0, ""}, - {"PR_TIMING_STATISTICAL", Const, 0, ""}, - {"PR_TIMING_TIMESTAMP", Const, 0, ""}, - {"PR_TSC_ENABLE", Const, 0, ""}, - {"PR_TSC_SIGSEGV", Const, 0, ""}, - {"PR_UNALIGN_NOPRINT", Const, 0, ""}, - {"PR_UNALIGN_SIGBUS", Const, 0, ""}, - {"PTRACE_ARCH_PRCTL", Const, 0, ""}, - {"PTRACE_ATTACH", Const, 0, ""}, - {"PTRACE_CONT", Const, 0, ""}, - {"PTRACE_DETACH", Const, 0, ""}, - {"PTRACE_EVENT_CLONE", Const, 0, ""}, - {"PTRACE_EVENT_EXEC", Const, 0, ""}, - {"PTRACE_EVENT_EXIT", Const, 0, ""}, - {"PTRACE_EVENT_FORK", Const, 0, ""}, - {"PTRACE_EVENT_VFORK", Const, 0, ""}, - {"PTRACE_EVENT_VFORK_DONE", Const, 0, ""}, - {"PTRACE_GETCRUNCHREGS", Const, 0, ""}, - {"PTRACE_GETEVENTMSG", Const, 0, ""}, - {"PTRACE_GETFPREGS", Const, 0, ""}, - {"PTRACE_GETFPXREGS", Const, 0, ""}, - {"PTRACE_GETHBPREGS", Const, 0, ""}, - {"PTRACE_GETREGS", Const, 0, ""}, - {"PTRACE_GETREGSET", Const, 0, ""}, - {"PTRACE_GETSIGINFO", Const, 0, ""}, - {"PTRACE_GETVFPREGS", Const, 0, ""}, - {"PTRACE_GETWMMXREGS", Const, 0, ""}, - {"PTRACE_GET_THREAD_AREA", Const, 0, ""}, - {"PTRACE_KILL", Const, 0, ""}, - {"PTRACE_OLDSETOPTIONS", Const, 0, ""}, - {"PTRACE_O_MASK", Const, 0, ""}, - {"PTRACE_O_TRACECLONE", Const, 0, ""}, - {"PTRACE_O_TRACEEXEC", Const, 0, ""}, - {"PTRACE_O_TRACEEXIT", Const, 0, ""}, - {"PTRACE_O_TRACEFORK", Const, 0, ""}, - {"PTRACE_O_TRACESYSGOOD", Const, 0, ""}, - {"PTRACE_O_TRACEVFORK", Const, 0, ""}, - {"PTRACE_O_TRACEVFORKDONE", Const, 0, ""}, - {"PTRACE_PEEKDATA", Const, 0, ""}, - {"PTRACE_PEEKTEXT", Const, 0, ""}, - {"PTRACE_PEEKUSR", Const, 0, ""}, - {"PTRACE_POKEDATA", Const, 0, ""}, - {"PTRACE_POKETEXT", Const, 0, ""}, - {"PTRACE_POKEUSR", Const, 0, ""}, - {"PTRACE_SETCRUNCHREGS", Const, 0, ""}, - {"PTRACE_SETFPREGS", Const, 0, ""}, - {"PTRACE_SETFPXREGS", Const, 0, ""}, - {"PTRACE_SETHBPREGS", Const, 0, ""}, - {"PTRACE_SETOPTIONS", Const, 0, ""}, - {"PTRACE_SETREGS", Const, 0, ""}, - {"PTRACE_SETREGSET", Const, 0, ""}, - {"PTRACE_SETSIGINFO", Const, 0, ""}, - {"PTRACE_SETVFPREGS", Const, 0, ""}, - {"PTRACE_SETWMMXREGS", Const, 0, ""}, - {"PTRACE_SET_SYSCALL", Const, 0, ""}, - {"PTRACE_SET_THREAD_AREA", Const, 0, ""}, - {"PTRACE_SINGLEBLOCK", Const, 0, ""}, - {"PTRACE_SINGLESTEP", Const, 0, ""}, - {"PTRACE_SYSCALL", Const, 0, ""}, - {"PTRACE_SYSEMU", Const, 0, ""}, - {"PTRACE_SYSEMU_SINGLESTEP", Const, 0, ""}, - {"PTRACE_TRACEME", Const, 0, ""}, - {"PT_ATTACH", Const, 0, ""}, - {"PT_ATTACHEXC", Const, 0, ""}, - {"PT_CONTINUE", Const, 0, ""}, - {"PT_DATA_ADDR", Const, 0, ""}, - {"PT_DENY_ATTACH", Const, 0, ""}, - {"PT_DETACH", Const, 0, ""}, - {"PT_FIRSTMACH", Const, 0, ""}, - {"PT_FORCEQUOTA", Const, 0, ""}, - {"PT_KILL", Const, 0, ""}, - {"PT_MASK", Const, 1, ""}, - {"PT_READ_D", Const, 0, ""}, - {"PT_READ_I", Const, 0, ""}, - {"PT_READ_U", Const, 0, ""}, - {"PT_SIGEXC", Const, 0, ""}, - {"PT_STEP", Const, 0, ""}, - {"PT_TEXT_ADDR", Const, 0, ""}, - {"PT_TEXT_END_ADDR", Const, 0, ""}, - {"PT_THUPDATE", Const, 0, ""}, - {"PT_TRACE_ME", Const, 0, ""}, - {"PT_WRITE_D", Const, 0, ""}, - {"PT_WRITE_I", Const, 0, ""}, - {"PT_WRITE_U", Const, 0, ""}, - {"ParseDirent", Func, 0, "func(buf []byte, max int, names []string) (consumed int, count int, newnames []string)"}, - {"ParseNetlinkMessage", Func, 0, "func(b []byte) ([]NetlinkMessage, error)"}, - {"ParseNetlinkRouteAttr", Func, 0, "func(m *NetlinkMessage) ([]NetlinkRouteAttr, error)"}, - {"ParseRoutingMessage", Func, 0, ""}, - {"ParseRoutingSockaddr", Func, 0, ""}, - {"ParseSocketControlMessage", Func, 0, "func(b []byte) ([]SocketControlMessage, error)"}, - {"ParseUnixCredentials", Func, 0, "func(m *SocketControlMessage) (*Ucred, error)"}, - {"ParseUnixRights", Func, 0, "func(m *SocketControlMessage) ([]int, error)"}, - {"PathMax", Const, 0, ""}, - {"Pathconf", Func, 0, ""}, - {"Pause", Func, 0, "func() (err error)"}, - {"Pipe", Func, 0, "func(p []int) error"}, - {"Pipe2", Func, 1, "func(p []int, flags int) error"}, - {"PivotRoot", Func, 0, "func(newroot string, putold string) (err error)"}, - {"Pointer", Type, 11, ""}, - {"PostQueuedCompletionStatus", Func, 0, ""}, - {"Pread", Func, 0, "func(fd int, p []byte, offset int64) (n int, err error)"}, - {"Proc", Type, 0, ""}, - {"Proc.Dll", Field, 0, ""}, - {"Proc.Name", Field, 0, ""}, - {"ProcAttr", Type, 0, ""}, - {"ProcAttr.Dir", Field, 0, ""}, - {"ProcAttr.Env", Field, 0, ""}, - {"ProcAttr.Files", Field, 0, ""}, - {"ProcAttr.Sys", Field, 0, ""}, - {"Process32First", Func, 4, ""}, - {"Process32Next", Func, 4, ""}, - {"ProcessEntry32", Type, 4, ""}, - {"ProcessEntry32.DefaultHeapID", Field, 4, ""}, - {"ProcessEntry32.ExeFile", Field, 4, ""}, - {"ProcessEntry32.Flags", Field, 4, ""}, - {"ProcessEntry32.ModuleID", Field, 4, ""}, - {"ProcessEntry32.ParentProcessID", Field, 4, ""}, - {"ProcessEntry32.PriClassBase", Field, 4, ""}, - {"ProcessEntry32.ProcessID", Field, 4, ""}, - {"ProcessEntry32.Size", Field, 4, ""}, - {"ProcessEntry32.Threads", Field, 4, ""}, - {"ProcessEntry32.Usage", Field, 4, ""}, - {"ProcessInformation", Type, 0, ""}, - {"ProcessInformation.Process", Field, 0, ""}, - {"ProcessInformation.ProcessId", Field, 0, ""}, - {"ProcessInformation.Thread", Field, 0, ""}, - {"ProcessInformation.ThreadId", Field, 0, ""}, - {"Protoent", Type, 0, ""}, - {"Protoent.Aliases", Field, 0, ""}, - {"Protoent.Name", Field, 0, ""}, - {"Protoent.Proto", Field, 0, ""}, - {"PtraceAttach", Func, 0, "func(pid int) (err error)"}, - {"PtraceCont", Func, 0, "func(pid int, signal int) (err error)"}, - {"PtraceDetach", Func, 0, "func(pid int) (err error)"}, - {"PtraceGetEventMsg", Func, 0, "func(pid int) (msg uint, err error)"}, - {"PtraceGetRegs", Func, 0, "func(pid int, regsout *PtraceRegs) (err error)"}, - {"PtracePeekData", Func, 0, "func(pid int, addr uintptr, out []byte) (count int, err error)"}, - {"PtracePeekText", Func, 0, "func(pid int, addr uintptr, out []byte) (count int, err error)"}, - {"PtracePokeData", Func, 0, "func(pid int, addr uintptr, data []byte) (count int, err error)"}, - {"PtracePokeText", Func, 0, "func(pid int, addr uintptr, data []byte) (count int, err error)"}, - {"PtraceRegs", Type, 0, ""}, - {"PtraceRegs.Cs", Field, 0, ""}, - {"PtraceRegs.Ds", Field, 0, ""}, - {"PtraceRegs.Eax", Field, 0, ""}, - {"PtraceRegs.Ebp", Field, 0, ""}, - {"PtraceRegs.Ebx", Field, 0, ""}, - {"PtraceRegs.Ecx", Field, 0, ""}, - {"PtraceRegs.Edi", Field, 0, ""}, - {"PtraceRegs.Edx", Field, 0, ""}, - {"PtraceRegs.Eflags", Field, 0, ""}, - {"PtraceRegs.Eip", Field, 0, ""}, - {"PtraceRegs.Es", Field, 0, ""}, - {"PtraceRegs.Esi", Field, 0, ""}, - {"PtraceRegs.Esp", Field, 0, ""}, - {"PtraceRegs.Fs", Field, 0, ""}, - {"PtraceRegs.Fs_base", Field, 0, ""}, - {"PtraceRegs.Gs", Field, 0, ""}, - {"PtraceRegs.Gs_base", Field, 0, ""}, - {"PtraceRegs.Orig_eax", Field, 0, ""}, - {"PtraceRegs.Orig_rax", Field, 0, ""}, - {"PtraceRegs.R10", Field, 0, ""}, - {"PtraceRegs.R11", Field, 0, ""}, - {"PtraceRegs.R12", Field, 0, ""}, - {"PtraceRegs.R13", Field, 0, ""}, - {"PtraceRegs.R14", Field, 0, ""}, - {"PtraceRegs.R15", Field, 0, ""}, - {"PtraceRegs.R8", Field, 0, ""}, - {"PtraceRegs.R9", Field, 0, ""}, - {"PtraceRegs.Rax", Field, 0, ""}, - {"PtraceRegs.Rbp", Field, 0, ""}, - {"PtraceRegs.Rbx", Field, 0, ""}, - {"PtraceRegs.Rcx", Field, 0, ""}, - {"PtraceRegs.Rdi", Field, 0, ""}, - {"PtraceRegs.Rdx", Field, 0, ""}, - {"PtraceRegs.Rip", Field, 0, ""}, - {"PtraceRegs.Rsi", Field, 0, ""}, - {"PtraceRegs.Rsp", Field, 0, ""}, - {"PtraceRegs.Ss", Field, 0, ""}, - {"PtraceRegs.Uregs", Field, 0, ""}, - {"PtraceRegs.Xcs", Field, 0, ""}, - {"PtraceRegs.Xds", Field, 0, ""}, - {"PtraceRegs.Xes", Field, 0, ""}, - {"PtraceRegs.Xfs", Field, 0, ""}, - {"PtraceRegs.Xgs", Field, 0, ""}, - {"PtraceRegs.Xss", Field, 0, ""}, - {"PtraceSetOptions", Func, 0, "func(pid int, options int) (err error)"}, - {"PtraceSetRegs", Func, 0, "func(pid int, regs *PtraceRegs) (err error)"}, - {"PtraceSingleStep", Func, 0, "func(pid int) (err error)"}, - {"PtraceSyscall", Func, 1, "func(pid int, signal int) (err error)"}, - {"Pwrite", Func, 0, "func(fd int, p []byte, offset int64) (n int, err error)"}, - {"REG_BINARY", Const, 0, ""}, - {"REG_DWORD", Const, 0, ""}, - {"REG_DWORD_BIG_ENDIAN", Const, 0, ""}, - {"REG_DWORD_LITTLE_ENDIAN", Const, 0, ""}, - {"REG_EXPAND_SZ", Const, 0, ""}, - {"REG_FULL_RESOURCE_DESCRIPTOR", Const, 0, ""}, - {"REG_LINK", Const, 0, ""}, - {"REG_MULTI_SZ", Const, 0, ""}, - {"REG_NONE", Const, 0, ""}, - {"REG_QWORD", Const, 0, ""}, - {"REG_QWORD_LITTLE_ENDIAN", Const, 0, ""}, - {"REG_RESOURCE_LIST", Const, 0, ""}, - {"REG_RESOURCE_REQUIREMENTS_LIST", Const, 0, ""}, - {"REG_SZ", Const, 0, ""}, - {"RLIMIT_AS", Const, 0, ""}, - {"RLIMIT_CORE", Const, 0, ""}, - {"RLIMIT_CPU", Const, 0, ""}, - {"RLIMIT_CPU_USAGE_MONITOR", Const, 16, ""}, - {"RLIMIT_DATA", Const, 0, ""}, - {"RLIMIT_FSIZE", Const, 0, ""}, - {"RLIMIT_NOFILE", Const, 0, ""}, - {"RLIMIT_STACK", Const, 0, ""}, - {"RLIM_INFINITY", Const, 0, ""}, - {"RTAX_ADVMSS", Const, 0, ""}, - {"RTAX_AUTHOR", Const, 0, ""}, - {"RTAX_BRD", Const, 0, ""}, - {"RTAX_CWND", Const, 0, ""}, - {"RTAX_DST", Const, 0, ""}, - {"RTAX_FEATURES", Const, 0, ""}, - {"RTAX_FEATURE_ALLFRAG", Const, 0, ""}, - {"RTAX_FEATURE_ECN", Const, 0, ""}, - {"RTAX_FEATURE_SACK", Const, 0, ""}, - {"RTAX_FEATURE_TIMESTAMP", Const, 0, ""}, - {"RTAX_GATEWAY", Const, 0, ""}, - {"RTAX_GENMASK", Const, 0, ""}, - {"RTAX_HOPLIMIT", Const, 0, ""}, - {"RTAX_IFA", Const, 0, ""}, - {"RTAX_IFP", Const, 0, ""}, - {"RTAX_INITCWND", Const, 0, ""}, - {"RTAX_INITRWND", Const, 0, ""}, - {"RTAX_LABEL", Const, 1, ""}, - {"RTAX_LOCK", Const, 0, ""}, - {"RTAX_MAX", Const, 0, ""}, - {"RTAX_MTU", Const, 0, ""}, - {"RTAX_NETMASK", Const, 0, ""}, - {"RTAX_REORDERING", Const, 0, ""}, - {"RTAX_RTO_MIN", Const, 0, ""}, - {"RTAX_RTT", Const, 0, ""}, - {"RTAX_RTTVAR", Const, 0, ""}, - {"RTAX_SRC", Const, 1, ""}, - {"RTAX_SRCMASK", Const, 1, ""}, - {"RTAX_SSTHRESH", Const, 0, ""}, - {"RTAX_TAG", Const, 1, ""}, - {"RTAX_UNSPEC", Const, 0, ""}, - {"RTAX_WINDOW", Const, 0, ""}, - {"RTA_ALIGNTO", Const, 0, ""}, - {"RTA_AUTHOR", Const, 0, ""}, - {"RTA_BRD", Const, 0, ""}, - {"RTA_CACHEINFO", Const, 0, ""}, - {"RTA_DST", Const, 0, ""}, - {"RTA_FLOW", Const, 0, ""}, - {"RTA_GATEWAY", Const, 0, ""}, - {"RTA_GENMASK", Const, 0, ""}, - {"RTA_IFA", Const, 0, ""}, - {"RTA_IFP", Const, 0, ""}, - {"RTA_IIF", Const, 0, ""}, - {"RTA_LABEL", Const, 1, ""}, - {"RTA_MAX", Const, 0, ""}, - {"RTA_METRICS", Const, 0, ""}, - {"RTA_MULTIPATH", Const, 0, ""}, - {"RTA_NETMASK", Const, 0, ""}, - {"RTA_OIF", Const, 0, ""}, - {"RTA_PREFSRC", Const, 0, ""}, - {"RTA_PRIORITY", Const, 0, ""}, - {"RTA_SRC", Const, 0, ""}, - {"RTA_SRCMASK", Const, 1, ""}, - {"RTA_TABLE", Const, 0, ""}, - {"RTA_TAG", Const, 1, ""}, - {"RTA_UNSPEC", Const, 0, ""}, - {"RTCF_DIRECTSRC", Const, 0, ""}, - {"RTCF_DOREDIRECT", Const, 0, ""}, - {"RTCF_LOG", Const, 0, ""}, - {"RTCF_MASQ", Const, 0, ""}, - {"RTCF_NAT", Const, 0, ""}, - {"RTCF_VALVE", Const, 0, ""}, - {"RTF_ADDRCLASSMASK", Const, 0, ""}, - {"RTF_ADDRCONF", Const, 0, ""}, - {"RTF_ALLONLINK", Const, 0, ""}, - {"RTF_ANNOUNCE", Const, 1, ""}, - {"RTF_BLACKHOLE", Const, 0, ""}, - {"RTF_BROADCAST", Const, 0, ""}, - {"RTF_CACHE", Const, 0, ""}, - {"RTF_CLONED", Const, 1, ""}, - {"RTF_CLONING", Const, 0, ""}, - {"RTF_CONDEMNED", Const, 0, ""}, - {"RTF_DEFAULT", Const, 0, ""}, - {"RTF_DELCLONE", Const, 0, ""}, - {"RTF_DONE", Const, 0, ""}, - {"RTF_DYNAMIC", Const, 0, ""}, - {"RTF_FLOW", Const, 0, ""}, - {"RTF_FMASK", Const, 0, ""}, - {"RTF_GATEWAY", Const, 0, ""}, - {"RTF_GWFLAG_COMPAT", Const, 3, ""}, - {"RTF_HOST", Const, 0, ""}, - {"RTF_IFREF", Const, 0, ""}, - {"RTF_IFSCOPE", Const, 0, ""}, - {"RTF_INTERFACE", Const, 0, ""}, - {"RTF_IRTT", Const, 0, ""}, - {"RTF_LINKRT", Const, 0, ""}, - {"RTF_LLDATA", Const, 0, ""}, - {"RTF_LLINFO", Const, 0, ""}, - {"RTF_LOCAL", Const, 0, ""}, - {"RTF_MASK", Const, 1, ""}, - {"RTF_MODIFIED", Const, 0, ""}, - {"RTF_MPATH", Const, 1, ""}, - {"RTF_MPLS", Const, 1, ""}, - {"RTF_MSS", Const, 0, ""}, - {"RTF_MTU", Const, 0, ""}, - {"RTF_MULTICAST", Const, 0, ""}, - {"RTF_NAT", Const, 0, ""}, - {"RTF_NOFORWARD", Const, 0, ""}, - {"RTF_NONEXTHOP", Const, 0, ""}, - {"RTF_NOPMTUDISC", Const, 0, ""}, - {"RTF_PERMANENT_ARP", Const, 1, ""}, - {"RTF_PINNED", Const, 0, ""}, - {"RTF_POLICY", Const, 0, ""}, - {"RTF_PRCLONING", Const, 0, ""}, - {"RTF_PROTO1", Const, 0, ""}, - {"RTF_PROTO2", Const, 0, ""}, - {"RTF_PROTO3", Const, 0, ""}, - {"RTF_PROXY", Const, 16, ""}, - {"RTF_REINSTATE", Const, 0, ""}, - {"RTF_REJECT", Const, 0, ""}, - {"RTF_RNH_LOCKED", Const, 0, ""}, - {"RTF_ROUTER", Const, 16, ""}, - {"RTF_SOURCE", Const, 1, ""}, - {"RTF_SRC", Const, 1, ""}, - {"RTF_STATIC", Const, 0, ""}, - {"RTF_STICKY", Const, 0, ""}, - {"RTF_THROW", Const, 0, ""}, - {"RTF_TUNNEL", Const, 1, ""}, - {"RTF_UP", Const, 0, ""}, - {"RTF_USETRAILERS", Const, 1, ""}, - {"RTF_WASCLONED", Const, 0, ""}, - {"RTF_WINDOW", Const, 0, ""}, - {"RTF_XRESOLVE", Const, 0, ""}, - {"RTM_ADD", Const, 0, ""}, - {"RTM_BASE", Const, 0, ""}, - {"RTM_CHANGE", Const, 0, ""}, - {"RTM_CHGADDR", Const, 1, ""}, - {"RTM_DELACTION", Const, 0, ""}, - {"RTM_DELADDR", Const, 0, ""}, - {"RTM_DELADDRLABEL", Const, 0, ""}, - {"RTM_DELETE", Const, 0, ""}, - {"RTM_DELLINK", Const, 0, ""}, - {"RTM_DELMADDR", Const, 0, ""}, - {"RTM_DELNEIGH", Const, 0, ""}, - {"RTM_DELQDISC", Const, 0, ""}, - {"RTM_DELROUTE", Const, 0, ""}, - {"RTM_DELRULE", Const, 0, ""}, - {"RTM_DELTCLASS", Const, 0, ""}, - {"RTM_DELTFILTER", Const, 0, ""}, - {"RTM_DESYNC", Const, 1, ""}, - {"RTM_F_CLONED", Const, 0, ""}, - {"RTM_F_EQUALIZE", Const, 0, ""}, - {"RTM_F_NOTIFY", Const, 0, ""}, - {"RTM_F_PREFIX", Const, 0, ""}, - {"RTM_GET", Const, 0, ""}, - {"RTM_GET2", Const, 0, ""}, - {"RTM_GETACTION", Const, 0, ""}, - {"RTM_GETADDR", Const, 0, ""}, - {"RTM_GETADDRLABEL", Const, 0, ""}, - {"RTM_GETANYCAST", Const, 0, ""}, - {"RTM_GETDCB", Const, 0, ""}, - {"RTM_GETLINK", Const, 0, ""}, - {"RTM_GETMULTICAST", Const, 0, ""}, - {"RTM_GETNEIGH", Const, 0, ""}, - {"RTM_GETNEIGHTBL", Const, 0, ""}, - {"RTM_GETQDISC", Const, 0, ""}, - {"RTM_GETROUTE", Const, 0, ""}, - {"RTM_GETRULE", Const, 0, ""}, - {"RTM_GETTCLASS", Const, 0, ""}, - {"RTM_GETTFILTER", Const, 0, ""}, - {"RTM_IEEE80211", Const, 0, ""}, - {"RTM_IFANNOUNCE", Const, 0, ""}, - {"RTM_IFINFO", Const, 0, ""}, - {"RTM_IFINFO2", Const, 0, ""}, - {"RTM_LLINFO_UPD", Const, 1, ""}, - {"RTM_LOCK", Const, 0, ""}, - {"RTM_LOSING", Const, 0, ""}, - {"RTM_MAX", Const, 0, ""}, - {"RTM_MAXSIZE", Const, 1, ""}, - {"RTM_MISS", Const, 0, ""}, - {"RTM_NEWACTION", Const, 0, ""}, - {"RTM_NEWADDR", Const, 0, ""}, - {"RTM_NEWADDRLABEL", Const, 0, ""}, - {"RTM_NEWLINK", Const, 0, ""}, - {"RTM_NEWMADDR", Const, 0, ""}, - {"RTM_NEWMADDR2", Const, 0, ""}, - {"RTM_NEWNDUSEROPT", Const, 0, ""}, - {"RTM_NEWNEIGH", Const, 0, ""}, - {"RTM_NEWNEIGHTBL", Const, 0, ""}, - {"RTM_NEWPREFIX", Const, 0, ""}, - {"RTM_NEWQDISC", Const, 0, ""}, - {"RTM_NEWROUTE", Const, 0, ""}, - {"RTM_NEWRULE", Const, 0, ""}, - {"RTM_NEWTCLASS", Const, 0, ""}, - {"RTM_NEWTFILTER", Const, 0, ""}, - {"RTM_NR_FAMILIES", Const, 0, ""}, - {"RTM_NR_MSGTYPES", Const, 0, ""}, - {"RTM_OIFINFO", Const, 1, ""}, - {"RTM_OLDADD", Const, 0, ""}, - {"RTM_OLDDEL", Const, 0, ""}, - {"RTM_OOIFINFO", Const, 1, ""}, - {"RTM_REDIRECT", Const, 0, ""}, - {"RTM_RESOLVE", Const, 0, ""}, - {"RTM_RTTUNIT", Const, 0, ""}, - {"RTM_SETDCB", Const, 0, ""}, - {"RTM_SETGATE", Const, 1, ""}, - {"RTM_SETLINK", Const, 0, ""}, - {"RTM_SETNEIGHTBL", Const, 0, ""}, - {"RTM_VERSION", Const, 0, ""}, - {"RTNH_ALIGNTO", Const, 0, ""}, - {"RTNH_F_DEAD", Const, 0, ""}, - {"RTNH_F_ONLINK", Const, 0, ""}, - {"RTNH_F_PERVASIVE", Const, 0, ""}, - {"RTNLGRP_IPV4_IFADDR", Const, 1, ""}, - {"RTNLGRP_IPV4_MROUTE", Const, 1, ""}, - {"RTNLGRP_IPV4_ROUTE", Const, 1, ""}, - {"RTNLGRP_IPV4_RULE", Const, 1, ""}, - {"RTNLGRP_IPV6_IFADDR", Const, 1, ""}, - {"RTNLGRP_IPV6_IFINFO", Const, 1, ""}, - {"RTNLGRP_IPV6_MROUTE", Const, 1, ""}, - {"RTNLGRP_IPV6_PREFIX", Const, 1, ""}, - {"RTNLGRP_IPV6_ROUTE", Const, 1, ""}, - {"RTNLGRP_IPV6_RULE", Const, 1, ""}, - {"RTNLGRP_LINK", Const, 1, ""}, - {"RTNLGRP_ND_USEROPT", Const, 1, ""}, - {"RTNLGRP_NEIGH", Const, 1, ""}, - {"RTNLGRP_NONE", Const, 1, ""}, - {"RTNLGRP_NOTIFY", Const, 1, ""}, - {"RTNLGRP_TC", Const, 1, ""}, - {"RTN_ANYCAST", Const, 0, ""}, - {"RTN_BLACKHOLE", Const, 0, ""}, - {"RTN_BROADCAST", Const, 0, ""}, - {"RTN_LOCAL", Const, 0, ""}, - {"RTN_MAX", Const, 0, ""}, - {"RTN_MULTICAST", Const, 0, ""}, - {"RTN_NAT", Const, 0, ""}, - {"RTN_PROHIBIT", Const, 0, ""}, - {"RTN_THROW", Const, 0, ""}, - {"RTN_UNICAST", Const, 0, ""}, - {"RTN_UNREACHABLE", Const, 0, ""}, - {"RTN_UNSPEC", Const, 0, ""}, - {"RTN_XRESOLVE", Const, 0, ""}, - {"RTPROT_BIRD", Const, 0, ""}, - {"RTPROT_BOOT", Const, 0, ""}, - {"RTPROT_DHCP", Const, 0, ""}, - {"RTPROT_DNROUTED", Const, 0, ""}, - {"RTPROT_GATED", Const, 0, ""}, - {"RTPROT_KERNEL", Const, 0, ""}, - {"RTPROT_MRT", Const, 0, ""}, - {"RTPROT_NTK", Const, 0, ""}, - {"RTPROT_RA", Const, 0, ""}, - {"RTPROT_REDIRECT", Const, 0, ""}, - {"RTPROT_STATIC", Const, 0, ""}, - {"RTPROT_UNSPEC", Const, 0, ""}, - {"RTPROT_XORP", Const, 0, ""}, - {"RTPROT_ZEBRA", Const, 0, ""}, - {"RTV_EXPIRE", Const, 0, ""}, - {"RTV_HOPCOUNT", Const, 0, ""}, - {"RTV_MTU", Const, 0, ""}, - {"RTV_RPIPE", Const, 0, ""}, - {"RTV_RTT", Const, 0, ""}, - {"RTV_RTTVAR", Const, 0, ""}, - {"RTV_SPIPE", Const, 0, ""}, - {"RTV_SSTHRESH", Const, 0, ""}, - {"RTV_WEIGHT", Const, 0, ""}, - {"RT_CACHING_CONTEXT", Const, 1, ""}, - {"RT_CLASS_DEFAULT", Const, 0, ""}, - {"RT_CLASS_LOCAL", Const, 0, ""}, - {"RT_CLASS_MAIN", Const, 0, ""}, - {"RT_CLASS_MAX", Const, 0, ""}, - {"RT_CLASS_UNSPEC", Const, 0, ""}, - {"RT_DEFAULT_FIB", Const, 1, ""}, - {"RT_NORTREF", Const, 1, ""}, - {"RT_SCOPE_HOST", Const, 0, ""}, - {"RT_SCOPE_LINK", Const, 0, ""}, - {"RT_SCOPE_NOWHERE", Const, 0, ""}, - {"RT_SCOPE_SITE", Const, 0, ""}, - {"RT_SCOPE_UNIVERSE", Const, 0, ""}, - {"RT_TABLEID_MAX", Const, 1, ""}, - {"RT_TABLE_COMPAT", Const, 0, ""}, - {"RT_TABLE_DEFAULT", Const, 0, ""}, - {"RT_TABLE_LOCAL", Const, 0, ""}, - {"RT_TABLE_MAIN", Const, 0, ""}, - {"RT_TABLE_MAX", Const, 0, ""}, - {"RT_TABLE_UNSPEC", Const, 0, ""}, - {"RUSAGE_CHILDREN", Const, 0, ""}, - {"RUSAGE_SELF", Const, 0, ""}, - {"RUSAGE_THREAD", Const, 0, ""}, - {"Radvisory_t", Type, 0, ""}, - {"Radvisory_t.Count", Field, 0, ""}, - {"Radvisory_t.Offset", Field, 0, ""}, - {"Radvisory_t.Pad_cgo_0", Field, 0, ""}, - {"RawConn", Type, 9, ""}, - {"RawSockaddr", Type, 0, ""}, - {"RawSockaddr.Data", Field, 0, ""}, - {"RawSockaddr.Family", Field, 0, ""}, - {"RawSockaddr.Len", Field, 0, ""}, - {"RawSockaddrAny", Type, 0, ""}, - {"RawSockaddrAny.Addr", Field, 0, ""}, - {"RawSockaddrAny.Pad", Field, 0, ""}, - {"RawSockaddrDatalink", Type, 0, ""}, - {"RawSockaddrDatalink.Alen", Field, 0, ""}, - {"RawSockaddrDatalink.Data", Field, 0, ""}, - {"RawSockaddrDatalink.Family", Field, 0, ""}, - {"RawSockaddrDatalink.Index", Field, 0, ""}, - {"RawSockaddrDatalink.Len", Field, 0, ""}, - {"RawSockaddrDatalink.Nlen", Field, 0, ""}, - {"RawSockaddrDatalink.Pad_cgo_0", Field, 2, ""}, - {"RawSockaddrDatalink.Slen", Field, 0, ""}, - {"RawSockaddrDatalink.Type", Field, 0, ""}, - {"RawSockaddrInet4", Type, 0, ""}, - {"RawSockaddrInet4.Addr", Field, 0, ""}, - {"RawSockaddrInet4.Family", Field, 0, ""}, - {"RawSockaddrInet4.Len", Field, 0, ""}, - {"RawSockaddrInet4.Port", Field, 0, ""}, - {"RawSockaddrInet4.Zero", Field, 0, ""}, - {"RawSockaddrInet6", Type, 0, ""}, - {"RawSockaddrInet6.Addr", Field, 0, ""}, - {"RawSockaddrInet6.Family", Field, 0, ""}, - {"RawSockaddrInet6.Flowinfo", Field, 0, ""}, - {"RawSockaddrInet6.Len", Field, 0, ""}, - {"RawSockaddrInet6.Port", Field, 0, ""}, - {"RawSockaddrInet6.Scope_id", Field, 0, ""}, - {"RawSockaddrLinklayer", Type, 0, ""}, - {"RawSockaddrLinklayer.Addr", Field, 0, ""}, - {"RawSockaddrLinklayer.Family", Field, 0, ""}, - {"RawSockaddrLinklayer.Halen", Field, 0, ""}, - {"RawSockaddrLinklayer.Hatype", Field, 0, ""}, - {"RawSockaddrLinklayer.Ifindex", Field, 0, ""}, - {"RawSockaddrLinklayer.Pkttype", Field, 0, ""}, - {"RawSockaddrLinklayer.Protocol", Field, 0, ""}, - {"RawSockaddrNetlink", Type, 0, ""}, - {"RawSockaddrNetlink.Family", Field, 0, ""}, - {"RawSockaddrNetlink.Groups", Field, 0, ""}, - {"RawSockaddrNetlink.Pad", Field, 0, ""}, - {"RawSockaddrNetlink.Pid", Field, 0, ""}, - {"RawSockaddrUnix", Type, 0, ""}, - {"RawSockaddrUnix.Family", Field, 0, ""}, - {"RawSockaddrUnix.Len", Field, 0, ""}, - {"RawSockaddrUnix.Pad_cgo_0", Field, 2, ""}, - {"RawSockaddrUnix.Path", Field, 0, ""}, - {"RawSyscall", Func, 0, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err Errno)"}, - {"RawSyscall6", Func, 0, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err Errno)"}, - {"Read", Func, 0, "func(fd int, p []byte) (n int, err error)"}, - {"ReadConsole", Func, 1, ""}, - {"ReadDirectoryChanges", Func, 0, ""}, - {"ReadDirent", Func, 0, "func(fd int, buf []byte) (n int, err error)"}, - {"ReadFile", Func, 0, ""}, - {"Readlink", Func, 0, "func(path string, buf []byte) (n int, err error)"}, - {"Reboot", Func, 0, "func(cmd int) (err error)"}, - {"Recvfrom", Func, 0, "func(fd int, p []byte, flags int) (n int, from Sockaddr, err error)"}, - {"Recvmsg", Func, 0, "func(fd int, p []byte, oob []byte, flags int) (n int, oobn int, recvflags int, from Sockaddr, err error)"}, - {"RegCloseKey", Func, 0, ""}, - {"RegEnumKeyEx", Func, 0, ""}, - {"RegOpenKeyEx", Func, 0, ""}, - {"RegQueryInfoKey", Func, 0, ""}, - {"RegQueryValueEx", Func, 0, ""}, - {"RemoveDirectory", Func, 0, ""}, - {"Removexattr", Func, 1, "func(path string, attr string) (err error)"}, - {"Rename", Func, 0, "func(oldpath string, newpath string) (err error)"}, - {"Renameat", Func, 0, "func(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)"}, - {"Revoke", Func, 0, ""}, - {"Rlimit", Type, 0, ""}, - {"Rlimit.Cur", Field, 0, ""}, - {"Rlimit.Max", Field, 0, ""}, - {"Rmdir", Func, 0, "func(path string) error"}, - {"RouteMessage", Type, 0, ""}, - {"RouteMessage.Data", Field, 0, ""}, - {"RouteMessage.Header", Field, 0, ""}, - {"RouteRIB", Func, 0, ""}, - {"RoutingMessage", Type, 14, ""}, - {"RtAttr", Type, 0, ""}, - {"RtAttr.Len", Field, 0, ""}, - {"RtAttr.Type", Field, 0, ""}, - {"RtGenmsg", Type, 0, ""}, - {"RtGenmsg.Family", Field, 0, ""}, - {"RtMetrics", Type, 0, ""}, - {"RtMetrics.Expire", Field, 0, ""}, - {"RtMetrics.Filler", Field, 0, ""}, - {"RtMetrics.Hopcount", Field, 0, ""}, - {"RtMetrics.Locks", Field, 0, ""}, - {"RtMetrics.Mtu", Field, 0, ""}, - {"RtMetrics.Pad", Field, 3, ""}, - {"RtMetrics.Pksent", Field, 0, ""}, - {"RtMetrics.Recvpipe", Field, 0, ""}, - {"RtMetrics.Refcnt", Field, 2, ""}, - {"RtMetrics.Rtt", Field, 0, ""}, - {"RtMetrics.Rttvar", Field, 0, ""}, - {"RtMetrics.Sendpipe", Field, 0, ""}, - {"RtMetrics.Ssthresh", Field, 0, ""}, - {"RtMetrics.Weight", Field, 0, ""}, - {"RtMsg", Type, 0, ""}, - {"RtMsg.Dst_len", Field, 0, ""}, - {"RtMsg.Family", Field, 0, ""}, - {"RtMsg.Flags", Field, 0, ""}, - {"RtMsg.Protocol", Field, 0, ""}, - {"RtMsg.Scope", Field, 0, ""}, - {"RtMsg.Src_len", Field, 0, ""}, - {"RtMsg.Table", Field, 0, ""}, - {"RtMsg.Tos", Field, 0, ""}, - {"RtMsg.Type", Field, 0, ""}, - {"RtMsghdr", Type, 0, ""}, - {"RtMsghdr.Addrs", Field, 0, ""}, - {"RtMsghdr.Errno", Field, 0, ""}, - {"RtMsghdr.Flags", Field, 0, ""}, - {"RtMsghdr.Fmask", Field, 0, ""}, - {"RtMsghdr.Hdrlen", Field, 2, ""}, - {"RtMsghdr.Index", Field, 0, ""}, - {"RtMsghdr.Inits", Field, 0, ""}, - {"RtMsghdr.Mpls", Field, 2, ""}, - {"RtMsghdr.Msglen", Field, 0, ""}, - {"RtMsghdr.Pad_cgo_0", Field, 0, ""}, - {"RtMsghdr.Pad_cgo_1", Field, 2, ""}, - {"RtMsghdr.Pid", Field, 0, ""}, - {"RtMsghdr.Priority", Field, 2, ""}, - {"RtMsghdr.Rmx", Field, 0, ""}, - {"RtMsghdr.Seq", Field, 0, ""}, - {"RtMsghdr.Tableid", Field, 2, ""}, - {"RtMsghdr.Type", Field, 0, ""}, - {"RtMsghdr.Use", Field, 0, ""}, - {"RtMsghdr.Version", Field, 0, ""}, - {"RtNexthop", Type, 0, ""}, - {"RtNexthop.Flags", Field, 0, ""}, - {"RtNexthop.Hops", Field, 0, ""}, - {"RtNexthop.Ifindex", Field, 0, ""}, - {"RtNexthop.Len", Field, 0, ""}, - {"Rusage", Type, 0, ""}, - {"Rusage.CreationTime", Field, 0, ""}, - {"Rusage.ExitTime", Field, 0, ""}, - {"Rusage.Idrss", Field, 0, ""}, - {"Rusage.Inblock", Field, 0, ""}, - {"Rusage.Isrss", Field, 0, ""}, - {"Rusage.Ixrss", Field, 0, ""}, - {"Rusage.KernelTime", Field, 0, ""}, - {"Rusage.Majflt", Field, 0, ""}, - {"Rusage.Maxrss", Field, 0, ""}, - {"Rusage.Minflt", Field, 0, ""}, - {"Rusage.Msgrcv", Field, 0, ""}, - {"Rusage.Msgsnd", Field, 0, ""}, - {"Rusage.Nivcsw", Field, 0, ""}, - {"Rusage.Nsignals", Field, 0, ""}, - {"Rusage.Nswap", Field, 0, ""}, - {"Rusage.Nvcsw", Field, 0, ""}, - {"Rusage.Oublock", Field, 0, ""}, - {"Rusage.Stime", Field, 0, ""}, - {"Rusage.UserTime", Field, 0, ""}, - {"Rusage.Utime", Field, 0, ""}, - {"SCM_BINTIME", Const, 0, ""}, - {"SCM_CREDENTIALS", Const, 0, ""}, - {"SCM_CREDS", Const, 0, ""}, - {"SCM_RIGHTS", Const, 0, ""}, - {"SCM_TIMESTAMP", Const, 0, ""}, - {"SCM_TIMESTAMPING", Const, 0, ""}, - {"SCM_TIMESTAMPNS", Const, 0, ""}, - {"SCM_TIMESTAMP_MONOTONIC", Const, 0, ""}, - {"SHUT_RD", Const, 0, ""}, - {"SHUT_RDWR", Const, 0, ""}, - {"SHUT_WR", Const, 0, ""}, - {"SID", Type, 0, ""}, - {"SIDAndAttributes", Type, 0, ""}, - {"SIDAndAttributes.Attributes", Field, 0, ""}, - {"SIDAndAttributes.Sid", Field, 0, ""}, - {"SIGABRT", Const, 0, ""}, - {"SIGALRM", Const, 0, ""}, - {"SIGBUS", Const, 0, ""}, - {"SIGCHLD", Const, 0, ""}, - {"SIGCLD", Const, 0, ""}, - {"SIGCONT", Const, 0, ""}, - {"SIGEMT", Const, 0, ""}, - {"SIGFPE", Const, 0, ""}, - {"SIGHUP", Const, 0, ""}, - {"SIGILL", Const, 0, ""}, - {"SIGINFO", Const, 0, ""}, - {"SIGINT", Const, 0, ""}, - {"SIGIO", Const, 0, ""}, - {"SIGIOT", Const, 0, ""}, - {"SIGKILL", Const, 0, ""}, - {"SIGLIBRT", Const, 1, ""}, - {"SIGLWP", Const, 0, ""}, - {"SIGPIPE", Const, 0, ""}, - {"SIGPOLL", Const, 0, ""}, - {"SIGPROF", Const, 0, ""}, - {"SIGPWR", Const, 0, ""}, - {"SIGQUIT", Const, 0, ""}, - {"SIGSEGV", Const, 0, ""}, - {"SIGSTKFLT", Const, 0, ""}, - {"SIGSTOP", Const, 0, ""}, - {"SIGSYS", Const, 0, ""}, - {"SIGTERM", Const, 0, ""}, - {"SIGTHR", Const, 0, ""}, - {"SIGTRAP", Const, 0, ""}, - {"SIGTSTP", Const, 0, ""}, - {"SIGTTIN", Const, 0, ""}, - {"SIGTTOU", Const, 0, ""}, - {"SIGUNUSED", Const, 0, ""}, - {"SIGURG", Const, 0, ""}, - {"SIGUSR1", Const, 0, ""}, - {"SIGUSR2", Const, 0, ""}, - {"SIGVTALRM", Const, 0, ""}, - {"SIGWINCH", Const, 0, ""}, - {"SIGXCPU", Const, 0, ""}, - {"SIGXFSZ", Const, 0, ""}, - {"SIOCADDDLCI", Const, 0, ""}, - {"SIOCADDMULTI", Const, 0, ""}, - {"SIOCADDRT", Const, 0, ""}, - {"SIOCAIFADDR", Const, 0, ""}, - {"SIOCAIFGROUP", Const, 0, ""}, - {"SIOCALIFADDR", Const, 0, ""}, - {"SIOCARPIPLL", Const, 0, ""}, - {"SIOCATMARK", Const, 0, ""}, - {"SIOCAUTOADDR", Const, 0, ""}, - {"SIOCAUTONETMASK", Const, 0, ""}, - {"SIOCBRDGADD", Const, 1, ""}, - {"SIOCBRDGADDS", Const, 1, ""}, - {"SIOCBRDGARL", Const, 1, ""}, - {"SIOCBRDGDADDR", Const, 1, ""}, - {"SIOCBRDGDEL", Const, 1, ""}, - {"SIOCBRDGDELS", Const, 1, ""}, - {"SIOCBRDGFLUSH", Const, 1, ""}, - {"SIOCBRDGFRL", Const, 1, ""}, - {"SIOCBRDGGCACHE", Const, 1, ""}, - {"SIOCBRDGGFD", Const, 1, ""}, - {"SIOCBRDGGHT", Const, 1, ""}, - {"SIOCBRDGGIFFLGS", Const, 1, ""}, - {"SIOCBRDGGMA", Const, 1, ""}, - {"SIOCBRDGGPARAM", Const, 1, ""}, - {"SIOCBRDGGPRI", Const, 1, ""}, - {"SIOCBRDGGRL", Const, 1, ""}, - {"SIOCBRDGGSIFS", Const, 1, ""}, - {"SIOCBRDGGTO", Const, 1, ""}, - {"SIOCBRDGIFS", Const, 1, ""}, - {"SIOCBRDGRTS", Const, 1, ""}, - {"SIOCBRDGSADDR", Const, 1, ""}, - {"SIOCBRDGSCACHE", Const, 1, ""}, - {"SIOCBRDGSFD", Const, 1, ""}, - {"SIOCBRDGSHT", Const, 1, ""}, - {"SIOCBRDGSIFCOST", Const, 1, ""}, - {"SIOCBRDGSIFFLGS", Const, 1, ""}, - {"SIOCBRDGSIFPRIO", Const, 1, ""}, - {"SIOCBRDGSMA", Const, 1, ""}, - {"SIOCBRDGSPRI", Const, 1, ""}, - {"SIOCBRDGSPROTO", Const, 1, ""}, - {"SIOCBRDGSTO", Const, 1, ""}, - {"SIOCBRDGSTXHC", Const, 1, ""}, - {"SIOCDARP", Const, 0, ""}, - {"SIOCDELDLCI", Const, 0, ""}, - {"SIOCDELMULTI", Const, 0, ""}, - {"SIOCDELRT", Const, 0, ""}, - {"SIOCDEVPRIVATE", Const, 0, ""}, - {"SIOCDIFADDR", Const, 0, ""}, - {"SIOCDIFGROUP", Const, 0, ""}, - {"SIOCDIFPHYADDR", Const, 0, ""}, - {"SIOCDLIFADDR", Const, 0, ""}, - {"SIOCDRARP", Const, 0, ""}, - {"SIOCGARP", Const, 0, ""}, - {"SIOCGDRVSPEC", Const, 0, ""}, - {"SIOCGETKALIVE", Const, 1, ""}, - {"SIOCGETLABEL", Const, 1, ""}, - {"SIOCGETPFLOW", Const, 1, ""}, - {"SIOCGETPFSYNC", Const, 1, ""}, - {"SIOCGETSGCNT", Const, 0, ""}, - {"SIOCGETVIFCNT", Const, 0, ""}, - {"SIOCGETVLAN", Const, 0, ""}, - {"SIOCGHIWAT", Const, 0, ""}, - {"SIOCGIFADDR", Const, 0, ""}, - {"SIOCGIFADDRPREF", Const, 1, ""}, - {"SIOCGIFALIAS", Const, 1, ""}, - {"SIOCGIFALTMTU", Const, 0, ""}, - {"SIOCGIFASYNCMAP", Const, 0, ""}, - {"SIOCGIFBOND", Const, 0, ""}, - {"SIOCGIFBR", Const, 0, ""}, - {"SIOCGIFBRDADDR", Const, 0, ""}, - {"SIOCGIFCAP", Const, 0, ""}, - {"SIOCGIFCONF", Const, 0, ""}, - {"SIOCGIFCOUNT", Const, 0, ""}, - {"SIOCGIFDATA", Const, 1, ""}, - {"SIOCGIFDESCR", Const, 0, ""}, - {"SIOCGIFDEVMTU", Const, 0, ""}, - {"SIOCGIFDLT", Const, 1, ""}, - {"SIOCGIFDSTADDR", Const, 0, ""}, - {"SIOCGIFENCAP", Const, 0, ""}, - {"SIOCGIFFIB", Const, 1, ""}, - {"SIOCGIFFLAGS", Const, 0, ""}, - {"SIOCGIFGATTR", Const, 1, ""}, - {"SIOCGIFGENERIC", Const, 0, ""}, - {"SIOCGIFGMEMB", Const, 0, ""}, - {"SIOCGIFGROUP", Const, 0, ""}, - {"SIOCGIFHARDMTU", Const, 3, ""}, - {"SIOCGIFHWADDR", Const, 0, ""}, - {"SIOCGIFINDEX", Const, 0, ""}, - {"SIOCGIFKPI", Const, 0, ""}, - {"SIOCGIFMAC", Const, 0, ""}, - {"SIOCGIFMAP", Const, 0, ""}, - {"SIOCGIFMEDIA", Const, 0, ""}, - {"SIOCGIFMEM", Const, 0, ""}, - {"SIOCGIFMETRIC", Const, 0, ""}, - {"SIOCGIFMTU", Const, 0, ""}, - {"SIOCGIFNAME", Const, 0, ""}, - {"SIOCGIFNETMASK", Const, 0, ""}, - {"SIOCGIFPDSTADDR", Const, 0, ""}, - {"SIOCGIFPFLAGS", Const, 0, ""}, - {"SIOCGIFPHYS", Const, 0, ""}, - {"SIOCGIFPRIORITY", Const, 1, ""}, - {"SIOCGIFPSRCADDR", Const, 0, ""}, - {"SIOCGIFRDOMAIN", Const, 1, ""}, - {"SIOCGIFRTLABEL", Const, 1, ""}, - {"SIOCGIFSLAVE", Const, 0, ""}, - {"SIOCGIFSTATUS", Const, 0, ""}, - {"SIOCGIFTIMESLOT", Const, 1, ""}, - {"SIOCGIFTXQLEN", Const, 0, ""}, - {"SIOCGIFVLAN", Const, 0, ""}, - {"SIOCGIFWAKEFLAGS", Const, 0, ""}, - {"SIOCGIFXFLAGS", Const, 1, ""}, - {"SIOCGLIFADDR", Const, 0, ""}, - {"SIOCGLIFPHYADDR", Const, 0, ""}, - {"SIOCGLIFPHYRTABLE", Const, 1, ""}, - {"SIOCGLIFPHYTTL", Const, 3, ""}, - {"SIOCGLINKSTR", Const, 1, ""}, - {"SIOCGLOWAT", Const, 0, ""}, - {"SIOCGPGRP", Const, 0, ""}, - {"SIOCGPRIVATE_0", Const, 0, ""}, - {"SIOCGPRIVATE_1", Const, 0, ""}, - {"SIOCGRARP", Const, 0, ""}, - {"SIOCGSPPPPARAMS", Const, 3, ""}, - {"SIOCGSTAMP", Const, 0, ""}, - {"SIOCGSTAMPNS", Const, 0, ""}, - {"SIOCGVH", Const, 1, ""}, - {"SIOCGVNETID", Const, 3, ""}, - {"SIOCIFCREATE", Const, 0, ""}, - {"SIOCIFCREATE2", Const, 0, ""}, - {"SIOCIFDESTROY", Const, 0, ""}, - {"SIOCIFGCLONERS", Const, 0, ""}, - {"SIOCINITIFADDR", Const, 1, ""}, - {"SIOCPROTOPRIVATE", Const, 0, ""}, - {"SIOCRSLVMULTI", Const, 0, ""}, - {"SIOCRTMSG", Const, 0, ""}, - {"SIOCSARP", Const, 0, ""}, - {"SIOCSDRVSPEC", Const, 0, ""}, - {"SIOCSETKALIVE", Const, 1, ""}, - {"SIOCSETLABEL", Const, 1, ""}, - {"SIOCSETPFLOW", Const, 1, ""}, - {"SIOCSETPFSYNC", Const, 1, ""}, - {"SIOCSETVLAN", Const, 0, ""}, - {"SIOCSHIWAT", Const, 0, ""}, - {"SIOCSIFADDR", Const, 0, ""}, - {"SIOCSIFADDRPREF", Const, 1, ""}, - {"SIOCSIFALTMTU", Const, 0, ""}, - {"SIOCSIFASYNCMAP", Const, 0, ""}, - {"SIOCSIFBOND", Const, 0, ""}, - {"SIOCSIFBR", Const, 0, ""}, - {"SIOCSIFBRDADDR", Const, 0, ""}, - {"SIOCSIFCAP", Const, 0, ""}, - {"SIOCSIFDESCR", Const, 0, ""}, - {"SIOCSIFDSTADDR", Const, 0, ""}, - {"SIOCSIFENCAP", Const, 0, ""}, - {"SIOCSIFFIB", Const, 1, ""}, - {"SIOCSIFFLAGS", Const, 0, ""}, - {"SIOCSIFGATTR", Const, 1, ""}, - {"SIOCSIFGENERIC", Const, 0, ""}, - {"SIOCSIFHWADDR", Const, 0, ""}, - {"SIOCSIFHWBROADCAST", Const, 0, ""}, - {"SIOCSIFKPI", Const, 0, ""}, - {"SIOCSIFLINK", Const, 0, ""}, - {"SIOCSIFLLADDR", Const, 0, ""}, - {"SIOCSIFMAC", Const, 0, ""}, - {"SIOCSIFMAP", Const, 0, ""}, - {"SIOCSIFMEDIA", Const, 0, ""}, - {"SIOCSIFMEM", Const, 0, ""}, - {"SIOCSIFMETRIC", Const, 0, ""}, - {"SIOCSIFMTU", Const, 0, ""}, - {"SIOCSIFNAME", Const, 0, ""}, - {"SIOCSIFNETMASK", Const, 0, ""}, - {"SIOCSIFPFLAGS", Const, 0, ""}, - {"SIOCSIFPHYADDR", Const, 0, ""}, - {"SIOCSIFPHYS", Const, 0, ""}, - {"SIOCSIFPRIORITY", Const, 1, ""}, - {"SIOCSIFRDOMAIN", Const, 1, ""}, - {"SIOCSIFRTLABEL", Const, 1, ""}, - {"SIOCSIFRVNET", Const, 0, ""}, - {"SIOCSIFSLAVE", Const, 0, ""}, - {"SIOCSIFTIMESLOT", Const, 1, ""}, - {"SIOCSIFTXQLEN", Const, 0, ""}, - {"SIOCSIFVLAN", Const, 0, ""}, - {"SIOCSIFVNET", Const, 0, ""}, - {"SIOCSIFXFLAGS", Const, 1, ""}, - {"SIOCSLIFPHYADDR", Const, 0, ""}, - {"SIOCSLIFPHYRTABLE", Const, 1, ""}, - {"SIOCSLIFPHYTTL", Const, 3, ""}, - {"SIOCSLINKSTR", Const, 1, ""}, - {"SIOCSLOWAT", Const, 0, ""}, - {"SIOCSPGRP", Const, 0, ""}, - {"SIOCSRARP", Const, 0, ""}, - {"SIOCSSPPPPARAMS", Const, 3, ""}, - {"SIOCSVH", Const, 1, ""}, - {"SIOCSVNETID", Const, 3, ""}, - {"SIOCZIFDATA", Const, 1, ""}, - {"SIO_GET_EXTENSION_FUNCTION_POINTER", Const, 1, ""}, - {"SIO_GET_INTERFACE_LIST", Const, 0, ""}, - {"SIO_KEEPALIVE_VALS", Const, 3, ""}, - {"SIO_UDP_CONNRESET", Const, 4, ""}, - {"SOCK_CLOEXEC", Const, 0, ""}, - {"SOCK_DCCP", Const, 0, ""}, - {"SOCK_DGRAM", Const, 0, ""}, - {"SOCK_FLAGS_MASK", Const, 1, ""}, - {"SOCK_MAXADDRLEN", Const, 0, ""}, - {"SOCK_NONBLOCK", Const, 0, ""}, - {"SOCK_NOSIGPIPE", Const, 1, ""}, - {"SOCK_PACKET", Const, 0, ""}, - {"SOCK_RAW", Const, 0, ""}, - {"SOCK_RDM", Const, 0, ""}, - {"SOCK_SEQPACKET", Const, 0, ""}, - {"SOCK_STREAM", Const, 0, ""}, - {"SOL_AAL", Const, 0, ""}, - {"SOL_ATM", Const, 0, ""}, - {"SOL_DECNET", Const, 0, ""}, - {"SOL_ICMPV6", Const, 0, ""}, - {"SOL_IP", Const, 0, ""}, - {"SOL_IPV6", Const, 0, ""}, - {"SOL_IRDA", Const, 0, ""}, - {"SOL_PACKET", Const, 0, ""}, - {"SOL_RAW", Const, 0, ""}, - {"SOL_SOCKET", Const, 0, ""}, - {"SOL_TCP", Const, 0, ""}, - {"SOL_X25", Const, 0, ""}, - {"SOMAXCONN", Const, 0, ""}, - {"SO_ACCEPTCONN", Const, 0, ""}, - {"SO_ACCEPTFILTER", Const, 0, ""}, - {"SO_ATTACH_FILTER", Const, 0, ""}, - {"SO_BINDANY", Const, 1, ""}, - {"SO_BINDTODEVICE", Const, 0, ""}, - {"SO_BINTIME", Const, 0, ""}, - {"SO_BROADCAST", Const, 0, ""}, - {"SO_BSDCOMPAT", Const, 0, ""}, - {"SO_DEBUG", Const, 0, ""}, - {"SO_DETACH_FILTER", Const, 0, ""}, - {"SO_DOMAIN", Const, 0, ""}, - {"SO_DONTROUTE", Const, 0, ""}, - {"SO_DONTTRUNC", Const, 0, ""}, - {"SO_ERROR", Const, 0, ""}, - {"SO_KEEPALIVE", Const, 0, ""}, - {"SO_LABEL", Const, 0, ""}, - {"SO_LINGER", Const, 0, ""}, - {"SO_LINGER_SEC", Const, 0, ""}, - {"SO_LISTENINCQLEN", Const, 0, ""}, - {"SO_LISTENQLEN", Const, 0, ""}, - {"SO_LISTENQLIMIT", Const, 0, ""}, - {"SO_MARK", Const, 0, ""}, - {"SO_NETPROC", Const, 1, ""}, - {"SO_NKE", Const, 0, ""}, - {"SO_NOADDRERR", Const, 0, ""}, - {"SO_NOHEADER", Const, 1, ""}, - {"SO_NOSIGPIPE", Const, 0, ""}, - {"SO_NOTIFYCONFLICT", Const, 0, ""}, - {"SO_NO_CHECK", Const, 0, ""}, - {"SO_NO_DDP", Const, 0, ""}, - {"SO_NO_OFFLOAD", Const, 0, ""}, - {"SO_NP_EXTENSIONS", Const, 0, ""}, - {"SO_NREAD", Const, 0, ""}, - {"SO_NUMRCVPKT", Const, 16, ""}, - {"SO_NWRITE", Const, 0, ""}, - {"SO_OOBINLINE", Const, 0, ""}, - {"SO_OVERFLOWED", Const, 1, ""}, - {"SO_PASSCRED", Const, 0, ""}, - {"SO_PASSSEC", Const, 0, ""}, - {"SO_PEERCRED", Const, 0, ""}, - {"SO_PEERLABEL", Const, 0, ""}, - {"SO_PEERNAME", Const, 0, ""}, - {"SO_PEERSEC", Const, 0, ""}, - {"SO_PRIORITY", Const, 0, ""}, - {"SO_PROTOCOL", Const, 0, ""}, - {"SO_PROTOTYPE", Const, 1, ""}, - {"SO_RANDOMPORT", Const, 0, ""}, - {"SO_RCVBUF", Const, 0, ""}, - {"SO_RCVBUFFORCE", Const, 0, ""}, - {"SO_RCVLOWAT", Const, 0, ""}, - {"SO_RCVTIMEO", Const, 0, ""}, - {"SO_RESTRICTIONS", Const, 0, ""}, - {"SO_RESTRICT_DENYIN", Const, 0, ""}, - {"SO_RESTRICT_DENYOUT", Const, 0, ""}, - {"SO_RESTRICT_DENYSET", Const, 0, ""}, - {"SO_REUSEADDR", Const, 0, ""}, - {"SO_REUSEPORT", Const, 0, ""}, - {"SO_REUSESHAREUID", Const, 0, ""}, - {"SO_RTABLE", Const, 1, ""}, - {"SO_RXQ_OVFL", Const, 0, ""}, - {"SO_SECURITY_AUTHENTICATION", Const, 0, ""}, - {"SO_SECURITY_ENCRYPTION_NETWORK", Const, 0, ""}, - {"SO_SECURITY_ENCRYPTION_TRANSPORT", Const, 0, ""}, - {"SO_SETFIB", Const, 0, ""}, - {"SO_SNDBUF", Const, 0, ""}, - {"SO_SNDBUFFORCE", Const, 0, ""}, - {"SO_SNDLOWAT", Const, 0, ""}, - {"SO_SNDTIMEO", Const, 0, ""}, - {"SO_SPLICE", Const, 1, ""}, - {"SO_TIMESTAMP", Const, 0, ""}, - {"SO_TIMESTAMPING", Const, 0, ""}, - {"SO_TIMESTAMPNS", Const, 0, ""}, - {"SO_TIMESTAMP_MONOTONIC", Const, 0, ""}, - {"SO_TYPE", Const, 0, ""}, - {"SO_UPCALLCLOSEWAIT", Const, 0, ""}, - {"SO_UPDATE_ACCEPT_CONTEXT", Const, 0, ""}, - {"SO_UPDATE_CONNECT_CONTEXT", Const, 1, ""}, - {"SO_USELOOPBACK", Const, 0, ""}, - {"SO_USER_COOKIE", Const, 1, ""}, - {"SO_VENDOR", Const, 3, ""}, - {"SO_WANTMORE", Const, 0, ""}, - {"SO_WANTOOBFLAG", Const, 0, ""}, - {"SSLExtraCertChainPolicyPara", Type, 0, ""}, - {"SSLExtraCertChainPolicyPara.AuthType", Field, 0, ""}, - {"SSLExtraCertChainPolicyPara.Checks", Field, 0, ""}, - {"SSLExtraCertChainPolicyPara.ServerName", Field, 0, ""}, - {"SSLExtraCertChainPolicyPara.Size", Field, 0, ""}, - {"STANDARD_RIGHTS_ALL", Const, 0, ""}, - {"STANDARD_RIGHTS_EXECUTE", Const, 0, ""}, - {"STANDARD_RIGHTS_READ", Const, 0, ""}, - {"STANDARD_RIGHTS_REQUIRED", Const, 0, ""}, - {"STANDARD_RIGHTS_WRITE", Const, 0, ""}, - {"STARTF_USESHOWWINDOW", Const, 0, ""}, - {"STARTF_USESTDHANDLES", Const, 0, ""}, - {"STD_ERROR_HANDLE", Const, 0, ""}, - {"STD_INPUT_HANDLE", Const, 0, ""}, - {"STD_OUTPUT_HANDLE", Const, 0, ""}, - {"SUBLANG_ENGLISH_US", Const, 0, ""}, - {"SW_FORCEMINIMIZE", Const, 0, ""}, - {"SW_HIDE", Const, 0, ""}, - {"SW_MAXIMIZE", Const, 0, ""}, - {"SW_MINIMIZE", Const, 0, ""}, - {"SW_NORMAL", Const, 0, ""}, - {"SW_RESTORE", Const, 0, ""}, - {"SW_SHOW", Const, 0, ""}, - {"SW_SHOWDEFAULT", Const, 0, ""}, - {"SW_SHOWMAXIMIZED", Const, 0, ""}, - {"SW_SHOWMINIMIZED", Const, 0, ""}, - {"SW_SHOWMINNOACTIVE", Const, 0, ""}, - {"SW_SHOWNA", Const, 0, ""}, - {"SW_SHOWNOACTIVATE", Const, 0, ""}, - {"SW_SHOWNORMAL", Const, 0, ""}, - {"SYMBOLIC_LINK_FLAG_DIRECTORY", Const, 4, ""}, - {"SYNCHRONIZE", Const, 0, ""}, - {"SYSCTL_VERSION", Const, 1, ""}, - {"SYSCTL_VERS_0", Const, 1, ""}, - {"SYSCTL_VERS_1", Const, 1, ""}, - {"SYSCTL_VERS_MASK", Const, 1, ""}, - {"SYS_ABORT2", Const, 0, ""}, - {"SYS_ACCEPT", Const, 0, ""}, - {"SYS_ACCEPT4", Const, 0, ""}, - {"SYS_ACCEPT_NOCANCEL", Const, 0, ""}, - {"SYS_ACCESS", Const, 0, ""}, - {"SYS_ACCESS_EXTENDED", Const, 0, ""}, - {"SYS_ACCT", Const, 0, ""}, - {"SYS_ADD_KEY", Const, 0, ""}, - {"SYS_ADD_PROFIL", Const, 0, ""}, - {"SYS_ADJFREQ", Const, 1, ""}, - {"SYS_ADJTIME", Const, 0, ""}, - {"SYS_ADJTIMEX", Const, 0, ""}, - {"SYS_AFS_SYSCALL", Const, 0, ""}, - {"SYS_AIO_CANCEL", Const, 0, ""}, - {"SYS_AIO_ERROR", Const, 0, ""}, - {"SYS_AIO_FSYNC", Const, 0, ""}, - {"SYS_AIO_MLOCK", Const, 14, ""}, - {"SYS_AIO_READ", Const, 0, ""}, - {"SYS_AIO_RETURN", Const, 0, ""}, - {"SYS_AIO_SUSPEND", Const, 0, ""}, - {"SYS_AIO_SUSPEND_NOCANCEL", Const, 0, ""}, - {"SYS_AIO_WAITCOMPLETE", Const, 14, ""}, - {"SYS_AIO_WRITE", Const, 0, ""}, - {"SYS_ALARM", Const, 0, ""}, - {"SYS_ARCH_PRCTL", Const, 0, ""}, - {"SYS_ARM_FADVISE64_64", Const, 0, ""}, - {"SYS_ARM_SYNC_FILE_RANGE", Const, 0, ""}, - {"SYS_ATGETMSG", Const, 0, ""}, - {"SYS_ATPGETREQ", Const, 0, ""}, - {"SYS_ATPGETRSP", Const, 0, ""}, - {"SYS_ATPSNDREQ", Const, 0, ""}, - {"SYS_ATPSNDRSP", Const, 0, ""}, - {"SYS_ATPUTMSG", Const, 0, ""}, - {"SYS_ATSOCKET", Const, 0, ""}, - {"SYS_AUDIT", Const, 0, ""}, - {"SYS_AUDITCTL", Const, 0, ""}, - {"SYS_AUDITON", Const, 0, ""}, - {"SYS_AUDIT_SESSION_JOIN", Const, 0, ""}, - {"SYS_AUDIT_SESSION_PORT", Const, 0, ""}, - {"SYS_AUDIT_SESSION_SELF", Const, 0, ""}, - {"SYS_BDFLUSH", Const, 0, ""}, - {"SYS_BIND", Const, 0, ""}, - {"SYS_BINDAT", Const, 3, ""}, - {"SYS_BREAK", Const, 0, ""}, - {"SYS_BRK", Const, 0, ""}, - {"SYS_BSDTHREAD_CREATE", Const, 0, ""}, - {"SYS_BSDTHREAD_REGISTER", Const, 0, ""}, - {"SYS_BSDTHREAD_TERMINATE", Const, 0, ""}, - {"SYS_CAPGET", Const, 0, ""}, - {"SYS_CAPSET", Const, 0, ""}, - {"SYS_CAP_ENTER", Const, 0, ""}, - {"SYS_CAP_FCNTLS_GET", Const, 1, ""}, - {"SYS_CAP_FCNTLS_LIMIT", Const, 1, ""}, - {"SYS_CAP_GETMODE", Const, 0, ""}, - {"SYS_CAP_GETRIGHTS", Const, 0, ""}, - {"SYS_CAP_IOCTLS_GET", Const, 1, ""}, - {"SYS_CAP_IOCTLS_LIMIT", Const, 1, ""}, - {"SYS_CAP_NEW", Const, 0, ""}, - {"SYS_CAP_RIGHTS_GET", Const, 1, ""}, - {"SYS_CAP_RIGHTS_LIMIT", Const, 1, ""}, - {"SYS_CHDIR", Const, 0, ""}, - {"SYS_CHFLAGS", Const, 0, ""}, - {"SYS_CHFLAGSAT", Const, 3, ""}, - {"SYS_CHMOD", Const, 0, ""}, - {"SYS_CHMOD_EXTENDED", Const, 0, ""}, - {"SYS_CHOWN", Const, 0, ""}, - {"SYS_CHOWN32", Const, 0, ""}, - {"SYS_CHROOT", Const, 0, ""}, - {"SYS_CHUD", Const, 0, ""}, - {"SYS_CLOCK_ADJTIME", Const, 0, ""}, - {"SYS_CLOCK_GETCPUCLOCKID2", Const, 1, ""}, - {"SYS_CLOCK_GETRES", Const, 0, ""}, - {"SYS_CLOCK_GETTIME", Const, 0, ""}, - {"SYS_CLOCK_NANOSLEEP", Const, 0, ""}, - {"SYS_CLOCK_SETTIME", Const, 0, ""}, - {"SYS_CLONE", Const, 0, ""}, - {"SYS_CLOSE", Const, 0, ""}, - {"SYS_CLOSEFROM", Const, 0, ""}, - {"SYS_CLOSE_NOCANCEL", Const, 0, ""}, - {"SYS_CONNECT", Const, 0, ""}, - {"SYS_CONNECTAT", Const, 3, ""}, - {"SYS_CONNECT_NOCANCEL", Const, 0, ""}, - {"SYS_COPYFILE", Const, 0, ""}, - {"SYS_CPUSET", Const, 0, ""}, - {"SYS_CPUSET_GETAFFINITY", Const, 0, ""}, - {"SYS_CPUSET_GETID", Const, 0, ""}, - {"SYS_CPUSET_SETAFFINITY", Const, 0, ""}, - {"SYS_CPUSET_SETID", Const, 0, ""}, - {"SYS_CREAT", Const, 0, ""}, - {"SYS_CREATE_MODULE", Const, 0, ""}, - {"SYS_CSOPS", Const, 0, ""}, - {"SYS_CSOPS_AUDITTOKEN", Const, 16, ""}, - {"SYS_DELETE", Const, 0, ""}, - {"SYS_DELETE_MODULE", Const, 0, ""}, - {"SYS_DUP", Const, 0, ""}, - {"SYS_DUP2", Const, 0, ""}, - {"SYS_DUP3", Const, 0, ""}, - {"SYS_EACCESS", Const, 0, ""}, - {"SYS_EPOLL_CREATE", Const, 0, ""}, - {"SYS_EPOLL_CREATE1", Const, 0, ""}, - {"SYS_EPOLL_CTL", Const, 0, ""}, - {"SYS_EPOLL_CTL_OLD", Const, 0, ""}, - {"SYS_EPOLL_PWAIT", Const, 0, ""}, - {"SYS_EPOLL_WAIT", Const, 0, ""}, - {"SYS_EPOLL_WAIT_OLD", Const, 0, ""}, - {"SYS_EVENTFD", Const, 0, ""}, - {"SYS_EVENTFD2", Const, 0, ""}, - {"SYS_EXCHANGEDATA", Const, 0, ""}, - {"SYS_EXECVE", Const, 0, ""}, - {"SYS_EXIT", Const, 0, ""}, - {"SYS_EXIT_GROUP", Const, 0, ""}, - {"SYS_EXTATTRCTL", Const, 0, ""}, - {"SYS_EXTATTR_DELETE_FD", Const, 0, ""}, - {"SYS_EXTATTR_DELETE_FILE", Const, 0, ""}, - {"SYS_EXTATTR_DELETE_LINK", Const, 0, ""}, - {"SYS_EXTATTR_GET_FD", Const, 0, ""}, - {"SYS_EXTATTR_GET_FILE", Const, 0, ""}, - {"SYS_EXTATTR_GET_LINK", Const, 0, ""}, - {"SYS_EXTATTR_LIST_FD", Const, 0, ""}, - {"SYS_EXTATTR_LIST_FILE", Const, 0, ""}, - {"SYS_EXTATTR_LIST_LINK", Const, 0, ""}, - {"SYS_EXTATTR_SET_FD", Const, 0, ""}, - {"SYS_EXTATTR_SET_FILE", Const, 0, ""}, - {"SYS_EXTATTR_SET_LINK", Const, 0, ""}, - {"SYS_FACCESSAT", Const, 0, ""}, - {"SYS_FADVISE64", Const, 0, ""}, - {"SYS_FADVISE64_64", Const, 0, ""}, - {"SYS_FALLOCATE", Const, 0, ""}, - {"SYS_FANOTIFY_INIT", Const, 0, ""}, - {"SYS_FANOTIFY_MARK", Const, 0, ""}, - {"SYS_FCHDIR", Const, 0, ""}, - {"SYS_FCHFLAGS", Const, 0, ""}, - {"SYS_FCHMOD", Const, 0, ""}, - {"SYS_FCHMODAT", Const, 0, ""}, - {"SYS_FCHMOD_EXTENDED", Const, 0, ""}, - {"SYS_FCHOWN", Const, 0, ""}, - {"SYS_FCHOWN32", Const, 0, ""}, - {"SYS_FCHOWNAT", Const, 0, ""}, - {"SYS_FCHROOT", Const, 1, ""}, - {"SYS_FCNTL", Const, 0, ""}, - {"SYS_FCNTL64", Const, 0, ""}, - {"SYS_FCNTL_NOCANCEL", Const, 0, ""}, - {"SYS_FDATASYNC", Const, 0, ""}, - {"SYS_FEXECVE", Const, 0, ""}, - {"SYS_FFCLOCK_GETCOUNTER", Const, 0, ""}, - {"SYS_FFCLOCK_GETESTIMATE", Const, 0, ""}, - {"SYS_FFCLOCK_SETESTIMATE", Const, 0, ""}, - {"SYS_FFSCTL", Const, 0, ""}, - {"SYS_FGETATTRLIST", Const, 0, ""}, - {"SYS_FGETXATTR", Const, 0, ""}, - {"SYS_FHOPEN", Const, 0, ""}, - {"SYS_FHSTAT", Const, 0, ""}, - {"SYS_FHSTATFS", Const, 0, ""}, - {"SYS_FILEPORT_MAKEFD", Const, 0, ""}, - {"SYS_FILEPORT_MAKEPORT", Const, 0, ""}, - {"SYS_FKTRACE", Const, 1, ""}, - {"SYS_FLISTXATTR", Const, 0, ""}, - {"SYS_FLOCK", Const, 0, ""}, - {"SYS_FORK", Const, 0, ""}, - {"SYS_FPATHCONF", Const, 0, ""}, - {"SYS_FREEBSD6_FTRUNCATE", Const, 0, ""}, - {"SYS_FREEBSD6_LSEEK", Const, 0, ""}, - {"SYS_FREEBSD6_MMAP", Const, 0, ""}, - {"SYS_FREEBSD6_PREAD", Const, 0, ""}, - {"SYS_FREEBSD6_PWRITE", Const, 0, ""}, - {"SYS_FREEBSD6_TRUNCATE", Const, 0, ""}, - {"SYS_FREMOVEXATTR", Const, 0, ""}, - {"SYS_FSCTL", Const, 0, ""}, - {"SYS_FSETATTRLIST", Const, 0, ""}, - {"SYS_FSETXATTR", Const, 0, ""}, - {"SYS_FSGETPATH", Const, 0, ""}, - {"SYS_FSTAT", Const, 0, ""}, - {"SYS_FSTAT64", Const, 0, ""}, - {"SYS_FSTAT64_EXTENDED", Const, 0, ""}, - {"SYS_FSTATAT", Const, 0, ""}, - {"SYS_FSTATAT64", Const, 0, ""}, - {"SYS_FSTATFS", Const, 0, ""}, - {"SYS_FSTATFS64", Const, 0, ""}, - {"SYS_FSTATV", Const, 0, ""}, - {"SYS_FSTATVFS1", Const, 1, ""}, - {"SYS_FSTAT_EXTENDED", Const, 0, ""}, - {"SYS_FSYNC", Const, 0, ""}, - {"SYS_FSYNC_NOCANCEL", Const, 0, ""}, - {"SYS_FSYNC_RANGE", Const, 1, ""}, - {"SYS_FTIME", Const, 0, ""}, - {"SYS_FTRUNCATE", Const, 0, ""}, - {"SYS_FTRUNCATE64", Const, 0, ""}, - {"SYS_FUTEX", Const, 0, ""}, - {"SYS_FUTIMENS", Const, 1, ""}, - {"SYS_FUTIMES", Const, 0, ""}, - {"SYS_FUTIMESAT", Const, 0, ""}, - {"SYS_GETATTRLIST", Const, 0, ""}, - {"SYS_GETAUDIT", Const, 0, ""}, - {"SYS_GETAUDIT_ADDR", Const, 0, ""}, - {"SYS_GETAUID", Const, 0, ""}, - {"SYS_GETCONTEXT", Const, 0, ""}, - {"SYS_GETCPU", Const, 0, ""}, - {"SYS_GETCWD", Const, 0, ""}, - {"SYS_GETDENTS", Const, 0, ""}, - {"SYS_GETDENTS64", Const, 0, ""}, - {"SYS_GETDIRENTRIES", Const, 0, ""}, - {"SYS_GETDIRENTRIES64", Const, 0, ""}, - {"SYS_GETDIRENTRIESATTR", Const, 0, ""}, - {"SYS_GETDTABLECOUNT", Const, 1, ""}, - {"SYS_GETDTABLESIZE", Const, 0, ""}, - {"SYS_GETEGID", Const, 0, ""}, - {"SYS_GETEGID32", Const, 0, ""}, - {"SYS_GETEUID", Const, 0, ""}, - {"SYS_GETEUID32", Const, 0, ""}, - {"SYS_GETFH", Const, 0, ""}, - {"SYS_GETFSSTAT", Const, 0, ""}, - {"SYS_GETFSSTAT64", Const, 0, ""}, - {"SYS_GETGID", Const, 0, ""}, - {"SYS_GETGID32", Const, 0, ""}, - {"SYS_GETGROUPS", Const, 0, ""}, - {"SYS_GETGROUPS32", Const, 0, ""}, - {"SYS_GETHOSTUUID", Const, 0, ""}, - {"SYS_GETITIMER", Const, 0, ""}, - {"SYS_GETLCID", Const, 0, ""}, - {"SYS_GETLOGIN", Const, 0, ""}, - {"SYS_GETLOGINCLASS", Const, 0, ""}, - {"SYS_GETPEERNAME", Const, 0, ""}, - {"SYS_GETPGID", Const, 0, ""}, - {"SYS_GETPGRP", Const, 0, ""}, - {"SYS_GETPID", Const, 0, ""}, - {"SYS_GETPMSG", Const, 0, ""}, - {"SYS_GETPPID", Const, 0, ""}, - {"SYS_GETPRIORITY", Const, 0, ""}, - {"SYS_GETRESGID", Const, 0, ""}, - {"SYS_GETRESGID32", Const, 0, ""}, - {"SYS_GETRESUID", Const, 0, ""}, - {"SYS_GETRESUID32", Const, 0, ""}, - {"SYS_GETRLIMIT", Const, 0, ""}, - {"SYS_GETRTABLE", Const, 1, ""}, - {"SYS_GETRUSAGE", Const, 0, ""}, - {"SYS_GETSGROUPS", Const, 0, ""}, - {"SYS_GETSID", Const, 0, ""}, - {"SYS_GETSOCKNAME", Const, 0, ""}, - {"SYS_GETSOCKOPT", Const, 0, ""}, - {"SYS_GETTHRID", Const, 1, ""}, - {"SYS_GETTID", Const, 0, ""}, - {"SYS_GETTIMEOFDAY", Const, 0, ""}, - {"SYS_GETUID", Const, 0, ""}, - {"SYS_GETUID32", Const, 0, ""}, - {"SYS_GETVFSSTAT", Const, 1, ""}, - {"SYS_GETWGROUPS", Const, 0, ""}, - {"SYS_GETXATTR", Const, 0, ""}, - {"SYS_GET_KERNEL_SYMS", Const, 0, ""}, - {"SYS_GET_MEMPOLICY", Const, 0, ""}, - {"SYS_GET_ROBUST_LIST", Const, 0, ""}, - {"SYS_GET_THREAD_AREA", Const, 0, ""}, - {"SYS_GSSD_SYSCALL", Const, 14, ""}, - {"SYS_GTTY", Const, 0, ""}, - {"SYS_IDENTITYSVC", Const, 0, ""}, - {"SYS_IDLE", Const, 0, ""}, - {"SYS_INITGROUPS", Const, 0, ""}, - {"SYS_INIT_MODULE", Const, 0, ""}, - {"SYS_INOTIFY_ADD_WATCH", Const, 0, ""}, - {"SYS_INOTIFY_INIT", Const, 0, ""}, - {"SYS_INOTIFY_INIT1", Const, 0, ""}, - {"SYS_INOTIFY_RM_WATCH", Const, 0, ""}, - {"SYS_IOCTL", Const, 0, ""}, - {"SYS_IOPERM", Const, 0, ""}, - {"SYS_IOPL", Const, 0, ""}, - {"SYS_IOPOLICYSYS", Const, 0, ""}, - {"SYS_IOPRIO_GET", Const, 0, ""}, - {"SYS_IOPRIO_SET", Const, 0, ""}, - {"SYS_IO_CANCEL", Const, 0, ""}, - {"SYS_IO_DESTROY", Const, 0, ""}, - {"SYS_IO_GETEVENTS", Const, 0, ""}, - {"SYS_IO_SETUP", Const, 0, ""}, - {"SYS_IO_SUBMIT", Const, 0, ""}, - {"SYS_IPC", Const, 0, ""}, - {"SYS_ISSETUGID", Const, 0, ""}, - {"SYS_JAIL", Const, 0, ""}, - {"SYS_JAIL_ATTACH", Const, 0, ""}, - {"SYS_JAIL_GET", Const, 0, ""}, - {"SYS_JAIL_REMOVE", Const, 0, ""}, - {"SYS_JAIL_SET", Const, 0, ""}, - {"SYS_KAS_INFO", Const, 16, ""}, - {"SYS_KDEBUG_TRACE", Const, 0, ""}, - {"SYS_KENV", Const, 0, ""}, - {"SYS_KEVENT", Const, 0, ""}, - {"SYS_KEVENT64", Const, 0, ""}, - {"SYS_KEXEC_LOAD", Const, 0, ""}, - {"SYS_KEYCTL", Const, 0, ""}, - {"SYS_KILL", Const, 0, ""}, - {"SYS_KLDFIND", Const, 0, ""}, - {"SYS_KLDFIRSTMOD", Const, 0, ""}, - {"SYS_KLDLOAD", Const, 0, ""}, - {"SYS_KLDNEXT", Const, 0, ""}, - {"SYS_KLDSTAT", Const, 0, ""}, - {"SYS_KLDSYM", Const, 0, ""}, - {"SYS_KLDUNLOAD", Const, 0, ""}, - {"SYS_KLDUNLOADF", Const, 0, ""}, - {"SYS_KMQ_NOTIFY", Const, 14, ""}, - {"SYS_KMQ_OPEN", Const, 14, ""}, - {"SYS_KMQ_SETATTR", Const, 14, ""}, - {"SYS_KMQ_TIMEDRECEIVE", Const, 14, ""}, - {"SYS_KMQ_TIMEDSEND", Const, 14, ""}, - {"SYS_KMQ_UNLINK", Const, 14, ""}, - {"SYS_KQUEUE", Const, 0, ""}, - {"SYS_KQUEUE1", Const, 1, ""}, - {"SYS_KSEM_CLOSE", Const, 14, ""}, - {"SYS_KSEM_DESTROY", Const, 14, ""}, - {"SYS_KSEM_GETVALUE", Const, 14, ""}, - {"SYS_KSEM_INIT", Const, 14, ""}, - {"SYS_KSEM_OPEN", Const, 14, ""}, - {"SYS_KSEM_POST", Const, 14, ""}, - {"SYS_KSEM_TIMEDWAIT", Const, 14, ""}, - {"SYS_KSEM_TRYWAIT", Const, 14, ""}, - {"SYS_KSEM_UNLINK", Const, 14, ""}, - {"SYS_KSEM_WAIT", Const, 14, ""}, - {"SYS_KTIMER_CREATE", Const, 0, ""}, - {"SYS_KTIMER_DELETE", Const, 0, ""}, - {"SYS_KTIMER_GETOVERRUN", Const, 0, ""}, - {"SYS_KTIMER_GETTIME", Const, 0, ""}, - {"SYS_KTIMER_SETTIME", Const, 0, ""}, - {"SYS_KTRACE", Const, 0, ""}, - {"SYS_LCHFLAGS", Const, 0, ""}, - {"SYS_LCHMOD", Const, 0, ""}, - {"SYS_LCHOWN", Const, 0, ""}, - {"SYS_LCHOWN32", Const, 0, ""}, - {"SYS_LEDGER", Const, 16, ""}, - {"SYS_LGETFH", Const, 0, ""}, - {"SYS_LGETXATTR", Const, 0, ""}, - {"SYS_LINK", Const, 0, ""}, - {"SYS_LINKAT", Const, 0, ""}, - {"SYS_LIO_LISTIO", Const, 0, ""}, - {"SYS_LISTEN", Const, 0, ""}, - {"SYS_LISTXATTR", Const, 0, ""}, - {"SYS_LLISTXATTR", Const, 0, ""}, - {"SYS_LOCK", Const, 0, ""}, - {"SYS_LOOKUP_DCOOKIE", Const, 0, ""}, - {"SYS_LPATHCONF", Const, 0, ""}, - {"SYS_LREMOVEXATTR", Const, 0, ""}, - {"SYS_LSEEK", Const, 0, ""}, - {"SYS_LSETXATTR", Const, 0, ""}, - {"SYS_LSTAT", Const, 0, ""}, - {"SYS_LSTAT64", Const, 0, ""}, - {"SYS_LSTAT64_EXTENDED", Const, 0, ""}, - {"SYS_LSTATV", Const, 0, ""}, - {"SYS_LSTAT_EXTENDED", Const, 0, ""}, - {"SYS_LUTIMES", Const, 0, ""}, - {"SYS_MAC_SYSCALL", Const, 0, ""}, - {"SYS_MADVISE", Const, 0, ""}, - {"SYS_MADVISE1", Const, 0, ""}, - {"SYS_MAXSYSCALL", Const, 0, ""}, - {"SYS_MBIND", Const, 0, ""}, - {"SYS_MIGRATE_PAGES", Const, 0, ""}, - {"SYS_MINCORE", Const, 0, ""}, - {"SYS_MINHERIT", Const, 0, ""}, - {"SYS_MKCOMPLEX", Const, 0, ""}, - {"SYS_MKDIR", Const, 0, ""}, - {"SYS_MKDIRAT", Const, 0, ""}, - {"SYS_MKDIR_EXTENDED", Const, 0, ""}, - {"SYS_MKFIFO", Const, 0, ""}, - {"SYS_MKFIFOAT", Const, 0, ""}, - {"SYS_MKFIFO_EXTENDED", Const, 0, ""}, - {"SYS_MKNOD", Const, 0, ""}, - {"SYS_MKNODAT", Const, 0, ""}, - {"SYS_MLOCK", Const, 0, ""}, - {"SYS_MLOCKALL", Const, 0, ""}, - {"SYS_MMAP", Const, 0, ""}, - {"SYS_MMAP2", Const, 0, ""}, - {"SYS_MODCTL", Const, 1, ""}, - {"SYS_MODFIND", Const, 0, ""}, - {"SYS_MODFNEXT", Const, 0, ""}, - {"SYS_MODIFY_LDT", Const, 0, ""}, - {"SYS_MODNEXT", Const, 0, ""}, - {"SYS_MODSTAT", Const, 0, ""}, - {"SYS_MODWATCH", Const, 0, ""}, - {"SYS_MOUNT", Const, 0, ""}, - {"SYS_MOVE_PAGES", Const, 0, ""}, - {"SYS_MPROTECT", Const, 0, ""}, - {"SYS_MPX", Const, 0, ""}, - {"SYS_MQUERY", Const, 1, ""}, - {"SYS_MQ_GETSETATTR", Const, 0, ""}, - {"SYS_MQ_NOTIFY", Const, 0, ""}, - {"SYS_MQ_OPEN", Const, 0, ""}, - {"SYS_MQ_TIMEDRECEIVE", Const, 0, ""}, - {"SYS_MQ_TIMEDSEND", Const, 0, ""}, - {"SYS_MQ_UNLINK", Const, 0, ""}, - {"SYS_MREMAP", Const, 0, ""}, - {"SYS_MSGCTL", Const, 0, ""}, - {"SYS_MSGGET", Const, 0, ""}, - {"SYS_MSGRCV", Const, 0, ""}, - {"SYS_MSGRCV_NOCANCEL", Const, 0, ""}, - {"SYS_MSGSND", Const, 0, ""}, - {"SYS_MSGSND_NOCANCEL", Const, 0, ""}, - {"SYS_MSGSYS", Const, 0, ""}, - {"SYS_MSYNC", Const, 0, ""}, - {"SYS_MSYNC_NOCANCEL", Const, 0, ""}, - {"SYS_MUNLOCK", Const, 0, ""}, - {"SYS_MUNLOCKALL", Const, 0, ""}, - {"SYS_MUNMAP", Const, 0, ""}, - {"SYS_NAME_TO_HANDLE_AT", Const, 0, ""}, - {"SYS_NANOSLEEP", Const, 0, ""}, - {"SYS_NEWFSTATAT", Const, 0, ""}, - {"SYS_NFSCLNT", Const, 0, ""}, - {"SYS_NFSSERVCTL", Const, 0, ""}, - {"SYS_NFSSVC", Const, 0, ""}, - {"SYS_NFSTAT", Const, 0, ""}, - {"SYS_NICE", Const, 0, ""}, - {"SYS_NLM_SYSCALL", Const, 14, ""}, - {"SYS_NLSTAT", Const, 0, ""}, - {"SYS_NMOUNT", Const, 0, ""}, - {"SYS_NSTAT", Const, 0, ""}, - {"SYS_NTP_ADJTIME", Const, 0, ""}, - {"SYS_NTP_GETTIME", Const, 0, ""}, - {"SYS_NUMA_GETAFFINITY", Const, 14, ""}, - {"SYS_NUMA_SETAFFINITY", Const, 14, ""}, - {"SYS_OABI_SYSCALL_BASE", Const, 0, ""}, - {"SYS_OBREAK", Const, 0, ""}, - {"SYS_OLDFSTAT", Const, 0, ""}, - {"SYS_OLDLSTAT", Const, 0, ""}, - {"SYS_OLDOLDUNAME", Const, 0, ""}, - {"SYS_OLDSTAT", Const, 0, ""}, - {"SYS_OLDUNAME", Const, 0, ""}, - {"SYS_OPEN", Const, 0, ""}, - {"SYS_OPENAT", Const, 0, ""}, - {"SYS_OPENBSD_POLL", Const, 0, ""}, - {"SYS_OPEN_BY_HANDLE_AT", Const, 0, ""}, - {"SYS_OPEN_DPROTECTED_NP", Const, 16, ""}, - {"SYS_OPEN_EXTENDED", Const, 0, ""}, - {"SYS_OPEN_NOCANCEL", Const, 0, ""}, - {"SYS_OVADVISE", Const, 0, ""}, - {"SYS_PACCEPT", Const, 1, ""}, - {"SYS_PATHCONF", Const, 0, ""}, - {"SYS_PAUSE", Const, 0, ""}, - {"SYS_PCICONFIG_IOBASE", Const, 0, ""}, - {"SYS_PCICONFIG_READ", Const, 0, ""}, - {"SYS_PCICONFIG_WRITE", Const, 0, ""}, - {"SYS_PDFORK", Const, 0, ""}, - {"SYS_PDGETPID", Const, 0, ""}, - {"SYS_PDKILL", Const, 0, ""}, - {"SYS_PERF_EVENT_OPEN", Const, 0, ""}, - {"SYS_PERSONALITY", Const, 0, ""}, - {"SYS_PID_HIBERNATE", Const, 0, ""}, - {"SYS_PID_RESUME", Const, 0, ""}, - {"SYS_PID_SHUTDOWN_SOCKETS", Const, 0, ""}, - {"SYS_PID_SUSPEND", Const, 0, ""}, - {"SYS_PIPE", Const, 0, ""}, - {"SYS_PIPE2", Const, 0, ""}, - {"SYS_PIVOT_ROOT", Const, 0, ""}, - {"SYS_PMC_CONTROL", Const, 1, ""}, - {"SYS_PMC_GET_INFO", Const, 1, ""}, - {"SYS_POLL", Const, 0, ""}, - {"SYS_POLLTS", Const, 1, ""}, - {"SYS_POLL_NOCANCEL", Const, 0, ""}, - {"SYS_POSIX_FADVISE", Const, 0, ""}, - {"SYS_POSIX_FALLOCATE", Const, 0, ""}, - {"SYS_POSIX_OPENPT", Const, 0, ""}, - {"SYS_POSIX_SPAWN", Const, 0, ""}, - {"SYS_PPOLL", Const, 0, ""}, - {"SYS_PRCTL", Const, 0, ""}, - {"SYS_PREAD", Const, 0, ""}, - {"SYS_PREAD64", Const, 0, ""}, - {"SYS_PREADV", Const, 0, ""}, - {"SYS_PREAD_NOCANCEL", Const, 0, ""}, - {"SYS_PRLIMIT64", Const, 0, ""}, - {"SYS_PROCCTL", Const, 3, ""}, - {"SYS_PROCESS_POLICY", Const, 0, ""}, - {"SYS_PROCESS_VM_READV", Const, 0, ""}, - {"SYS_PROCESS_VM_WRITEV", Const, 0, ""}, - {"SYS_PROC_INFO", Const, 0, ""}, - {"SYS_PROF", Const, 0, ""}, - {"SYS_PROFIL", Const, 0, ""}, - {"SYS_PSELECT", Const, 0, ""}, - {"SYS_PSELECT6", Const, 0, ""}, - {"SYS_PSET_ASSIGN", Const, 1, ""}, - {"SYS_PSET_CREATE", Const, 1, ""}, - {"SYS_PSET_DESTROY", Const, 1, ""}, - {"SYS_PSYNCH_CVBROAD", Const, 0, ""}, - {"SYS_PSYNCH_CVCLRPREPOST", Const, 0, ""}, - {"SYS_PSYNCH_CVSIGNAL", Const, 0, ""}, - {"SYS_PSYNCH_CVWAIT", Const, 0, ""}, - {"SYS_PSYNCH_MUTEXDROP", Const, 0, ""}, - {"SYS_PSYNCH_MUTEXWAIT", Const, 0, ""}, - {"SYS_PSYNCH_RW_DOWNGRADE", Const, 0, ""}, - {"SYS_PSYNCH_RW_LONGRDLOCK", Const, 0, ""}, - {"SYS_PSYNCH_RW_RDLOCK", Const, 0, ""}, - {"SYS_PSYNCH_RW_UNLOCK", Const, 0, ""}, - {"SYS_PSYNCH_RW_UNLOCK2", Const, 0, ""}, - {"SYS_PSYNCH_RW_UPGRADE", Const, 0, ""}, - {"SYS_PSYNCH_RW_WRLOCK", Const, 0, ""}, - {"SYS_PSYNCH_RW_YIELDWRLOCK", Const, 0, ""}, - {"SYS_PTRACE", Const, 0, ""}, - {"SYS_PUTPMSG", Const, 0, ""}, - {"SYS_PWRITE", Const, 0, ""}, - {"SYS_PWRITE64", Const, 0, ""}, - {"SYS_PWRITEV", Const, 0, ""}, - {"SYS_PWRITE_NOCANCEL", Const, 0, ""}, - {"SYS_QUERY_MODULE", Const, 0, ""}, - {"SYS_QUOTACTL", Const, 0, ""}, - {"SYS_RASCTL", Const, 1, ""}, - {"SYS_RCTL_ADD_RULE", Const, 0, ""}, - {"SYS_RCTL_GET_LIMITS", Const, 0, ""}, - {"SYS_RCTL_GET_RACCT", Const, 0, ""}, - {"SYS_RCTL_GET_RULES", Const, 0, ""}, - {"SYS_RCTL_REMOVE_RULE", Const, 0, ""}, - {"SYS_READ", Const, 0, ""}, - {"SYS_READAHEAD", Const, 0, ""}, - {"SYS_READDIR", Const, 0, ""}, - {"SYS_READLINK", Const, 0, ""}, - {"SYS_READLINKAT", Const, 0, ""}, - {"SYS_READV", Const, 0, ""}, - {"SYS_READV_NOCANCEL", Const, 0, ""}, - {"SYS_READ_NOCANCEL", Const, 0, ""}, - {"SYS_REBOOT", Const, 0, ""}, - {"SYS_RECV", Const, 0, ""}, - {"SYS_RECVFROM", Const, 0, ""}, - {"SYS_RECVFROM_NOCANCEL", Const, 0, ""}, - {"SYS_RECVMMSG", Const, 0, ""}, - {"SYS_RECVMSG", Const, 0, ""}, - {"SYS_RECVMSG_NOCANCEL", Const, 0, ""}, - {"SYS_REMAP_FILE_PAGES", Const, 0, ""}, - {"SYS_REMOVEXATTR", Const, 0, ""}, - {"SYS_RENAME", Const, 0, ""}, - {"SYS_RENAMEAT", Const, 0, ""}, - {"SYS_REQUEST_KEY", Const, 0, ""}, - {"SYS_RESTART_SYSCALL", Const, 0, ""}, - {"SYS_REVOKE", Const, 0, ""}, - {"SYS_RFORK", Const, 0, ""}, - {"SYS_RMDIR", Const, 0, ""}, - {"SYS_RTPRIO", Const, 0, ""}, - {"SYS_RTPRIO_THREAD", Const, 0, ""}, - {"SYS_RT_SIGACTION", Const, 0, ""}, - {"SYS_RT_SIGPENDING", Const, 0, ""}, - {"SYS_RT_SIGPROCMASK", Const, 0, ""}, - {"SYS_RT_SIGQUEUEINFO", Const, 0, ""}, - {"SYS_RT_SIGRETURN", Const, 0, ""}, - {"SYS_RT_SIGSUSPEND", Const, 0, ""}, - {"SYS_RT_SIGTIMEDWAIT", Const, 0, ""}, - {"SYS_RT_TGSIGQUEUEINFO", Const, 0, ""}, - {"SYS_SBRK", Const, 0, ""}, - {"SYS_SCHED_GETAFFINITY", Const, 0, ""}, - {"SYS_SCHED_GETPARAM", Const, 0, ""}, - {"SYS_SCHED_GETSCHEDULER", Const, 0, ""}, - {"SYS_SCHED_GET_PRIORITY_MAX", Const, 0, ""}, - {"SYS_SCHED_GET_PRIORITY_MIN", Const, 0, ""}, - {"SYS_SCHED_RR_GET_INTERVAL", Const, 0, ""}, - {"SYS_SCHED_SETAFFINITY", Const, 0, ""}, - {"SYS_SCHED_SETPARAM", Const, 0, ""}, - {"SYS_SCHED_SETSCHEDULER", Const, 0, ""}, - {"SYS_SCHED_YIELD", Const, 0, ""}, - {"SYS_SCTP_GENERIC_RECVMSG", Const, 0, ""}, - {"SYS_SCTP_GENERIC_SENDMSG", Const, 0, ""}, - {"SYS_SCTP_GENERIC_SENDMSG_IOV", Const, 0, ""}, - {"SYS_SCTP_PEELOFF", Const, 0, ""}, - {"SYS_SEARCHFS", Const, 0, ""}, - {"SYS_SECURITY", Const, 0, ""}, - {"SYS_SELECT", Const, 0, ""}, - {"SYS_SELECT_NOCANCEL", Const, 0, ""}, - {"SYS_SEMCONFIG", Const, 1, ""}, - {"SYS_SEMCTL", Const, 0, ""}, - {"SYS_SEMGET", Const, 0, ""}, - {"SYS_SEMOP", Const, 0, ""}, - {"SYS_SEMSYS", Const, 0, ""}, - {"SYS_SEMTIMEDOP", Const, 0, ""}, - {"SYS_SEM_CLOSE", Const, 0, ""}, - {"SYS_SEM_DESTROY", Const, 0, ""}, - {"SYS_SEM_GETVALUE", Const, 0, ""}, - {"SYS_SEM_INIT", Const, 0, ""}, - {"SYS_SEM_OPEN", Const, 0, ""}, - {"SYS_SEM_POST", Const, 0, ""}, - {"SYS_SEM_TRYWAIT", Const, 0, ""}, - {"SYS_SEM_UNLINK", Const, 0, ""}, - {"SYS_SEM_WAIT", Const, 0, ""}, - {"SYS_SEM_WAIT_NOCANCEL", Const, 0, ""}, - {"SYS_SEND", Const, 0, ""}, - {"SYS_SENDFILE", Const, 0, ""}, - {"SYS_SENDFILE64", Const, 0, ""}, - {"SYS_SENDMMSG", Const, 0, ""}, - {"SYS_SENDMSG", Const, 0, ""}, - {"SYS_SENDMSG_NOCANCEL", Const, 0, ""}, - {"SYS_SENDTO", Const, 0, ""}, - {"SYS_SENDTO_NOCANCEL", Const, 0, ""}, - {"SYS_SETATTRLIST", Const, 0, ""}, - {"SYS_SETAUDIT", Const, 0, ""}, - {"SYS_SETAUDIT_ADDR", Const, 0, ""}, - {"SYS_SETAUID", Const, 0, ""}, - {"SYS_SETCONTEXT", Const, 0, ""}, - {"SYS_SETDOMAINNAME", Const, 0, ""}, - {"SYS_SETEGID", Const, 0, ""}, - {"SYS_SETEUID", Const, 0, ""}, - {"SYS_SETFIB", Const, 0, ""}, - {"SYS_SETFSGID", Const, 0, ""}, - {"SYS_SETFSGID32", Const, 0, ""}, - {"SYS_SETFSUID", Const, 0, ""}, - {"SYS_SETFSUID32", Const, 0, ""}, - {"SYS_SETGID", Const, 0, ""}, - {"SYS_SETGID32", Const, 0, ""}, - {"SYS_SETGROUPS", Const, 0, ""}, - {"SYS_SETGROUPS32", Const, 0, ""}, - {"SYS_SETHOSTNAME", Const, 0, ""}, - {"SYS_SETITIMER", Const, 0, ""}, - {"SYS_SETLCID", Const, 0, ""}, - {"SYS_SETLOGIN", Const, 0, ""}, - {"SYS_SETLOGINCLASS", Const, 0, ""}, - {"SYS_SETNS", Const, 0, ""}, - {"SYS_SETPGID", Const, 0, ""}, - {"SYS_SETPRIORITY", Const, 0, ""}, - {"SYS_SETPRIVEXEC", Const, 0, ""}, - {"SYS_SETREGID", Const, 0, ""}, - {"SYS_SETREGID32", Const, 0, ""}, - {"SYS_SETRESGID", Const, 0, ""}, - {"SYS_SETRESGID32", Const, 0, ""}, - {"SYS_SETRESUID", Const, 0, ""}, - {"SYS_SETRESUID32", Const, 0, ""}, - {"SYS_SETREUID", Const, 0, ""}, - {"SYS_SETREUID32", Const, 0, ""}, - {"SYS_SETRLIMIT", Const, 0, ""}, - {"SYS_SETRTABLE", Const, 1, ""}, - {"SYS_SETSGROUPS", Const, 0, ""}, - {"SYS_SETSID", Const, 0, ""}, - {"SYS_SETSOCKOPT", Const, 0, ""}, - {"SYS_SETTID", Const, 0, ""}, - {"SYS_SETTID_WITH_PID", Const, 0, ""}, - {"SYS_SETTIMEOFDAY", Const, 0, ""}, - {"SYS_SETUID", Const, 0, ""}, - {"SYS_SETUID32", Const, 0, ""}, - {"SYS_SETWGROUPS", Const, 0, ""}, - {"SYS_SETXATTR", Const, 0, ""}, - {"SYS_SET_MEMPOLICY", Const, 0, ""}, - {"SYS_SET_ROBUST_LIST", Const, 0, ""}, - {"SYS_SET_THREAD_AREA", Const, 0, ""}, - {"SYS_SET_TID_ADDRESS", Const, 0, ""}, - {"SYS_SGETMASK", Const, 0, ""}, - {"SYS_SHARED_REGION_CHECK_NP", Const, 0, ""}, - {"SYS_SHARED_REGION_MAP_AND_SLIDE_NP", Const, 0, ""}, - {"SYS_SHMAT", Const, 0, ""}, - {"SYS_SHMCTL", Const, 0, ""}, - {"SYS_SHMDT", Const, 0, ""}, - {"SYS_SHMGET", Const, 0, ""}, - {"SYS_SHMSYS", Const, 0, ""}, - {"SYS_SHM_OPEN", Const, 0, ""}, - {"SYS_SHM_UNLINK", Const, 0, ""}, - {"SYS_SHUTDOWN", Const, 0, ""}, - {"SYS_SIGACTION", Const, 0, ""}, - {"SYS_SIGALTSTACK", Const, 0, ""}, - {"SYS_SIGNAL", Const, 0, ""}, - {"SYS_SIGNALFD", Const, 0, ""}, - {"SYS_SIGNALFD4", Const, 0, ""}, - {"SYS_SIGPENDING", Const, 0, ""}, - {"SYS_SIGPROCMASK", Const, 0, ""}, - {"SYS_SIGQUEUE", Const, 0, ""}, - {"SYS_SIGQUEUEINFO", Const, 1, ""}, - {"SYS_SIGRETURN", Const, 0, ""}, - {"SYS_SIGSUSPEND", Const, 0, ""}, - {"SYS_SIGSUSPEND_NOCANCEL", Const, 0, ""}, - {"SYS_SIGTIMEDWAIT", Const, 0, ""}, - {"SYS_SIGWAIT", Const, 0, ""}, - {"SYS_SIGWAITINFO", Const, 0, ""}, - {"SYS_SOCKET", Const, 0, ""}, - {"SYS_SOCKETCALL", Const, 0, ""}, - {"SYS_SOCKETPAIR", Const, 0, ""}, - {"SYS_SPLICE", Const, 0, ""}, - {"SYS_SSETMASK", Const, 0, ""}, - {"SYS_SSTK", Const, 0, ""}, - {"SYS_STACK_SNAPSHOT", Const, 0, ""}, - {"SYS_STAT", Const, 0, ""}, - {"SYS_STAT64", Const, 0, ""}, - {"SYS_STAT64_EXTENDED", Const, 0, ""}, - {"SYS_STATFS", Const, 0, ""}, - {"SYS_STATFS64", Const, 0, ""}, - {"SYS_STATV", Const, 0, ""}, - {"SYS_STATVFS1", Const, 1, ""}, - {"SYS_STAT_EXTENDED", Const, 0, ""}, - {"SYS_STIME", Const, 0, ""}, - {"SYS_STTY", Const, 0, ""}, - {"SYS_SWAPCONTEXT", Const, 0, ""}, - {"SYS_SWAPCTL", Const, 1, ""}, - {"SYS_SWAPOFF", Const, 0, ""}, - {"SYS_SWAPON", Const, 0, ""}, - {"SYS_SYMLINK", Const, 0, ""}, - {"SYS_SYMLINKAT", Const, 0, ""}, - {"SYS_SYNC", Const, 0, ""}, - {"SYS_SYNCFS", Const, 0, ""}, - {"SYS_SYNC_FILE_RANGE", Const, 0, ""}, - {"SYS_SYSARCH", Const, 0, ""}, - {"SYS_SYSCALL", Const, 0, ""}, - {"SYS_SYSCALL_BASE", Const, 0, ""}, - {"SYS_SYSFS", Const, 0, ""}, - {"SYS_SYSINFO", Const, 0, ""}, - {"SYS_SYSLOG", Const, 0, ""}, - {"SYS_TEE", Const, 0, ""}, - {"SYS_TGKILL", Const, 0, ""}, - {"SYS_THREAD_SELFID", Const, 0, ""}, - {"SYS_THR_CREATE", Const, 0, ""}, - {"SYS_THR_EXIT", Const, 0, ""}, - {"SYS_THR_KILL", Const, 0, ""}, - {"SYS_THR_KILL2", Const, 0, ""}, - {"SYS_THR_NEW", Const, 0, ""}, - {"SYS_THR_SELF", Const, 0, ""}, - {"SYS_THR_SET_NAME", Const, 0, ""}, - {"SYS_THR_SUSPEND", Const, 0, ""}, - {"SYS_THR_WAKE", Const, 0, ""}, - {"SYS_TIME", Const, 0, ""}, - {"SYS_TIMERFD_CREATE", Const, 0, ""}, - {"SYS_TIMERFD_GETTIME", Const, 0, ""}, - {"SYS_TIMERFD_SETTIME", Const, 0, ""}, - {"SYS_TIMER_CREATE", Const, 0, ""}, - {"SYS_TIMER_DELETE", Const, 0, ""}, - {"SYS_TIMER_GETOVERRUN", Const, 0, ""}, - {"SYS_TIMER_GETTIME", Const, 0, ""}, - {"SYS_TIMER_SETTIME", Const, 0, ""}, - {"SYS_TIMES", Const, 0, ""}, - {"SYS_TKILL", Const, 0, ""}, - {"SYS_TRUNCATE", Const, 0, ""}, - {"SYS_TRUNCATE64", Const, 0, ""}, - {"SYS_TUXCALL", Const, 0, ""}, - {"SYS_UGETRLIMIT", Const, 0, ""}, - {"SYS_ULIMIT", Const, 0, ""}, - {"SYS_UMASK", Const, 0, ""}, - {"SYS_UMASK_EXTENDED", Const, 0, ""}, - {"SYS_UMOUNT", Const, 0, ""}, - {"SYS_UMOUNT2", Const, 0, ""}, - {"SYS_UNAME", Const, 0, ""}, - {"SYS_UNDELETE", Const, 0, ""}, - {"SYS_UNLINK", Const, 0, ""}, - {"SYS_UNLINKAT", Const, 0, ""}, - {"SYS_UNMOUNT", Const, 0, ""}, - {"SYS_UNSHARE", Const, 0, ""}, - {"SYS_USELIB", Const, 0, ""}, - {"SYS_USTAT", Const, 0, ""}, - {"SYS_UTIME", Const, 0, ""}, - {"SYS_UTIMENSAT", Const, 0, ""}, - {"SYS_UTIMES", Const, 0, ""}, - {"SYS_UTRACE", Const, 0, ""}, - {"SYS_UUIDGEN", Const, 0, ""}, - {"SYS_VADVISE", Const, 1, ""}, - {"SYS_VFORK", Const, 0, ""}, - {"SYS_VHANGUP", Const, 0, ""}, - {"SYS_VM86", Const, 0, ""}, - {"SYS_VM86OLD", Const, 0, ""}, - {"SYS_VMSPLICE", Const, 0, ""}, - {"SYS_VM_PRESSURE_MONITOR", Const, 0, ""}, - {"SYS_VSERVER", Const, 0, ""}, - {"SYS_WAIT4", Const, 0, ""}, - {"SYS_WAIT4_NOCANCEL", Const, 0, ""}, - {"SYS_WAIT6", Const, 1, ""}, - {"SYS_WAITEVENT", Const, 0, ""}, - {"SYS_WAITID", Const, 0, ""}, - {"SYS_WAITID_NOCANCEL", Const, 0, ""}, - {"SYS_WAITPID", Const, 0, ""}, - {"SYS_WATCHEVENT", Const, 0, ""}, - {"SYS_WORKQ_KERNRETURN", Const, 0, ""}, - {"SYS_WORKQ_OPEN", Const, 0, ""}, - {"SYS_WRITE", Const, 0, ""}, - {"SYS_WRITEV", Const, 0, ""}, - {"SYS_WRITEV_NOCANCEL", Const, 0, ""}, - {"SYS_WRITE_NOCANCEL", Const, 0, ""}, - {"SYS_YIELD", Const, 0, ""}, - {"SYS__LLSEEK", Const, 0, ""}, - {"SYS__LWP_CONTINUE", Const, 1, ""}, - {"SYS__LWP_CREATE", Const, 1, ""}, - {"SYS__LWP_CTL", Const, 1, ""}, - {"SYS__LWP_DETACH", Const, 1, ""}, - {"SYS__LWP_EXIT", Const, 1, ""}, - {"SYS__LWP_GETNAME", Const, 1, ""}, - {"SYS__LWP_GETPRIVATE", Const, 1, ""}, - {"SYS__LWP_KILL", Const, 1, ""}, - {"SYS__LWP_PARK", Const, 1, ""}, - {"SYS__LWP_SELF", Const, 1, ""}, - {"SYS__LWP_SETNAME", Const, 1, ""}, - {"SYS__LWP_SETPRIVATE", Const, 1, ""}, - {"SYS__LWP_SUSPEND", Const, 1, ""}, - {"SYS__LWP_UNPARK", Const, 1, ""}, - {"SYS__LWP_UNPARK_ALL", Const, 1, ""}, - {"SYS__LWP_WAIT", Const, 1, ""}, - {"SYS__LWP_WAKEUP", Const, 1, ""}, - {"SYS__NEWSELECT", Const, 0, ""}, - {"SYS__PSET_BIND", Const, 1, ""}, - {"SYS__SCHED_GETAFFINITY", Const, 1, ""}, - {"SYS__SCHED_GETPARAM", Const, 1, ""}, - {"SYS__SCHED_SETAFFINITY", Const, 1, ""}, - {"SYS__SCHED_SETPARAM", Const, 1, ""}, - {"SYS__SYSCTL", Const, 0, ""}, - {"SYS__UMTX_LOCK", Const, 0, ""}, - {"SYS__UMTX_OP", Const, 0, ""}, - {"SYS__UMTX_UNLOCK", Const, 0, ""}, - {"SYS___ACL_ACLCHECK_FD", Const, 0, ""}, - {"SYS___ACL_ACLCHECK_FILE", Const, 0, ""}, - {"SYS___ACL_ACLCHECK_LINK", Const, 0, ""}, - {"SYS___ACL_DELETE_FD", Const, 0, ""}, - {"SYS___ACL_DELETE_FILE", Const, 0, ""}, - {"SYS___ACL_DELETE_LINK", Const, 0, ""}, - {"SYS___ACL_GET_FD", Const, 0, ""}, - {"SYS___ACL_GET_FILE", Const, 0, ""}, - {"SYS___ACL_GET_LINK", Const, 0, ""}, - {"SYS___ACL_SET_FD", Const, 0, ""}, - {"SYS___ACL_SET_FILE", Const, 0, ""}, - {"SYS___ACL_SET_LINK", Const, 0, ""}, - {"SYS___CAP_RIGHTS_GET", Const, 14, ""}, - {"SYS___CLONE", Const, 1, ""}, - {"SYS___DISABLE_THREADSIGNAL", Const, 0, ""}, - {"SYS___GETCWD", Const, 0, ""}, - {"SYS___GETLOGIN", Const, 1, ""}, - {"SYS___GET_TCB", Const, 1, ""}, - {"SYS___MAC_EXECVE", Const, 0, ""}, - {"SYS___MAC_GETFSSTAT", Const, 0, ""}, - {"SYS___MAC_GET_FD", Const, 0, ""}, - {"SYS___MAC_GET_FILE", Const, 0, ""}, - {"SYS___MAC_GET_LCID", Const, 0, ""}, - {"SYS___MAC_GET_LCTX", Const, 0, ""}, - {"SYS___MAC_GET_LINK", Const, 0, ""}, - {"SYS___MAC_GET_MOUNT", Const, 0, ""}, - {"SYS___MAC_GET_PID", Const, 0, ""}, - {"SYS___MAC_GET_PROC", Const, 0, ""}, - {"SYS___MAC_MOUNT", Const, 0, ""}, - {"SYS___MAC_SET_FD", Const, 0, ""}, - {"SYS___MAC_SET_FILE", Const, 0, ""}, - {"SYS___MAC_SET_LCTX", Const, 0, ""}, - {"SYS___MAC_SET_LINK", Const, 0, ""}, - {"SYS___MAC_SET_PROC", Const, 0, ""}, - {"SYS___MAC_SYSCALL", Const, 0, ""}, - {"SYS___OLD_SEMWAIT_SIGNAL", Const, 0, ""}, - {"SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL", Const, 0, ""}, - {"SYS___POSIX_CHOWN", Const, 1, ""}, - {"SYS___POSIX_FCHOWN", Const, 1, ""}, - {"SYS___POSIX_LCHOWN", Const, 1, ""}, - {"SYS___POSIX_RENAME", Const, 1, ""}, - {"SYS___PTHREAD_CANCELED", Const, 0, ""}, - {"SYS___PTHREAD_CHDIR", Const, 0, ""}, - {"SYS___PTHREAD_FCHDIR", Const, 0, ""}, - {"SYS___PTHREAD_KILL", Const, 0, ""}, - {"SYS___PTHREAD_MARKCANCEL", Const, 0, ""}, - {"SYS___PTHREAD_SIGMASK", Const, 0, ""}, - {"SYS___QUOTACTL", Const, 1, ""}, - {"SYS___SEMCTL", Const, 1, ""}, - {"SYS___SEMWAIT_SIGNAL", Const, 0, ""}, - {"SYS___SEMWAIT_SIGNAL_NOCANCEL", Const, 0, ""}, - {"SYS___SETLOGIN", Const, 1, ""}, - {"SYS___SETUGID", Const, 0, ""}, - {"SYS___SET_TCB", Const, 1, ""}, - {"SYS___SIGACTION_SIGTRAMP", Const, 1, ""}, - {"SYS___SIGTIMEDWAIT", Const, 1, ""}, - {"SYS___SIGWAIT", Const, 0, ""}, - {"SYS___SIGWAIT_NOCANCEL", Const, 0, ""}, - {"SYS___SYSCTL", Const, 0, ""}, - {"SYS___TFORK", Const, 1, ""}, - {"SYS___THREXIT", Const, 1, ""}, - {"SYS___THRSIGDIVERT", Const, 1, ""}, - {"SYS___THRSLEEP", Const, 1, ""}, - {"SYS___THRWAKEUP", Const, 1, ""}, - {"S_ARCH1", Const, 1, ""}, - {"S_ARCH2", Const, 1, ""}, - {"S_BLKSIZE", Const, 0, ""}, - {"S_IEXEC", Const, 0, ""}, - {"S_IFBLK", Const, 0, ""}, - {"S_IFCHR", Const, 0, ""}, - {"S_IFDIR", Const, 0, ""}, - {"S_IFIFO", Const, 0, ""}, - {"S_IFLNK", Const, 0, ""}, - {"S_IFMT", Const, 0, ""}, - {"S_IFREG", Const, 0, ""}, - {"S_IFSOCK", Const, 0, ""}, - {"S_IFWHT", Const, 0, ""}, - {"S_IREAD", Const, 0, ""}, - {"S_IRGRP", Const, 0, ""}, - {"S_IROTH", Const, 0, ""}, - {"S_IRUSR", Const, 0, ""}, - {"S_IRWXG", Const, 0, ""}, - {"S_IRWXO", Const, 0, ""}, - {"S_IRWXU", Const, 0, ""}, - {"S_ISGID", Const, 0, ""}, - {"S_ISTXT", Const, 0, ""}, - {"S_ISUID", Const, 0, ""}, - {"S_ISVTX", Const, 0, ""}, - {"S_IWGRP", Const, 0, ""}, - {"S_IWOTH", Const, 0, ""}, - {"S_IWRITE", Const, 0, ""}, - {"S_IWUSR", Const, 0, ""}, - {"S_IXGRP", Const, 0, ""}, - {"S_IXOTH", Const, 0, ""}, - {"S_IXUSR", Const, 0, ""}, - {"S_LOGIN_SET", Const, 1, ""}, - {"SecurityAttributes", Type, 0, ""}, - {"SecurityAttributes.InheritHandle", Field, 0, ""}, - {"SecurityAttributes.Length", Field, 0, ""}, - {"SecurityAttributes.SecurityDescriptor", Field, 0, ""}, - {"Seek", Func, 0, "func(fd int, offset int64, whence int) (off int64, err error)"}, - {"Select", Func, 0, "func(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)"}, - {"Sendfile", Func, 0, "func(outfd int, infd int, offset *int64, count int) (written int, err error)"}, - {"Sendmsg", Func, 0, "func(fd int, p []byte, oob []byte, to Sockaddr, flags int) (err error)"}, - {"SendmsgN", Func, 3, "func(fd int, p []byte, oob []byte, to Sockaddr, flags int) (n int, err error)"}, - {"Sendto", Func, 0, "func(fd int, p []byte, flags int, to Sockaddr) (err error)"}, - {"Servent", Type, 0, ""}, - {"Servent.Aliases", Field, 0, ""}, - {"Servent.Name", Field, 0, ""}, - {"Servent.Port", Field, 0, ""}, - {"Servent.Proto", Field, 0, ""}, - {"SetBpf", Func, 0, ""}, - {"SetBpfBuflen", Func, 0, ""}, - {"SetBpfDatalink", Func, 0, ""}, - {"SetBpfHeadercmpl", Func, 0, ""}, - {"SetBpfImmediate", Func, 0, ""}, - {"SetBpfInterface", Func, 0, ""}, - {"SetBpfPromisc", Func, 0, ""}, - {"SetBpfTimeout", Func, 0, ""}, - {"SetCurrentDirectory", Func, 0, ""}, - {"SetEndOfFile", Func, 0, ""}, - {"SetEnvironmentVariable", Func, 0, ""}, - {"SetFileAttributes", Func, 0, ""}, - {"SetFileCompletionNotificationModes", Func, 2, ""}, - {"SetFilePointer", Func, 0, ""}, - {"SetFileTime", Func, 0, ""}, - {"SetHandleInformation", Func, 0, ""}, - {"SetKevent", Func, 0, ""}, - {"SetLsfPromisc", Func, 0, "func(name string, m bool) error"}, - {"SetNonblock", Func, 0, "func(fd int, nonblocking bool) (err error)"}, - {"Setdomainname", Func, 0, "func(p []byte) (err error)"}, - {"Setegid", Func, 0, "func(egid int) (err error)"}, - {"Setenv", Func, 0, "func(key string, value string) error"}, - {"Seteuid", Func, 0, "func(euid int) (err error)"}, - {"Setfsgid", Func, 0, "func(gid int) (err error)"}, - {"Setfsuid", Func, 0, "func(uid int) (err error)"}, - {"Setgid", Func, 0, "func(gid int) (err error)"}, - {"Setgroups", Func, 0, "func(gids []int) (err error)"}, - {"Sethostname", Func, 0, "func(p []byte) (err error)"}, - {"Setlogin", Func, 0, ""}, - {"Setpgid", Func, 0, "func(pid int, pgid int) (err error)"}, - {"Setpriority", Func, 0, "func(which int, who int, prio int) (err error)"}, - {"Setprivexec", Func, 0, ""}, - {"Setregid", Func, 0, "func(rgid int, egid int) (err error)"}, - {"Setresgid", Func, 0, "func(rgid int, egid int, sgid int) (err error)"}, - {"Setresuid", Func, 0, "func(ruid int, euid int, suid int) (err error)"}, - {"Setreuid", Func, 0, "func(ruid int, euid int) (err error)"}, - {"Setrlimit", Func, 0, "func(resource int, rlim *Rlimit) error"}, - {"Setsid", Func, 0, "func() (pid int, err error)"}, - {"Setsockopt", Func, 0, ""}, - {"SetsockoptByte", Func, 0, "func(fd int, level int, opt int, value byte) (err error)"}, - {"SetsockoptICMPv6Filter", Func, 2, "func(fd int, level int, opt int, filter *ICMPv6Filter) error"}, - {"SetsockoptIPMreq", Func, 0, "func(fd int, level int, opt int, mreq *IPMreq) (err error)"}, - {"SetsockoptIPMreqn", Func, 0, "func(fd int, level int, opt int, mreq *IPMreqn) (err error)"}, - {"SetsockoptIPv6Mreq", Func, 0, "func(fd int, level int, opt int, mreq *IPv6Mreq) (err error)"}, - {"SetsockoptInet4Addr", Func, 0, "func(fd int, level int, opt int, value [4]byte) (err error)"}, - {"SetsockoptInt", Func, 0, "func(fd int, level int, opt int, value int) (err error)"}, - {"SetsockoptLinger", Func, 0, "func(fd int, level int, opt int, l *Linger) (err error)"}, - {"SetsockoptString", Func, 0, "func(fd int, level int, opt int, s string) (err error)"}, - {"SetsockoptTimeval", Func, 0, "func(fd int, level int, opt int, tv *Timeval) (err error)"}, - {"Settimeofday", Func, 0, "func(tv *Timeval) (err error)"}, - {"Setuid", Func, 0, "func(uid int) (err error)"}, - {"Setxattr", Func, 1, "func(path string, attr string, data []byte, flags int) (err error)"}, - {"Shutdown", Func, 0, "func(fd int, how int) (err error)"}, - {"SidTypeAlias", Const, 0, ""}, - {"SidTypeComputer", Const, 0, ""}, - {"SidTypeDeletedAccount", Const, 0, ""}, - {"SidTypeDomain", Const, 0, ""}, - {"SidTypeGroup", Const, 0, ""}, - {"SidTypeInvalid", Const, 0, ""}, - {"SidTypeLabel", Const, 0, ""}, - {"SidTypeUnknown", Const, 0, ""}, - {"SidTypeUser", Const, 0, ""}, - {"SidTypeWellKnownGroup", Const, 0, ""}, - {"Signal", Type, 0, ""}, - {"SizeofBpfHdr", Const, 0, ""}, - {"SizeofBpfInsn", Const, 0, ""}, - {"SizeofBpfProgram", Const, 0, ""}, - {"SizeofBpfStat", Const, 0, ""}, - {"SizeofBpfVersion", Const, 0, ""}, - {"SizeofBpfZbuf", Const, 0, ""}, - {"SizeofBpfZbufHeader", Const, 0, ""}, - {"SizeofCmsghdr", Const, 0, ""}, - {"SizeofICMPv6Filter", Const, 2, ""}, - {"SizeofIPMreq", Const, 0, ""}, - {"SizeofIPMreqn", Const, 0, ""}, - {"SizeofIPv6MTUInfo", Const, 2, ""}, - {"SizeofIPv6Mreq", Const, 0, ""}, - {"SizeofIfAddrmsg", Const, 0, ""}, - {"SizeofIfAnnounceMsghdr", Const, 1, ""}, - {"SizeofIfData", Const, 0, ""}, - {"SizeofIfInfomsg", Const, 0, ""}, - {"SizeofIfMsghdr", Const, 0, ""}, - {"SizeofIfaMsghdr", Const, 0, ""}, - {"SizeofIfmaMsghdr", Const, 0, ""}, - {"SizeofIfmaMsghdr2", Const, 0, ""}, - {"SizeofInet4Pktinfo", Const, 0, ""}, - {"SizeofInet6Pktinfo", Const, 0, ""}, - {"SizeofInotifyEvent", Const, 0, ""}, - {"SizeofLinger", Const, 0, ""}, - {"SizeofMsghdr", Const, 0, ""}, - {"SizeofNlAttr", Const, 0, ""}, - {"SizeofNlMsgerr", Const, 0, ""}, - {"SizeofNlMsghdr", Const, 0, ""}, - {"SizeofRtAttr", Const, 0, ""}, - {"SizeofRtGenmsg", Const, 0, ""}, - {"SizeofRtMetrics", Const, 0, ""}, - {"SizeofRtMsg", Const, 0, ""}, - {"SizeofRtMsghdr", Const, 0, ""}, - {"SizeofRtNexthop", Const, 0, ""}, - {"SizeofSockFilter", Const, 0, ""}, - {"SizeofSockFprog", Const, 0, ""}, - {"SizeofSockaddrAny", Const, 0, ""}, - {"SizeofSockaddrDatalink", Const, 0, ""}, - {"SizeofSockaddrInet4", Const, 0, ""}, - {"SizeofSockaddrInet6", Const, 0, ""}, - {"SizeofSockaddrLinklayer", Const, 0, ""}, - {"SizeofSockaddrNetlink", Const, 0, ""}, - {"SizeofSockaddrUnix", Const, 0, ""}, - {"SizeofTCPInfo", Const, 1, ""}, - {"SizeofUcred", Const, 0, ""}, - {"SlicePtrFromStrings", Func, 1, "func(ss []string) ([]*byte, error)"}, - {"SockFilter", Type, 0, ""}, - {"SockFilter.Code", Field, 0, ""}, - {"SockFilter.Jf", Field, 0, ""}, - {"SockFilter.Jt", Field, 0, ""}, - {"SockFilter.K", Field, 0, ""}, - {"SockFprog", Type, 0, ""}, - {"SockFprog.Filter", Field, 0, ""}, - {"SockFprog.Len", Field, 0, ""}, - {"SockFprog.Pad_cgo_0", Field, 0, ""}, - {"SockaddrDatalink", Type, 0, ""}, - {"SockaddrDatalink.Alen", Field, 0, ""}, - {"SockaddrDatalink.Data", Field, 0, ""}, - {"SockaddrDatalink.Family", Field, 0, ""}, - {"SockaddrDatalink.Index", Field, 0, ""}, - {"SockaddrDatalink.Len", Field, 0, ""}, - {"SockaddrDatalink.Nlen", Field, 0, ""}, - {"SockaddrDatalink.Slen", Field, 0, ""}, - {"SockaddrDatalink.Type", Field, 0, ""}, - {"SockaddrGen", Type, 0, ""}, - {"SockaddrInet4", Type, 0, ""}, - {"SockaddrInet4.Addr", Field, 0, ""}, - {"SockaddrInet4.Port", Field, 0, ""}, - {"SockaddrInet6", Type, 0, ""}, - {"SockaddrInet6.Addr", Field, 0, ""}, - {"SockaddrInet6.Port", Field, 0, ""}, - {"SockaddrInet6.ZoneId", Field, 0, ""}, - {"SockaddrLinklayer", Type, 0, ""}, - {"SockaddrLinklayer.Addr", Field, 0, ""}, - {"SockaddrLinklayer.Halen", Field, 0, ""}, - {"SockaddrLinklayer.Hatype", Field, 0, ""}, - {"SockaddrLinklayer.Ifindex", Field, 0, ""}, - {"SockaddrLinklayer.Pkttype", Field, 0, ""}, - {"SockaddrLinklayer.Protocol", Field, 0, ""}, - {"SockaddrNetlink", Type, 0, ""}, - {"SockaddrNetlink.Family", Field, 0, ""}, - {"SockaddrNetlink.Groups", Field, 0, ""}, - {"SockaddrNetlink.Pad", Field, 0, ""}, - {"SockaddrNetlink.Pid", Field, 0, ""}, - {"SockaddrUnix", Type, 0, ""}, - {"SockaddrUnix.Name", Field, 0, ""}, - {"Socket", Func, 0, "func(domain int, typ int, proto int) (fd int, err error)"}, - {"SocketControlMessage", Type, 0, ""}, - {"SocketControlMessage.Data", Field, 0, ""}, - {"SocketControlMessage.Header", Field, 0, ""}, - {"SocketDisableIPv6", Var, 0, ""}, - {"Socketpair", Func, 0, "func(domain int, typ int, proto int) (fd [2]int, err error)"}, - {"Splice", Func, 0, "func(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)"}, - {"StartProcess", Func, 0, "func(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error)"}, - {"StartupInfo", Type, 0, ""}, - {"StartupInfo.Cb", Field, 0, ""}, - {"StartupInfo.Desktop", Field, 0, ""}, - {"StartupInfo.FillAttribute", Field, 0, ""}, - {"StartupInfo.Flags", Field, 0, ""}, - {"StartupInfo.ShowWindow", Field, 0, ""}, - {"StartupInfo.StdErr", Field, 0, ""}, - {"StartupInfo.StdInput", Field, 0, ""}, - {"StartupInfo.StdOutput", Field, 0, ""}, - {"StartupInfo.Title", Field, 0, ""}, - {"StartupInfo.X", Field, 0, ""}, - {"StartupInfo.XCountChars", Field, 0, ""}, - {"StartupInfo.XSize", Field, 0, ""}, - {"StartupInfo.Y", Field, 0, ""}, - {"StartupInfo.YCountChars", Field, 0, ""}, - {"StartupInfo.YSize", Field, 0, ""}, - {"Stat", Func, 0, "func(path string, stat *Stat_t) (err error)"}, - {"Stat_t", Type, 0, ""}, - {"Stat_t.Atim", Field, 0, ""}, - {"Stat_t.Atim_ext", Field, 12, ""}, - {"Stat_t.Atimespec", Field, 0, ""}, - {"Stat_t.Birthtimespec", Field, 0, ""}, - {"Stat_t.Blksize", Field, 0, ""}, - {"Stat_t.Blocks", Field, 0, ""}, - {"Stat_t.Btim_ext", Field, 12, ""}, - {"Stat_t.Ctim", Field, 0, ""}, - {"Stat_t.Ctim_ext", Field, 12, ""}, - {"Stat_t.Ctimespec", Field, 0, ""}, - {"Stat_t.Dev", Field, 0, ""}, - {"Stat_t.Flags", Field, 0, ""}, - {"Stat_t.Gen", Field, 0, ""}, - {"Stat_t.Gid", Field, 0, ""}, - {"Stat_t.Ino", Field, 0, ""}, - {"Stat_t.Lspare", Field, 0, ""}, - {"Stat_t.Lspare0", Field, 2, ""}, - {"Stat_t.Lspare1", Field, 2, ""}, - {"Stat_t.Mode", Field, 0, ""}, - {"Stat_t.Mtim", Field, 0, ""}, - {"Stat_t.Mtim_ext", Field, 12, ""}, - {"Stat_t.Mtimespec", Field, 0, ""}, - {"Stat_t.Nlink", Field, 0, ""}, - {"Stat_t.Pad_cgo_0", Field, 0, ""}, - {"Stat_t.Pad_cgo_1", Field, 0, ""}, - {"Stat_t.Pad_cgo_2", Field, 0, ""}, - {"Stat_t.Padding0", Field, 12, ""}, - {"Stat_t.Padding1", Field, 12, ""}, - {"Stat_t.Qspare", Field, 0, ""}, - {"Stat_t.Rdev", Field, 0, ""}, - {"Stat_t.Size", Field, 0, ""}, - {"Stat_t.Spare", Field, 2, ""}, - {"Stat_t.Uid", Field, 0, ""}, - {"Stat_t.X__pad0", Field, 0, ""}, - {"Stat_t.X__pad1", Field, 0, ""}, - {"Stat_t.X__pad2", Field, 0, ""}, - {"Stat_t.X__st_birthtim", Field, 2, ""}, - {"Stat_t.X__st_ino", Field, 0, ""}, - {"Stat_t.X__unused", Field, 0, ""}, - {"Statfs", Func, 0, "func(path string, buf *Statfs_t) (err error)"}, - {"Statfs_t", Type, 0, ""}, - {"Statfs_t.Asyncreads", Field, 0, ""}, - {"Statfs_t.Asyncwrites", Field, 0, ""}, - {"Statfs_t.Bavail", Field, 0, ""}, - {"Statfs_t.Bfree", Field, 0, ""}, - {"Statfs_t.Blocks", Field, 0, ""}, - {"Statfs_t.Bsize", Field, 0, ""}, - {"Statfs_t.Charspare", Field, 0, ""}, - {"Statfs_t.F_asyncreads", Field, 2, ""}, - {"Statfs_t.F_asyncwrites", Field, 2, ""}, - {"Statfs_t.F_bavail", Field, 2, ""}, - {"Statfs_t.F_bfree", Field, 2, ""}, - {"Statfs_t.F_blocks", Field, 2, ""}, - {"Statfs_t.F_bsize", Field, 2, ""}, - {"Statfs_t.F_ctime", Field, 2, ""}, - {"Statfs_t.F_favail", Field, 2, ""}, - {"Statfs_t.F_ffree", Field, 2, ""}, - {"Statfs_t.F_files", Field, 2, ""}, - {"Statfs_t.F_flags", Field, 2, ""}, - {"Statfs_t.F_fsid", Field, 2, ""}, - {"Statfs_t.F_fstypename", Field, 2, ""}, - {"Statfs_t.F_iosize", Field, 2, ""}, - {"Statfs_t.F_mntfromname", Field, 2, ""}, - {"Statfs_t.F_mntfromspec", Field, 3, ""}, - {"Statfs_t.F_mntonname", Field, 2, ""}, - {"Statfs_t.F_namemax", Field, 2, ""}, - {"Statfs_t.F_owner", Field, 2, ""}, - {"Statfs_t.F_spare", Field, 2, ""}, - {"Statfs_t.F_syncreads", Field, 2, ""}, - {"Statfs_t.F_syncwrites", Field, 2, ""}, - {"Statfs_t.Ffree", Field, 0, ""}, - {"Statfs_t.Files", Field, 0, ""}, - {"Statfs_t.Flags", Field, 0, ""}, - {"Statfs_t.Frsize", Field, 0, ""}, - {"Statfs_t.Fsid", Field, 0, ""}, - {"Statfs_t.Fssubtype", Field, 0, ""}, - {"Statfs_t.Fstypename", Field, 0, ""}, - {"Statfs_t.Iosize", Field, 0, ""}, - {"Statfs_t.Mntfromname", Field, 0, ""}, - {"Statfs_t.Mntonname", Field, 0, ""}, - {"Statfs_t.Mount_info", Field, 2, ""}, - {"Statfs_t.Namelen", Field, 0, ""}, - {"Statfs_t.Namemax", Field, 0, ""}, - {"Statfs_t.Owner", Field, 0, ""}, - {"Statfs_t.Pad_cgo_0", Field, 0, ""}, - {"Statfs_t.Pad_cgo_1", Field, 2, ""}, - {"Statfs_t.Reserved", Field, 0, ""}, - {"Statfs_t.Spare", Field, 0, ""}, - {"Statfs_t.Syncreads", Field, 0, ""}, - {"Statfs_t.Syncwrites", Field, 0, ""}, - {"Statfs_t.Type", Field, 0, ""}, - {"Statfs_t.Version", Field, 0, ""}, - {"Stderr", Var, 0, ""}, - {"Stdin", Var, 0, ""}, - {"Stdout", Var, 0, ""}, - {"StringBytePtr", Func, 0, "func(s string) *byte"}, - {"StringByteSlice", Func, 0, "func(s string) []byte"}, - {"StringSlicePtr", Func, 0, "func(ss []string) []*byte"}, - {"StringToSid", Func, 0, ""}, - {"StringToUTF16", Func, 0, ""}, - {"StringToUTF16Ptr", Func, 0, ""}, - {"Symlink", Func, 0, "func(oldpath string, newpath string) (err error)"}, - {"Sync", Func, 0, "func()"}, - {"SyncFileRange", Func, 0, "func(fd int, off int64, n int64, flags int) (err error)"}, - {"SysProcAttr", Type, 0, ""}, - {"SysProcAttr.AdditionalInheritedHandles", Field, 17, ""}, - {"SysProcAttr.AmbientCaps", Field, 9, ""}, - {"SysProcAttr.CgroupFD", Field, 20, ""}, - {"SysProcAttr.Chroot", Field, 0, ""}, - {"SysProcAttr.Cloneflags", Field, 2, ""}, - {"SysProcAttr.CmdLine", Field, 0, ""}, - {"SysProcAttr.CreationFlags", Field, 1, ""}, - {"SysProcAttr.Credential", Field, 0, ""}, - {"SysProcAttr.Ctty", Field, 1, ""}, - {"SysProcAttr.Foreground", Field, 5, ""}, - {"SysProcAttr.GidMappings", Field, 4, ""}, - {"SysProcAttr.GidMappingsEnableSetgroups", Field, 5, ""}, - {"SysProcAttr.HideWindow", Field, 0, ""}, - {"SysProcAttr.Jail", Field, 21, ""}, - {"SysProcAttr.NoInheritHandles", Field, 16, ""}, - {"SysProcAttr.Noctty", Field, 0, ""}, - {"SysProcAttr.ParentProcess", Field, 17, ""}, - {"SysProcAttr.Pdeathsig", Field, 0, ""}, - {"SysProcAttr.Pgid", Field, 5, ""}, - {"SysProcAttr.PidFD", Field, 22, ""}, - {"SysProcAttr.ProcessAttributes", Field, 13, ""}, - {"SysProcAttr.Ptrace", Field, 0, ""}, - {"SysProcAttr.Setctty", Field, 0, ""}, - {"SysProcAttr.Setpgid", Field, 0, ""}, - {"SysProcAttr.Setsid", Field, 0, ""}, - {"SysProcAttr.ThreadAttributes", Field, 13, ""}, - {"SysProcAttr.Token", Field, 10, ""}, - {"SysProcAttr.UidMappings", Field, 4, ""}, - {"SysProcAttr.Unshareflags", Field, 7, ""}, - {"SysProcAttr.UseCgroupFD", Field, 20, ""}, - {"SysProcIDMap", Type, 4, ""}, - {"SysProcIDMap.ContainerID", Field, 4, ""}, - {"SysProcIDMap.HostID", Field, 4, ""}, - {"SysProcIDMap.Size", Field, 4, ""}, - {"Syscall", Func, 0, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err Errno)"}, - {"Syscall12", Func, 0, ""}, - {"Syscall15", Func, 0, ""}, - {"Syscall18", Func, 12, ""}, - {"Syscall6", Func, 0, "func(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err Errno)"}, - {"Syscall9", Func, 0, ""}, - {"SyscallN", Func, 18, ""}, - {"Sysctl", Func, 0, ""}, - {"SysctlUint32", Func, 0, ""}, - {"Sysctlnode", Type, 2, ""}, - {"Sysctlnode.Flags", Field, 2, ""}, - {"Sysctlnode.Name", Field, 2, ""}, - {"Sysctlnode.Num", Field, 2, ""}, - {"Sysctlnode.Un", Field, 2, ""}, - {"Sysctlnode.Ver", Field, 2, ""}, - {"Sysctlnode.X__rsvd", Field, 2, ""}, - {"Sysctlnode.X_sysctl_desc", Field, 2, ""}, - {"Sysctlnode.X_sysctl_func", Field, 2, ""}, - {"Sysctlnode.X_sysctl_parent", Field, 2, ""}, - {"Sysctlnode.X_sysctl_size", Field, 2, ""}, - {"Sysinfo", Func, 0, "func(info *Sysinfo_t) (err error)"}, - {"Sysinfo_t", Type, 0, ""}, - {"Sysinfo_t.Bufferram", Field, 0, ""}, - {"Sysinfo_t.Freehigh", Field, 0, ""}, - {"Sysinfo_t.Freeram", Field, 0, ""}, - {"Sysinfo_t.Freeswap", Field, 0, ""}, - {"Sysinfo_t.Loads", Field, 0, ""}, - {"Sysinfo_t.Pad", Field, 0, ""}, - {"Sysinfo_t.Pad_cgo_0", Field, 0, ""}, - {"Sysinfo_t.Pad_cgo_1", Field, 0, ""}, - {"Sysinfo_t.Procs", Field, 0, ""}, - {"Sysinfo_t.Sharedram", Field, 0, ""}, - {"Sysinfo_t.Totalhigh", Field, 0, ""}, - {"Sysinfo_t.Totalram", Field, 0, ""}, - {"Sysinfo_t.Totalswap", Field, 0, ""}, - {"Sysinfo_t.Unit", Field, 0, ""}, - {"Sysinfo_t.Uptime", Field, 0, ""}, - {"Sysinfo_t.X_f", Field, 0, ""}, - {"Systemtime", Type, 0, ""}, - {"Systemtime.Day", Field, 0, ""}, - {"Systemtime.DayOfWeek", Field, 0, ""}, - {"Systemtime.Hour", Field, 0, ""}, - {"Systemtime.Milliseconds", Field, 0, ""}, - {"Systemtime.Minute", Field, 0, ""}, - {"Systemtime.Month", Field, 0, ""}, - {"Systemtime.Second", Field, 0, ""}, - {"Systemtime.Year", Field, 0, ""}, - {"TCGETS", Const, 0, ""}, - {"TCIFLUSH", Const, 1, ""}, - {"TCIOFLUSH", Const, 1, ""}, - {"TCOFLUSH", Const, 1, ""}, - {"TCPInfo", Type, 1, ""}, - {"TCPInfo.Advmss", Field, 1, ""}, - {"TCPInfo.Ato", Field, 1, ""}, - {"TCPInfo.Backoff", Field, 1, ""}, - {"TCPInfo.Ca_state", Field, 1, ""}, - {"TCPInfo.Fackets", Field, 1, ""}, - {"TCPInfo.Last_ack_recv", Field, 1, ""}, - {"TCPInfo.Last_ack_sent", Field, 1, ""}, - {"TCPInfo.Last_data_recv", Field, 1, ""}, - {"TCPInfo.Last_data_sent", Field, 1, ""}, - {"TCPInfo.Lost", Field, 1, ""}, - {"TCPInfo.Options", Field, 1, ""}, - {"TCPInfo.Pad_cgo_0", Field, 1, ""}, - {"TCPInfo.Pmtu", Field, 1, ""}, - {"TCPInfo.Probes", Field, 1, ""}, - {"TCPInfo.Rcv_mss", Field, 1, ""}, - {"TCPInfo.Rcv_rtt", Field, 1, ""}, - {"TCPInfo.Rcv_space", Field, 1, ""}, - {"TCPInfo.Rcv_ssthresh", Field, 1, ""}, - {"TCPInfo.Reordering", Field, 1, ""}, - {"TCPInfo.Retrans", Field, 1, ""}, - {"TCPInfo.Retransmits", Field, 1, ""}, - {"TCPInfo.Rto", Field, 1, ""}, - {"TCPInfo.Rtt", Field, 1, ""}, - {"TCPInfo.Rttvar", Field, 1, ""}, - {"TCPInfo.Sacked", Field, 1, ""}, - {"TCPInfo.Snd_cwnd", Field, 1, ""}, - {"TCPInfo.Snd_mss", Field, 1, ""}, - {"TCPInfo.Snd_ssthresh", Field, 1, ""}, - {"TCPInfo.State", Field, 1, ""}, - {"TCPInfo.Total_retrans", Field, 1, ""}, - {"TCPInfo.Unacked", Field, 1, ""}, - {"TCPKeepalive", Type, 3, ""}, - {"TCPKeepalive.Interval", Field, 3, ""}, - {"TCPKeepalive.OnOff", Field, 3, ""}, - {"TCPKeepalive.Time", Field, 3, ""}, - {"TCP_CA_NAME_MAX", Const, 0, ""}, - {"TCP_CONGCTL", Const, 1, ""}, - {"TCP_CONGESTION", Const, 0, ""}, - {"TCP_CONNECTIONTIMEOUT", Const, 0, ""}, - {"TCP_CORK", Const, 0, ""}, - {"TCP_DEFER_ACCEPT", Const, 0, ""}, - {"TCP_ENABLE_ECN", Const, 16, ""}, - {"TCP_INFO", Const, 0, ""}, - {"TCP_KEEPALIVE", Const, 0, ""}, - {"TCP_KEEPCNT", Const, 0, ""}, - {"TCP_KEEPIDLE", Const, 0, ""}, - {"TCP_KEEPINIT", Const, 1, ""}, - {"TCP_KEEPINTVL", Const, 0, ""}, - {"TCP_LINGER2", Const, 0, ""}, - {"TCP_MAXBURST", Const, 0, ""}, - {"TCP_MAXHLEN", Const, 0, ""}, - {"TCP_MAXOLEN", Const, 0, ""}, - {"TCP_MAXSEG", Const, 0, ""}, - {"TCP_MAXWIN", Const, 0, ""}, - {"TCP_MAX_SACK", Const, 0, ""}, - {"TCP_MAX_WINSHIFT", Const, 0, ""}, - {"TCP_MD5SIG", Const, 0, ""}, - {"TCP_MD5SIG_MAXKEYLEN", Const, 0, ""}, - {"TCP_MINMSS", Const, 0, ""}, - {"TCP_MINMSSOVERLOAD", Const, 0, ""}, - {"TCP_MSS", Const, 0, ""}, - {"TCP_NODELAY", Const, 0, ""}, - {"TCP_NOOPT", Const, 0, ""}, - {"TCP_NOPUSH", Const, 0, ""}, - {"TCP_NOTSENT_LOWAT", Const, 16, ""}, - {"TCP_NSTATES", Const, 1, ""}, - {"TCP_QUICKACK", Const, 0, ""}, - {"TCP_RXT_CONNDROPTIME", Const, 0, ""}, - {"TCP_RXT_FINDROP", Const, 0, ""}, - {"TCP_SACK_ENABLE", Const, 1, ""}, - {"TCP_SENDMOREACKS", Const, 16, ""}, - {"TCP_SYNCNT", Const, 0, ""}, - {"TCP_VENDOR", Const, 3, ""}, - {"TCP_WINDOW_CLAMP", Const, 0, ""}, - {"TCSAFLUSH", Const, 1, ""}, - {"TCSETS", Const, 0, ""}, - {"TF_DISCONNECT", Const, 0, ""}, - {"TF_REUSE_SOCKET", Const, 0, ""}, - {"TF_USE_DEFAULT_WORKER", Const, 0, ""}, - {"TF_USE_KERNEL_APC", Const, 0, ""}, - {"TF_USE_SYSTEM_THREAD", Const, 0, ""}, - {"TF_WRITE_BEHIND", Const, 0, ""}, - {"TH32CS_INHERIT", Const, 4, ""}, - {"TH32CS_SNAPALL", Const, 4, ""}, - {"TH32CS_SNAPHEAPLIST", Const, 4, ""}, - {"TH32CS_SNAPMODULE", Const, 4, ""}, - {"TH32CS_SNAPMODULE32", Const, 4, ""}, - {"TH32CS_SNAPPROCESS", Const, 4, ""}, - {"TH32CS_SNAPTHREAD", Const, 4, ""}, - {"TIME_ZONE_ID_DAYLIGHT", Const, 0, ""}, - {"TIME_ZONE_ID_STANDARD", Const, 0, ""}, - {"TIME_ZONE_ID_UNKNOWN", Const, 0, ""}, - {"TIOCCBRK", Const, 0, ""}, - {"TIOCCDTR", Const, 0, ""}, - {"TIOCCONS", Const, 0, ""}, - {"TIOCDCDTIMESTAMP", Const, 0, ""}, - {"TIOCDRAIN", Const, 0, ""}, - {"TIOCDSIMICROCODE", Const, 0, ""}, - {"TIOCEXCL", Const, 0, ""}, - {"TIOCEXT", Const, 0, ""}, - {"TIOCFLAG_CDTRCTS", Const, 1, ""}, - {"TIOCFLAG_CLOCAL", Const, 1, ""}, - {"TIOCFLAG_CRTSCTS", Const, 1, ""}, - {"TIOCFLAG_MDMBUF", Const, 1, ""}, - {"TIOCFLAG_PPS", Const, 1, ""}, - {"TIOCFLAG_SOFTCAR", Const, 1, ""}, - {"TIOCFLUSH", Const, 0, ""}, - {"TIOCGDEV", Const, 0, ""}, - {"TIOCGDRAINWAIT", Const, 0, ""}, - {"TIOCGETA", Const, 0, ""}, - {"TIOCGETD", Const, 0, ""}, - {"TIOCGFLAGS", Const, 1, ""}, - {"TIOCGICOUNT", Const, 0, ""}, - {"TIOCGLCKTRMIOS", Const, 0, ""}, - {"TIOCGLINED", Const, 1, ""}, - {"TIOCGPGRP", Const, 0, ""}, - {"TIOCGPTN", Const, 0, ""}, - {"TIOCGQSIZE", Const, 1, ""}, - {"TIOCGRANTPT", Const, 1, ""}, - {"TIOCGRS485", Const, 0, ""}, - {"TIOCGSERIAL", Const, 0, ""}, - {"TIOCGSID", Const, 0, ""}, - {"TIOCGSIZE", Const, 1, ""}, - {"TIOCGSOFTCAR", Const, 0, ""}, - {"TIOCGTSTAMP", Const, 1, ""}, - {"TIOCGWINSZ", Const, 0, ""}, - {"TIOCINQ", Const, 0, ""}, - {"TIOCIXOFF", Const, 0, ""}, - {"TIOCIXON", Const, 0, ""}, - {"TIOCLINUX", Const, 0, ""}, - {"TIOCMBIC", Const, 0, ""}, - {"TIOCMBIS", Const, 0, ""}, - {"TIOCMGDTRWAIT", Const, 0, ""}, - {"TIOCMGET", Const, 0, ""}, - {"TIOCMIWAIT", Const, 0, ""}, - {"TIOCMODG", Const, 0, ""}, - {"TIOCMODS", Const, 0, ""}, - {"TIOCMSDTRWAIT", Const, 0, ""}, - {"TIOCMSET", Const, 0, ""}, - {"TIOCM_CAR", Const, 0, ""}, - {"TIOCM_CD", Const, 0, ""}, - {"TIOCM_CTS", Const, 0, ""}, - {"TIOCM_DCD", Const, 0, ""}, - {"TIOCM_DSR", Const, 0, ""}, - {"TIOCM_DTR", Const, 0, ""}, - {"TIOCM_LE", Const, 0, ""}, - {"TIOCM_RI", Const, 0, ""}, - {"TIOCM_RNG", Const, 0, ""}, - {"TIOCM_RTS", Const, 0, ""}, - {"TIOCM_SR", Const, 0, ""}, - {"TIOCM_ST", Const, 0, ""}, - {"TIOCNOTTY", Const, 0, ""}, - {"TIOCNXCL", Const, 0, ""}, - {"TIOCOUTQ", Const, 0, ""}, - {"TIOCPKT", Const, 0, ""}, - {"TIOCPKT_DATA", Const, 0, ""}, - {"TIOCPKT_DOSTOP", Const, 0, ""}, - {"TIOCPKT_FLUSHREAD", Const, 0, ""}, - {"TIOCPKT_FLUSHWRITE", Const, 0, ""}, - {"TIOCPKT_IOCTL", Const, 0, ""}, - {"TIOCPKT_NOSTOP", Const, 0, ""}, - {"TIOCPKT_START", Const, 0, ""}, - {"TIOCPKT_STOP", Const, 0, ""}, - {"TIOCPTMASTER", Const, 0, ""}, - {"TIOCPTMGET", Const, 1, ""}, - {"TIOCPTSNAME", Const, 1, ""}, - {"TIOCPTYGNAME", Const, 0, ""}, - {"TIOCPTYGRANT", Const, 0, ""}, - {"TIOCPTYUNLK", Const, 0, ""}, - {"TIOCRCVFRAME", Const, 1, ""}, - {"TIOCREMOTE", Const, 0, ""}, - {"TIOCSBRK", Const, 0, ""}, - {"TIOCSCONS", Const, 0, ""}, - {"TIOCSCTTY", Const, 0, ""}, - {"TIOCSDRAINWAIT", Const, 0, ""}, - {"TIOCSDTR", Const, 0, ""}, - {"TIOCSERCONFIG", Const, 0, ""}, - {"TIOCSERGETLSR", Const, 0, ""}, - {"TIOCSERGETMULTI", Const, 0, ""}, - {"TIOCSERGSTRUCT", Const, 0, ""}, - {"TIOCSERGWILD", Const, 0, ""}, - {"TIOCSERSETMULTI", Const, 0, ""}, - {"TIOCSERSWILD", Const, 0, ""}, - {"TIOCSER_TEMT", Const, 0, ""}, - {"TIOCSETA", Const, 0, ""}, - {"TIOCSETAF", Const, 0, ""}, - {"TIOCSETAW", Const, 0, ""}, - {"TIOCSETD", Const, 0, ""}, - {"TIOCSFLAGS", Const, 1, ""}, - {"TIOCSIG", Const, 0, ""}, - {"TIOCSLCKTRMIOS", Const, 0, ""}, - {"TIOCSLINED", Const, 1, ""}, - {"TIOCSPGRP", Const, 0, ""}, - {"TIOCSPTLCK", Const, 0, ""}, - {"TIOCSQSIZE", Const, 1, ""}, - {"TIOCSRS485", Const, 0, ""}, - {"TIOCSSERIAL", Const, 0, ""}, - {"TIOCSSIZE", Const, 1, ""}, - {"TIOCSSOFTCAR", Const, 0, ""}, - {"TIOCSTART", Const, 0, ""}, - {"TIOCSTAT", Const, 0, ""}, - {"TIOCSTI", Const, 0, ""}, - {"TIOCSTOP", Const, 0, ""}, - {"TIOCSTSTAMP", Const, 1, ""}, - {"TIOCSWINSZ", Const, 0, ""}, - {"TIOCTIMESTAMP", Const, 0, ""}, - {"TIOCUCNTL", Const, 0, ""}, - {"TIOCVHANGUP", Const, 0, ""}, - {"TIOCXMTFRAME", Const, 1, ""}, - {"TOKEN_ADJUST_DEFAULT", Const, 0, ""}, - {"TOKEN_ADJUST_GROUPS", Const, 0, ""}, - {"TOKEN_ADJUST_PRIVILEGES", Const, 0, ""}, - {"TOKEN_ADJUST_SESSIONID", Const, 11, ""}, - {"TOKEN_ALL_ACCESS", Const, 0, ""}, - {"TOKEN_ASSIGN_PRIMARY", Const, 0, ""}, - {"TOKEN_DUPLICATE", Const, 0, ""}, - {"TOKEN_EXECUTE", Const, 0, ""}, - {"TOKEN_IMPERSONATE", Const, 0, ""}, - {"TOKEN_QUERY", Const, 0, ""}, - {"TOKEN_QUERY_SOURCE", Const, 0, ""}, - {"TOKEN_READ", Const, 0, ""}, - {"TOKEN_WRITE", Const, 0, ""}, - {"TOSTOP", Const, 0, ""}, - {"TRUNCATE_EXISTING", Const, 0, ""}, - {"TUNATTACHFILTER", Const, 0, ""}, - {"TUNDETACHFILTER", Const, 0, ""}, - {"TUNGETFEATURES", Const, 0, ""}, - {"TUNGETIFF", Const, 0, ""}, - {"TUNGETSNDBUF", Const, 0, ""}, - {"TUNGETVNETHDRSZ", Const, 0, ""}, - {"TUNSETDEBUG", Const, 0, ""}, - {"TUNSETGROUP", Const, 0, ""}, - {"TUNSETIFF", Const, 0, ""}, - {"TUNSETLINK", Const, 0, ""}, - {"TUNSETNOCSUM", Const, 0, ""}, - {"TUNSETOFFLOAD", Const, 0, ""}, - {"TUNSETOWNER", Const, 0, ""}, - {"TUNSETPERSIST", Const, 0, ""}, - {"TUNSETSNDBUF", Const, 0, ""}, - {"TUNSETTXFILTER", Const, 0, ""}, - {"TUNSETVNETHDRSZ", Const, 0, ""}, - {"Tee", Func, 0, "func(rfd int, wfd int, len int, flags int) (n int64, err error)"}, - {"TerminateProcess", Func, 0, ""}, - {"Termios", Type, 0, ""}, - {"Termios.Cc", Field, 0, ""}, - {"Termios.Cflag", Field, 0, ""}, - {"Termios.Iflag", Field, 0, ""}, - {"Termios.Ispeed", Field, 0, ""}, - {"Termios.Lflag", Field, 0, ""}, - {"Termios.Line", Field, 0, ""}, - {"Termios.Oflag", Field, 0, ""}, - {"Termios.Ospeed", Field, 0, ""}, - {"Termios.Pad_cgo_0", Field, 0, ""}, - {"Tgkill", Func, 0, "func(tgid int, tid int, sig Signal) (err error)"}, - {"Time", Func, 0, "func(t *Time_t) (tt Time_t, err error)"}, - {"Time_t", Type, 0, ""}, - {"Times", Func, 0, "func(tms *Tms) (ticks uintptr, err error)"}, - {"Timespec", Type, 0, ""}, - {"Timespec.Nsec", Field, 0, ""}, - {"Timespec.Pad_cgo_0", Field, 2, ""}, - {"Timespec.Sec", Field, 0, ""}, - {"TimespecToNsec", Func, 0, "func(ts Timespec) int64"}, - {"Timeval", Type, 0, ""}, - {"Timeval.Pad_cgo_0", Field, 0, ""}, - {"Timeval.Sec", Field, 0, ""}, - {"Timeval.Usec", Field, 0, ""}, - {"Timeval32", Type, 0, ""}, - {"Timeval32.Sec", Field, 0, ""}, - {"Timeval32.Usec", Field, 0, ""}, - {"TimevalToNsec", Func, 0, "func(tv Timeval) int64"}, - {"Timex", Type, 0, ""}, - {"Timex.Calcnt", Field, 0, ""}, - {"Timex.Constant", Field, 0, ""}, - {"Timex.Errcnt", Field, 0, ""}, - {"Timex.Esterror", Field, 0, ""}, - {"Timex.Freq", Field, 0, ""}, - {"Timex.Jitcnt", Field, 0, ""}, - {"Timex.Jitter", Field, 0, ""}, - {"Timex.Maxerror", Field, 0, ""}, - {"Timex.Modes", Field, 0, ""}, - {"Timex.Offset", Field, 0, ""}, - {"Timex.Pad_cgo_0", Field, 0, ""}, - {"Timex.Pad_cgo_1", Field, 0, ""}, - {"Timex.Pad_cgo_2", Field, 0, ""}, - {"Timex.Pad_cgo_3", Field, 0, ""}, - {"Timex.Ppsfreq", Field, 0, ""}, - {"Timex.Precision", Field, 0, ""}, - {"Timex.Shift", Field, 0, ""}, - {"Timex.Stabil", Field, 0, ""}, - {"Timex.Status", Field, 0, ""}, - {"Timex.Stbcnt", Field, 0, ""}, - {"Timex.Tai", Field, 0, ""}, - {"Timex.Tick", Field, 0, ""}, - {"Timex.Time", Field, 0, ""}, - {"Timex.Tolerance", Field, 0, ""}, - {"Timezoneinformation", Type, 0, ""}, - {"Timezoneinformation.Bias", Field, 0, ""}, - {"Timezoneinformation.DaylightBias", Field, 0, ""}, - {"Timezoneinformation.DaylightDate", Field, 0, ""}, - {"Timezoneinformation.DaylightName", Field, 0, ""}, - {"Timezoneinformation.StandardBias", Field, 0, ""}, - {"Timezoneinformation.StandardDate", Field, 0, ""}, - {"Timezoneinformation.StandardName", Field, 0, ""}, - {"Tms", Type, 0, ""}, - {"Tms.Cstime", Field, 0, ""}, - {"Tms.Cutime", Field, 0, ""}, - {"Tms.Stime", Field, 0, ""}, - {"Tms.Utime", Field, 0, ""}, - {"Token", Type, 0, ""}, - {"TokenAccessInformation", Const, 0, ""}, - {"TokenAuditPolicy", Const, 0, ""}, - {"TokenDefaultDacl", Const, 0, ""}, - {"TokenElevation", Const, 0, ""}, - {"TokenElevationType", Const, 0, ""}, - {"TokenGroups", Const, 0, ""}, - {"TokenGroupsAndPrivileges", Const, 0, ""}, - {"TokenHasRestrictions", Const, 0, ""}, - {"TokenImpersonationLevel", Const, 0, ""}, - {"TokenIntegrityLevel", Const, 0, ""}, - {"TokenLinkedToken", Const, 0, ""}, - {"TokenLogonSid", Const, 0, ""}, - {"TokenMandatoryPolicy", Const, 0, ""}, - {"TokenOrigin", Const, 0, ""}, - {"TokenOwner", Const, 0, ""}, - {"TokenPrimaryGroup", Const, 0, ""}, - {"TokenPrivileges", Const, 0, ""}, - {"TokenRestrictedSids", Const, 0, ""}, - {"TokenSandBoxInert", Const, 0, ""}, - {"TokenSessionId", Const, 0, ""}, - {"TokenSessionReference", Const, 0, ""}, - {"TokenSource", Const, 0, ""}, - {"TokenStatistics", Const, 0, ""}, - {"TokenType", Const, 0, ""}, - {"TokenUIAccess", Const, 0, ""}, - {"TokenUser", Const, 0, ""}, - {"TokenVirtualizationAllowed", Const, 0, ""}, - {"TokenVirtualizationEnabled", Const, 0, ""}, - {"Tokenprimarygroup", Type, 0, ""}, - {"Tokenprimarygroup.PrimaryGroup", Field, 0, ""}, - {"Tokenuser", Type, 0, ""}, - {"Tokenuser.User", Field, 0, ""}, - {"TranslateAccountName", Func, 0, ""}, - {"TranslateName", Func, 0, ""}, - {"TransmitFile", Func, 0, ""}, - {"TransmitFileBuffers", Type, 0, ""}, - {"TransmitFileBuffers.Head", Field, 0, ""}, - {"TransmitFileBuffers.HeadLength", Field, 0, ""}, - {"TransmitFileBuffers.Tail", Field, 0, ""}, - {"TransmitFileBuffers.TailLength", Field, 0, ""}, - {"Truncate", Func, 0, "func(path string, length int64) (err error)"}, - {"UNIX_PATH_MAX", Const, 12, ""}, - {"USAGE_MATCH_TYPE_AND", Const, 0, ""}, - {"USAGE_MATCH_TYPE_OR", Const, 0, ""}, - {"UTF16FromString", Func, 1, ""}, - {"UTF16PtrFromString", Func, 1, ""}, - {"UTF16ToString", Func, 0, ""}, - {"Ucred", Type, 0, ""}, - {"Ucred.Gid", Field, 0, ""}, - {"Ucred.Pid", Field, 0, ""}, - {"Ucred.Uid", Field, 0, ""}, - {"Umask", Func, 0, "func(mask int) (oldmask int)"}, - {"Uname", Func, 0, "func(buf *Utsname) (err error)"}, - {"Undelete", Func, 0, ""}, - {"UnixCredentials", Func, 0, "func(ucred *Ucred) []byte"}, - {"UnixRights", Func, 0, "func(fds ...int) []byte"}, - {"Unlink", Func, 0, "func(path string) error"}, - {"Unlinkat", Func, 0, "func(dirfd int, path string) error"}, - {"UnmapViewOfFile", Func, 0, ""}, - {"Unmount", Func, 0, "func(target string, flags int) (err error)"}, - {"Unsetenv", Func, 4, "func(key string) error"}, - {"Unshare", Func, 0, "func(flags int) (err error)"}, - {"UserInfo10", Type, 0, ""}, - {"UserInfo10.Comment", Field, 0, ""}, - {"UserInfo10.FullName", Field, 0, ""}, - {"UserInfo10.Name", Field, 0, ""}, - {"UserInfo10.UsrComment", Field, 0, ""}, - {"Ustat", Func, 0, "func(dev int, ubuf *Ustat_t) (err error)"}, - {"Ustat_t", Type, 0, ""}, - {"Ustat_t.Fname", Field, 0, ""}, - {"Ustat_t.Fpack", Field, 0, ""}, - {"Ustat_t.Pad_cgo_0", Field, 0, ""}, - {"Ustat_t.Pad_cgo_1", Field, 0, ""}, - {"Ustat_t.Tfree", Field, 0, ""}, - {"Ustat_t.Tinode", Field, 0, ""}, - {"Utimbuf", Type, 0, ""}, - {"Utimbuf.Actime", Field, 0, ""}, - {"Utimbuf.Modtime", Field, 0, ""}, - {"Utime", Func, 0, "func(path string, buf *Utimbuf) (err error)"}, - {"Utimes", Func, 0, "func(path string, tv []Timeval) (err error)"}, - {"UtimesNano", Func, 1, "func(path string, ts []Timespec) (err error)"}, - {"Utsname", Type, 0, ""}, - {"Utsname.Domainname", Field, 0, ""}, - {"Utsname.Machine", Field, 0, ""}, - {"Utsname.Nodename", Field, 0, ""}, - {"Utsname.Release", Field, 0, ""}, - {"Utsname.Sysname", Field, 0, ""}, - {"Utsname.Version", Field, 0, ""}, - {"VDISCARD", Const, 0, ""}, - {"VDSUSP", Const, 1, ""}, - {"VEOF", Const, 0, ""}, - {"VEOL", Const, 0, ""}, - {"VEOL2", Const, 0, ""}, - {"VERASE", Const, 0, ""}, - {"VERASE2", Const, 1, ""}, - {"VINTR", Const, 0, ""}, - {"VKILL", Const, 0, ""}, - {"VLNEXT", Const, 0, ""}, - {"VMIN", Const, 0, ""}, - {"VQUIT", Const, 0, ""}, - {"VREPRINT", Const, 0, ""}, - {"VSTART", Const, 0, ""}, - {"VSTATUS", Const, 1, ""}, - {"VSTOP", Const, 0, ""}, - {"VSUSP", Const, 0, ""}, - {"VSWTC", Const, 0, ""}, - {"VT0", Const, 1, ""}, - {"VT1", Const, 1, ""}, - {"VTDLY", Const, 1, ""}, - {"VTIME", Const, 0, ""}, - {"VWERASE", Const, 0, ""}, - {"VirtualLock", Func, 0, ""}, - {"VirtualUnlock", Func, 0, ""}, - {"WAIT_ABANDONED", Const, 0, ""}, - {"WAIT_FAILED", Const, 0, ""}, - {"WAIT_OBJECT_0", Const, 0, ""}, - {"WAIT_TIMEOUT", Const, 0, ""}, - {"WALL", Const, 0, ""}, - {"WALLSIG", Const, 1, ""}, - {"WALTSIG", Const, 1, ""}, - {"WCLONE", Const, 0, ""}, - {"WCONTINUED", Const, 0, ""}, - {"WCOREFLAG", Const, 0, ""}, - {"WEXITED", Const, 0, ""}, - {"WLINUXCLONE", Const, 0, ""}, - {"WNOHANG", Const, 0, ""}, - {"WNOTHREAD", Const, 0, ""}, - {"WNOWAIT", Const, 0, ""}, - {"WNOZOMBIE", Const, 1, ""}, - {"WOPTSCHECKED", Const, 1, ""}, - {"WORDSIZE", Const, 0, ""}, - {"WSABuf", Type, 0, ""}, - {"WSABuf.Buf", Field, 0, ""}, - {"WSABuf.Len", Field, 0, ""}, - {"WSACleanup", Func, 0, ""}, - {"WSADESCRIPTION_LEN", Const, 0, ""}, - {"WSAData", Type, 0, ""}, - {"WSAData.Description", Field, 0, ""}, - {"WSAData.HighVersion", Field, 0, ""}, - {"WSAData.MaxSockets", Field, 0, ""}, - {"WSAData.MaxUdpDg", Field, 0, ""}, - {"WSAData.SystemStatus", Field, 0, ""}, - {"WSAData.VendorInfo", Field, 0, ""}, - {"WSAData.Version", Field, 0, ""}, - {"WSAEACCES", Const, 2, ""}, - {"WSAECONNABORTED", Const, 9, ""}, - {"WSAECONNRESET", Const, 3, ""}, - {"WSAENOPROTOOPT", Const, 23, ""}, - {"WSAEnumProtocols", Func, 2, ""}, - {"WSAID_CONNECTEX", Var, 1, ""}, - {"WSAIoctl", Func, 0, ""}, - {"WSAPROTOCOL_LEN", Const, 2, ""}, - {"WSAProtocolChain", Type, 2, ""}, - {"WSAProtocolChain.ChainEntries", Field, 2, ""}, - {"WSAProtocolChain.ChainLen", Field, 2, ""}, - {"WSAProtocolInfo", Type, 2, ""}, - {"WSAProtocolInfo.AddressFamily", Field, 2, ""}, - {"WSAProtocolInfo.CatalogEntryId", Field, 2, ""}, - {"WSAProtocolInfo.MaxSockAddr", Field, 2, ""}, - {"WSAProtocolInfo.MessageSize", Field, 2, ""}, - {"WSAProtocolInfo.MinSockAddr", Field, 2, ""}, - {"WSAProtocolInfo.NetworkByteOrder", Field, 2, ""}, - {"WSAProtocolInfo.Protocol", Field, 2, ""}, - {"WSAProtocolInfo.ProtocolChain", Field, 2, ""}, - {"WSAProtocolInfo.ProtocolMaxOffset", Field, 2, ""}, - {"WSAProtocolInfo.ProtocolName", Field, 2, ""}, - {"WSAProtocolInfo.ProviderFlags", Field, 2, ""}, - {"WSAProtocolInfo.ProviderId", Field, 2, ""}, - {"WSAProtocolInfo.ProviderReserved", Field, 2, ""}, - {"WSAProtocolInfo.SecurityScheme", Field, 2, ""}, - {"WSAProtocolInfo.ServiceFlags1", Field, 2, ""}, - {"WSAProtocolInfo.ServiceFlags2", Field, 2, ""}, - {"WSAProtocolInfo.ServiceFlags3", Field, 2, ""}, - {"WSAProtocolInfo.ServiceFlags4", Field, 2, ""}, - {"WSAProtocolInfo.SocketType", Field, 2, ""}, - {"WSAProtocolInfo.Version", Field, 2, ""}, - {"WSARecv", Func, 0, ""}, - {"WSARecvFrom", Func, 0, ""}, - {"WSASYS_STATUS_LEN", Const, 0, ""}, - {"WSASend", Func, 0, ""}, - {"WSASendTo", Func, 0, ""}, - {"WSASendto", Func, 0, ""}, - {"WSAStartup", Func, 0, ""}, - {"WSTOPPED", Const, 0, ""}, - {"WTRAPPED", Const, 1, ""}, - {"WUNTRACED", Const, 0, ""}, - {"Wait4", Func, 0, "func(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error)"}, - {"WaitForSingleObject", Func, 0, ""}, - {"WaitStatus", Type, 0, ""}, - {"WaitStatus.ExitCode", Field, 0, ""}, - {"Win32FileAttributeData", Type, 0, ""}, - {"Win32FileAttributeData.CreationTime", Field, 0, ""}, - {"Win32FileAttributeData.FileAttributes", Field, 0, ""}, - {"Win32FileAttributeData.FileSizeHigh", Field, 0, ""}, - {"Win32FileAttributeData.FileSizeLow", Field, 0, ""}, - {"Win32FileAttributeData.LastAccessTime", Field, 0, ""}, - {"Win32FileAttributeData.LastWriteTime", Field, 0, ""}, - {"Win32finddata", Type, 0, ""}, - {"Win32finddata.AlternateFileName", Field, 0, ""}, - {"Win32finddata.CreationTime", Field, 0, ""}, - {"Win32finddata.FileAttributes", Field, 0, ""}, - {"Win32finddata.FileName", Field, 0, ""}, - {"Win32finddata.FileSizeHigh", Field, 0, ""}, - {"Win32finddata.FileSizeLow", Field, 0, ""}, - {"Win32finddata.LastAccessTime", Field, 0, ""}, - {"Win32finddata.LastWriteTime", Field, 0, ""}, - {"Win32finddata.Reserved0", Field, 0, ""}, - {"Win32finddata.Reserved1", Field, 0, ""}, - {"Write", Func, 0, "func(fd int, p []byte) (n int, err error)"}, - {"WriteConsole", Func, 1, ""}, - {"WriteFile", Func, 0, ""}, - {"X509_ASN_ENCODING", Const, 0, ""}, - {"XCASE", Const, 0, ""}, - {"XP1_CONNECTIONLESS", Const, 2, ""}, - {"XP1_CONNECT_DATA", Const, 2, ""}, - {"XP1_DISCONNECT_DATA", Const, 2, ""}, - {"XP1_EXPEDITED_DATA", Const, 2, ""}, - {"XP1_GRACEFUL_CLOSE", Const, 2, ""}, - {"XP1_GUARANTEED_DELIVERY", Const, 2, ""}, - {"XP1_GUARANTEED_ORDER", Const, 2, ""}, - {"XP1_IFS_HANDLES", Const, 2, ""}, - {"XP1_MESSAGE_ORIENTED", Const, 2, ""}, - {"XP1_MULTIPOINT_CONTROL_PLANE", Const, 2, ""}, - {"XP1_MULTIPOINT_DATA_PLANE", Const, 2, ""}, - {"XP1_PARTIAL_MESSAGE", Const, 2, ""}, - {"XP1_PSEUDO_STREAM", Const, 2, ""}, - {"XP1_QOS_SUPPORTED", Const, 2, ""}, - {"XP1_SAN_SUPPORT_SDP", Const, 2, ""}, - {"XP1_SUPPORT_BROADCAST", Const, 2, ""}, - {"XP1_SUPPORT_MULTIPOINT", Const, 2, ""}, - {"XP1_UNI_RECV", Const, 2, ""}, - {"XP1_UNI_SEND", Const, 2, ""}, - }, - "syscall/js": { - {"CopyBytesToGo", Func, 0, ""}, - {"CopyBytesToJS", Func, 0, ""}, - {"Error", Type, 0, ""}, - {"Func", Type, 0, ""}, - {"FuncOf", Func, 0, ""}, - {"Global", Func, 0, ""}, - {"Null", Func, 0, ""}, - {"Type", Type, 0, ""}, - {"TypeBoolean", Const, 0, ""}, - {"TypeFunction", Const, 0, ""}, - {"TypeNull", Const, 0, ""}, - {"TypeNumber", Const, 0, ""}, - {"TypeObject", Const, 0, ""}, - {"TypeString", Const, 0, ""}, - {"TypeSymbol", Const, 0, ""}, - {"TypeUndefined", Const, 0, ""}, - {"Undefined", Func, 0, ""}, - {"Value", Type, 0, ""}, - {"ValueError", Type, 0, ""}, - {"ValueOf", Func, 0, ""}, - }, - "testing": { - {"(*B).ArtifactDir", Method, 26, ""}, - {"(*B).Attr", Method, 25, ""}, - {"(*B).Chdir", Method, 24, ""}, - {"(*B).Cleanup", Method, 14, ""}, - {"(*B).Context", Method, 24, ""}, - {"(*B).Elapsed", Method, 20, ""}, - {"(*B).Error", Method, 0, ""}, - {"(*B).Errorf", Method, 0, ""}, - {"(*B).Fail", Method, 0, ""}, - {"(*B).FailNow", Method, 0, ""}, - {"(*B).Failed", Method, 0, ""}, - {"(*B).Fatal", Method, 0, ""}, - {"(*B).Fatalf", Method, 0, ""}, - {"(*B).Helper", Method, 9, ""}, - {"(*B).Log", Method, 0, ""}, - {"(*B).Logf", Method, 0, ""}, - {"(*B).Loop", Method, 24, ""}, - {"(*B).Name", Method, 8, ""}, - {"(*B).Output", Method, 25, ""}, - {"(*B).ReportAllocs", Method, 1, ""}, - {"(*B).ReportMetric", Method, 13, ""}, - {"(*B).ResetTimer", Method, 0, ""}, - {"(*B).Run", Method, 7, ""}, - {"(*B).RunParallel", Method, 3, ""}, - {"(*B).SetBytes", Method, 0, ""}, - {"(*B).SetParallelism", Method, 3, ""}, - {"(*B).Setenv", Method, 17, ""}, - {"(*B).Skip", Method, 1, ""}, - {"(*B).SkipNow", Method, 1, ""}, - {"(*B).Skipf", Method, 1, ""}, - {"(*B).Skipped", Method, 1, ""}, - {"(*B).StartTimer", Method, 0, ""}, - {"(*B).StopTimer", Method, 0, ""}, - {"(*B).TempDir", Method, 15, ""}, - {"(*F).Add", Method, 18, ""}, - {"(*F).ArtifactDir", Method, 26, ""}, - {"(*F).Attr", Method, 25, ""}, - {"(*F).Chdir", Method, 24, ""}, - {"(*F).Cleanup", Method, 18, ""}, - {"(*F).Context", Method, 24, ""}, - {"(*F).Error", Method, 18, ""}, - {"(*F).Errorf", Method, 18, ""}, - {"(*F).Fail", Method, 18, ""}, - {"(*F).FailNow", Method, 18, ""}, - {"(*F).Failed", Method, 18, ""}, - {"(*F).Fatal", Method, 18, ""}, - {"(*F).Fatalf", Method, 18, ""}, - {"(*F).Fuzz", Method, 18, ""}, - {"(*F).Helper", Method, 18, ""}, - {"(*F).Log", Method, 18, ""}, - {"(*F).Logf", Method, 18, ""}, - {"(*F).Name", Method, 18, ""}, - {"(*F).Output", Method, 25, ""}, - {"(*F).Setenv", Method, 18, ""}, - {"(*F).Skip", Method, 18, ""}, - {"(*F).SkipNow", Method, 18, ""}, - {"(*F).Skipf", Method, 18, ""}, - {"(*F).Skipped", Method, 18, ""}, - {"(*F).TempDir", Method, 18, ""}, - {"(*M).Run", Method, 4, ""}, - {"(*PB).Next", Method, 3, ""}, - {"(*T).ArtifactDir", Method, 26, ""}, - {"(*T).Attr", Method, 25, ""}, - {"(*T).Chdir", Method, 24, ""}, - {"(*T).Cleanup", Method, 14, ""}, - {"(*T).Context", Method, 24, ""}, - {"(*T).Deadline", Method, 15, ""}, - {"(*T).Error", Method, 0, ""}, - {"(*T).Errorf", Method, 0, ""}, - {"(*T).Fail", Method, 0, ""}, - {"(*T).FailNow", Method, 0, ""}, - {"(*T).Failed", Method, 0, ""}, - {"(*T).Fatal", Method, 0, ""}, - {"(*T).Fatalf", Method, 0, ""}, - {"(*T).Helper", Method, 9, ""}, - {"(*T).Log", Method, 0, ""}, - {"(*T).Logf", Method, 0, ""}, - {"(*T).Name", Method, 8, ""}, - {"(*T).Output", Method, 25, ""}, - {"(*T).Parallel", Method, 0, ""}, - {"(*T).Run", Method, 7, ""}, - {"(*T).Setenv", Method, 17, ""}, - {"(*T).Skip", Method, 1, ""}, - {"(*T).SkipNow", Method, 1, ""}, - {"(*T).Skipf", Method, 1, ""}, - {"(*T).Skipped", Method, 1, ""}, - {"(*T).TempDir", Method, 15, ""}, - {"(BenchmarkResult).AllocedBytesPerOp", Method, 1, ""}, - {"(BenchmarkResult).AllocsPerOp", Method, 1, ""}, - {"(BenchmarkResult).MemString", Method, 1, ""}, - {"(BenchmarkResult).NsPerOp", Method, 0, ""}, - {"(BenchmarkResult).String", Method, 0, ""}, - {"(TB).ArtifactDir", Method, 26, ""}, - {"(TB).Attr", Method, 25, ""}, - {"(TB).Chdir", Method, 24, ""}, - {"(TB).Cleanup", Method, 14, ""}, - {"(TB).Context", Method, 24, ""}, - {"(TB).Error", Method, 2, ""}, - {"(TB).Errorf", Method, 2, ""}, - {"(TB).Fail", Method, 2, ""}, - {"(TB).FailNow", Method, 2, ""}, - {"(TB).Failed", Method, 2, ""}, - {"(TB).Fatal", Method, 2, ""}, - {"(TB).Fatalf", Method, 2, ""}, - {"(TB).Helper", Method, 9, ""}, - {"(TB).Log", Method, 2, ""}, - {"(TB).Logf", Method, 2, ""}, - {"(TB).Name", Method, 8, ""}, - {"(TB).Output", Method, 25, ""}, - {"(TB).Setenv", Method, 17, ""}, - {"(TB).Skip", Method, 2, ""}, - {"(TB).SkipNow", Method, 2, ""}, - {"(TB).Skipf", Method, 2, ""}, - {"(TB).Skipped", Method, 2, ""}, - {"(TB).TempDir", Method, 15, ""}, - {"AllocsPerRun", Func, 1, "func(runs int, f func()) (avg float64)"}, - {"B", Type, 0, ""}, - {"B.N", Field, 0, ""}, - {"Benchmark", Func, 0, "func(f func(b *B)) BenchmarkResult"}, - {"BenchmarkResult", Type, 0, ""}, - {"BenchmarkResult.Bytes", Field, 0, ""}, - {"BenchmarkResult.Extra", Field, 13, ""}, - {"BenchmarkResult.MemAllocs", Field, 1, ""}, - {"BenchmarkResult.MemBytes", Field, 1, ""}, - {"BenchmarkResult.N", Field, 0, ""}, - {"BenchmarkResult.T", Field, 0, ""}, - {"Cover", Type, 2, ""}, - {"Cover.Blocks", Field, 2, ""}, - {"Cover.Counters", Field, 2, ""}, - {"Cover.CoveredPackages", Field, 2, ""}, - {"Cover.Mode", Field, 2, ""}, - {"CoverBlock", Type, 2, ""}, - {"CoverBlock.Col0", Field, 2, ""}, - {"CoverBlock.Col1", Field, 2, ""}, - {"CoverBlock.Line0", Field, 2, ""}, - {"CoverBlock.Line1", Field, 2, ""}, - {"CoverBlock.Stmts", Field, 2, ""}, - {"CoverMode", Func, 8, "func() string"}, - {"Coverage", Func, 4, "func() float64"}, - {"F", Type, 18, ""}, - {"Init", Func, 13, "func()"}, - {"InternalBenchmark", Type, 0, ""}, - {"InternalBenchmark.F", Field, 0, ""}, - {"InternalBenchmark.Name", Field, 0, ""}, - {"InternalExample", Type, 0, ""}, - {"InternalExample.F", Field, 0, ""}, - {"InternalExample.Name", Field, 0, ""}, - {"InternalExample.Output", Field, 0, ""}, - {"InternalExample.Unordered", Field, 7, ""}, - {"InternalFuzzTarget", Type, 18, ""}, - {"InternalFuzzTarget.Fn", Field, 18, ""}, - {"InternalFuzzTarget.Name", Field, 18, ""}, - {"InternalTest", Type, 0, ""}, - {"InternalTest.F", Field, 0, ""}, - {"InternalTest.Name", Field, 0, ""}, - {"M", Type, 4, ""}, - {"Main", Func, 0, "func(matchString func(pat string, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample)"}, - {"MainStart", Func, 4, "func(deps testDeps, tests []InternalTest, benchmarks []InternalBenchmark, fuzzTargets []InternalFuzzTarget, examples []InternalExample) *M"}, - {"PB", Type, 3, ""}, - {"RegisterCover", Func, 2, "func(c Cover)"}, - {"RunBenchmarks", Func, 0, "func(matchString func(pat string, str string) (bool, error), benchmarks []InternalBenchmark)"}, - {"RunExamples", Func, 0, "func(matchString func(pat string, str string) (bool, error), examples []InternalExample) (ok bool)"}, - {"RunTests", Func, 0, "func(matchString func(pat string, str string) (bool, error), tests []InternalTest) (ok bool)"}, - {"Short", Func, 0, "func() bool"}, - {"T", Type, 0, ""}, - {"Testing", Func, 21, "func() bool"}, - {"Verbose", Func, 1, "func() bool"}, - }, - "testing/cryptotest": { - {"SetGlobalRandom", Func, 26, "func(t *testing.T, seed uint64)"}, - }, - "testing/fstest": { - {"(MapFS).Glob", Method, 16, ""}, - {"(MapFS).Lstat", Method, 25, ""}, - {"(MapFS).Open", Method, 16, ""}, - {"(MapFS).ReadDir", Method, 16, ""}, - {"(MapFS).ReadFile", Method, 16, ""}, - {"(MapFS).ReadLink", Method, 25, ""}, - {"(MapFS).Stat", Method, 16, ""}, - {"(MapFS).Sub", Method, 16, ""}, - {"MapFS", Type, 16, ""}, - {"MapFile", Type, 16, ""}, - {"MapFile.Data", Field, 16, ""}, - {"MapFile.ModTime", Field, 16, ""}, - {"MapFile.Mode", Field, 16, ""}, - {"MapFile.Sys", Field, 16, ""}, - {"TestFS", Func, 16, "func(fsys fs.FS, expected ...string) error"}, - }, - "testing/iotest": { - {"DataErrReader", Func, 0, "func(r io.Reader) io.Reader"}, - {"ErrReader", Func, 16, "func(err error) io.Reader"}, - {"ErrTimeout", Var, 0, ""}, - {"HalfReader", Func, 0, "func(r io.Reader) io.Reader"}, - {"NewReadLogger", Func, 0, "func(prefix string, r io.Reader) io.Reader"}, - {"NewWriteLogger", Func, 0, "func(prefix string, w io.Writer) io.Writer"}, - {"OneByteReader", Func, 0, "func(r io.Reader) io.Reader"}, - {"TestReader", Func, 16, "func(r io.Reader, content []byte) error"}, - {"TimeoutReader", Func, 0, "func(r io.Reader) io.Reader"}, - {"TruncateWriter", Func, 0, "func(w io.Writer, n int64) io.Writer"}, - }, - "testing/quick": { - {"(*CheckEqualError).Error", Method, 0, ""}, - {"(*CheckError).Error", Method, 0, ""}, - {"(Generator).Generate", Method, 0, ""}, - {"(SetupError).Error", Method, 0, ""}, - {"Check", Func, 0, "func(f any, config *Config) error"}, - {"CheckEqual", Func, 0, "func(f any, g any, config *Config) error"}, - {"CheckEqualError", Type, 0, ""}, - {"CheckEqualError.CheckError", Field, 0, ""}, - {"CheckEqualError.Out1", Field, 0, ""}, - {"CheckEqualError.Out2", Field, 0, ""}, - {"CheckError", Type, 0, ""}, - {"CheckError.Count", Field, 0, ""}, - {"CheckError.In", Field, 0, ""}, - {"Config", Type, 0, ""}, - {"Config.MaxCount", Field, 0, ""}, - {"Config.MaxCountScale", Field, 0, ""}, - {"Config.Rand", Field, 0, ""}, - {"Config.Values", Field, 0, ""}, - {"Generator", Type, 0, ""}, - {"SetupError", Type, 0, ""}, - {"Value", Func, 0, "func(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool)"}, - }, - "testing/slogtest": { - {"Run", Func, 22, "func(t *testing.T, newHandler func(*testing.T) slog.Handler, result func(*testing.T) map[string]any)"}, - {"TestHandler", Func, 21, "func(h slog.Handler, results func() []map[string]any) error"}, - }, - "testing/synctest": { - {"Test", Func, 25, "func(t *testing.T, f func(*testing.T))"}, - {"Wait", Func, 25, "func()"}, - }, - "text/scanner": { - {"(*Position).IsValid", Method, 0, ""}, - {"(*Scanner).Init", Method, 0, ""}, - {"(*Scanner).IsValid", Method, 0, ""}, - {"(*Scanner).Next", Method, 0, ""}, - {"(*Scanner).Peek", Method, 0, ""}, - {"(*Scanner).Pos", Method, 0, ""}, - {"(*Scanner).Scan", Method, 0, ""}, - {"(*Scanner).TokenText", Method, 0, ""}, - {"(Position).String", Method, 0, ""}, - {"(Scanner).String", Method, 0, ""}, - {"Char", Const, 0, ""}, - {"Comment", Const, 0, ""}, - {"EOF", Const, 0, ""}, - {"Float", Const, 0, ""}, - {"GoTokens", Const, 0, ""}, - {"GoWhitespace", Const, 0, ""}, - {"Ident", Const, 0, ""}, - {"Int", Const, 0, ""}, - {"Position", Type, 0, ""}, - {"Position.Column", Field, 0, ""}, - {"Position.Filename", Field, 0, ""}, - {"Position.Line", Field, 0, ""}, - {"Position.Offset", Field, 0, ""}, - {"RawString", Const, 0, ""}, - {"ScanChars", Const, 0, ""}, - {"ScanComments", Const, 0, ""}, - {"ScanFloats", Const, 0, ""}, - {"ScanIdents", Const, 0, ""}, - {"ScanInts", Const, 0, ""}, - {"ScanRawStrings", Const, 0, ""}, - {"ScanStrings", Const, 0, ""}, - {"Scanner", Type, 0, ""}, - {"Scanner.Error", Field, 0, ""}, - {"Scanner.ErrorCount", Field, 0, ""}, - {"Scanner.IsIdentRune", Field, 4, ""}, - {"Scanner.Mode", Field, 0, ""}, - {"Scanner.Position", Field, 0, ""}, - {"Scanner.Whitespace", Field, 0, ""}, - {"SkipComments", Const, 0, ""}, - {"String", Const, 0, ""}, - {"TokenString", Func, 0, "func(tok rune) string"}, - }, - "text/tabwriter": { - {"(*Writer).Flush", Method, 0, ""}, - {"(*Writer).Init", Method, 0, ""}, - {"(*Writer).Write", Method, 0, ""}, - {"AlignRight", Const, 0, ""}, - {"Debug", Const, 0, ""}, - {"DiscardEmptyColumns", Const, 0, ""}, - {"Escape", Const, 0, ""}, - {"FilterHTML", Const, 0, ""}, - {"NewWriter", Func, 0, "func(output io.Writer, minwidth int, tabwidth int, padding int, padchar byte, flags uint) *Writer"}, - {"StripEscape", Const, 0, ""}, - {"TabIndent", Const, 0, ""}, - {"Writer", Type, 0, ""}, - }, - "text/template": { - {"(*Template).AddParseTree", Method, 0, ""}, - {"(*Template).Clone", Method, 0, ""}, - {"(*Template).DefinedTemplates", Method, 5, ""}, - {"(*Template).Delims", Method, 0, ""}, - {"(*Template).Execute", Method, 0, ""}, - {"(*Template).ExecuteTemplate", Method, 0, ""}, - {"(*Template).Funcs", Method, 0, ""}, - {"(*Template).Lookup", Method, 0, ""}, - {"(*Template).Name", Method, 0, ""}, - {"(*Template).New", Method, 0, ""}, - {"(*Template).Option", Method, 5, ""}, - {"(*Template).Parse", Method, 0, ""}, - {"(*Template).ParseFS", Method, 16, ""}, - {"(*Template).ParseFiles", Method, 0, ""}, - {"(*Template).ParseGlob", Method, 0, ""}, - {"(*Template).Templates", Method, 0, ""}, - {"(ExecError).Error", Method, 6, ""}, - {"(ExecError).Unwrap", Method, 13, ""}, - {"(Template).Copy", Method, 2, ""}, - {"(Template).ErrorContext", Method, 1, ""}, - {"ExecError", Type, 6, ""}, - {"ExecError.Err", Field, 6, ""}, - {"ExecError.Name", Field, 6, ""}, - {"FuncMap", Type, 0, ""}, - {"HTMLEscape", Func, 0, "func(w io.Writer, b []byte)"}, - {"HTMLEscapeString", Func, 0, "func(s string) string"}, - {"HTMLEscaper", Func, 0, "func(args ...any) string"}, - {"IsTrue", Func, 6, "func(val any) (truth bool, ok bool)"}, - {"JSEscape", Func, 0, "func(w io.Writer, b []byte)"}, - {"JSEscapeString", Func, 0, "func(s string) string"}, - {"JSEscaper", Func, 0, "func(args ...any) string"}, - {"Must", Func, 0, "func(t *Template, err error) *Template"}, - {"New", Func, 0, "func(name string) *Template"}, - {"ParseFS", Func, 16, "func(fsys fs.FS, patterns ...string) (*Template, error)"}, - {"ParseFiles", Func, 0, "func(filenames ...string) (*Template, error)"}, - {"ParseGlob", Func, 0, "func(pattern string) (*Template, error)"}, - {"Template", Type, 0, ""}, - {"Template.Tree", Field, 0, ""}, - {"URLQueryEscaper", Func, 0, "func(args ...any) string"}, - }, - "text/template/parse": { - {"(*ActionNode).Copy", Method, 0, ""}, - {"(*ActionNode).String", Method, 0, ""}, - {"(*BoolNode).Copy", Method, 0, ""}, - {"(*BoolNode).String", Method, 0, ""}, - {"(*BranchNode).Copy", Method, 4, ""}, - {"(*BranchNode).String", Method, 0, ""}, - {"(*BreakNode).Copy", Method, 18, ""}, - {"(*BreakNode).String", Method, 18, ""}, - {"(*ChainNode).Add", Method, 1, ""}, - {"(*ChainNode).Copy", Method, 1, ""}, - {"(*ChainNode).String", Method, 1, ""}, - {"(*CommandNode).Copy", Method, 0, ""}, - {"(*CommandNode).String", Method, 0, ""}, - {"(*CommentNode).Copy", Method, 16, ""}, - {"(*CommentNode).String", Method, 16, ""}, - {"(*ContinueNode).Copy", Method, 18, ""}, - {"(*ContinueNode).String", Method, 18, ""}, - {"(*DotNode).Copy", Method, 0, ""}, - {"(*DotNode).String", Method, 0, ""}, - {"(*DotNode).Type", Method, 0, ""}, - {"(*FieldNode).Copy", Method, 0, ""}, - {"(*FieldNode).String", Method, 0, ""}, - {"(*IdentifierNode).Copy", Method, 0, ""}, - {"(*IdentifierNode).SetPos", Method, 1, ""}, - {"(*IdentifierNode).SetTree", Method, 4, ""}, - {"(*IdentifierNode).String", Method, 0, ""}, - {"(*IfNode).Copy", Method, 0, ""}, - {"(*IfNode).String", Method, 0, ""}, - {"(*ListNode).Copy", Method, 0, ""}, - {"(*ListNode).CopyList", Method, 0, ""}, - {"(*ListNode).String", Method, 0, ""}, - {"(*NilNode).Copy", Method, 1, ""}, - {"(*NilNode).String", Method, 1, ""}, - {"(*NilNode).Type", Method, 1, ""}, - {"(*NumberNode).Copy", Method, 0, ""}, - {"(*NumberNode).String", Method, 0, ""}, - {"(*PipeNode).Copy", Method, 0, ""}, - {"(*PipeNode).CopyPipe", Method, 0, ""}, - {"(*PipeNode).String", Method, 0, ""}, - {"(*RangeNode).Copy", Method, 0, ""}, - {"(*RangeNode).String", Method, 0, ""}, - {"(*StringNode).Copy", Method, 0, ""}, - {"(*StringNode).String", Method, 0, ""}, - {"(*TemplateNode).Copy", Method, 0, ""}, - {"(*TemplateNode).String", Method, 0, ""}, - {"(*TextNode).Copy", Method, 0, ""}, - {"(*TextNode).String", Method, 0, ""}, - {"(*Tree).Copy", Method, 2, ""}, - {"(*Tree).ErrorContext", Method, 1, ""}, - {"(*Tree).Parse", Method, 0, ""}, - {"(*VariableNode).Copy", Method, 0, ""}, - {"(*VariableNode).String", Method, 0, ""}, - {"(*WithNode).Copy", Method, 0, ""}, - {"(*WithNode).String", Method, 0, ""}, - {"(ActionNode).Position", Method, 1, ""}, - {"(ActionNode).Type", Method, 0, ""}, - {"(BoolNode).Position", Method, 1, ""}, - {"(BoolNode).Type", Method, 0, ""}, - {"(BranchNode).Position", Method, 1, ""}, - {"(BranchNode).Type", Method, 0, ""}, - {"(BreakNode).Position", Method, 18, ""}, - {"(BreakNode).Type", Method, 18, ""}, - {"(ChainNode).Position", Method, 1, ""}, - {"(ChainNode).Type", Method, 1, ""}, - {"(CommandNode).Position", Method, 1, ""}, - {"(CommandNode).Type", Method, 0, ""}, - {"(CommentNode).Position", Method, 16, ""}, - {"(CommentNode).Type", Method, 16, ""}, - {"(ContinueNode).Position", Method, 18, ""}, - {"(ContinueNode).Type", Method, 18, ""}, - {"(DotNode).Position", Method, 1, ""}, - {"(FieldNode).Position", Method, 1, ""}, - {"(FieldNode).Type", Method, 0, ""}, - {"(IdentifierNode).Position", Method, 1, ""}, - {"(IdentifierNode).Type", Method, 0, ""}, - {"(IfNode).Position", Method, 1, ""}, - {"(IfNode).Type", Method, 0, ""}, - {"(ListNode).Position", Method, 1, ""}, - {"(ListNode).Type", Method, 0, ""}, - {"(NilNode).Position", Method, 1, ""}, - {"(Node).Copy", Method, 0, ""}, - {"(Node).Position", Method, 1, ""}, - {"(Node).String", Method, 0, ""}, - {"(Node).Type", Method, 0, ""}, - {"(NodeType).Type", Method, 0, ""}, - {"(NumberNode).Position", Method, 1, ""}, - {"(NumberNode).Type", Method, 0, ""}, - {"(PipeNode).Position", Method, 1, ""}, - {"(PipeNode).Type", Method, 0, ""}, - {"(Pos).Position", Method, 1, ""}, - {"(RangeNode).Position", Method, 1, ""}, - {"(RangeNode).Type", Method, 0, ""}, - {"(StringNode).Position", Method, 1, ""}, - {"(StringNode).Type", Method, 0, ""}, - {"(TemplateNode).Position", Method, 1, ""}, - {"(TemplateNode).Type", Method, 0, ""}, - {"(TextNode).Position", Method, 1, ""}, - {"(TextNode).Type", Method, 0, ""}, - {"(VariableNode).Position", Method, 1, ""}, - {"(VariableNode).Type", Method, 0, ""}, - {"(WithNode).Position", Method, 1, ""}, - {"(WithNode).Type", Method, 0, ""}, - {"ActionNode", Type, 0, ""}, - {"ActionNode.Line", Field, 0, ""}, - {"ActionNode.NodeType", Field, 0, ""}, - {"ActionNode.Pipe", Field, 0, ""}, - {"ActionNode.Pos", Field, 1, ""}, - {"BoolNode", Type, 0, ""}, - {"BoolNode.NodeType", Field, 0, ""}, - {"BoolNode.Pos", Field, 1, ""}, - {"BoolNode.True", Field, 0, ""}, - {"BranchNode", Type, 0, ""}, - {"BranchNode.ElseList", Field, 0, ""}, - {"BranchNode.Line", Field, 0, ""}, - {"BranchNode.List", Field, 0, ""}, - {"BranchNode.NodeType", Field, 0, ""}, - {"BranchNode.Pipe", Field, 0, ""}, - {"BranchNode.Pos", Field, 1, ""}, - {"BreakNode", Type, 18, ""}, - {"BreakNode.Line", Field, 18, ""}, - {"BreakNode.NodeType", Field, 18, ""}, - {"BreakNode.Pos", Field, 18, ""}, - {"ChainNode", Type, 1, ""}, - {"ChainNode.Field", Field, 1, ""}, - {"ChainNode.Node", Field, 1, ""}, - {"ChainNode.NodeType", Field, 1, ""}, - {"ChainNode.Pos", Field, 1, ""}, - {"CommandNode", Type, 0, ""}, - {"CommandNode.Args", Field, 0, ""}, - {"CommandNode.NodeType", Field, 0, ""}, - {"CommandNode.Pos", Field, 1, ""}, - {"CommentNode", Type, 16, ""}, - {"CommentNode.NodeType", Field, 16, ""}, - {"CommentNode.Pos", Field, 16, ""}, - {"CommentNode.Text", Field, 16, ""}, - {"ContinueNode", Type, 18, ""}, - {"ContinueNode.Line", Field, 18, ""}, - {"ContinueNode.NodeType", Field, 18, ""}, - {"ContinueNode.Pos", Field, 18, ""}, - {"DotNode", Type, 0, ""}, - {"DotNode.NodeType", Field, 4, ""}, - {"DotNode.Pos", Field, 1, ""}, - {"FieldNode", Type, 0, ""}, - {"FieldNode.Ident", Field, 0, ""}, - {"FieldNode.NodeType", Field, 0, ""}, - {"FieldNode.Pos", Field, 1, ""}, - {"IdentifierNode", Type, 0, ""}, - {"IdentifierNode.Ident", Field, 0, ""}, - {"IdentifierNode.NodeType", Field, 0, ""}, - {"IdentifierNode.Pos", Field, 1, ""}, - {"IfNode", Type, 0, ""}, - {"IfNode.BranchNode", Field, 0, ""}, - {"IsEmptyTree", Func, 0, "func(n Node) bool"}, - {"ListNode", Type, 0, ""}, - {"ListNode.NodeType", Field, 0, ""}, - {"ListNode.Nodes", Field, 0, ""}, - {"ListNode.Pos", Field, 1, ""}, - {"Mode", Type, 16, ""}, - {"New", Func, 0, "func(name string, funcs ...map[string]any) *Tree"}, - {"NewIdentifier", Func, 0, "func(ident string) *IdentifierNode"}, - {"NilNode", Type, 1, ""}, - {"NilNode.NodeType", Field, 4, ""}, - {"NilNode.Pos", Field, 1, ""}, - {"Node", Type, 0, ""}, - {"NodeAction", Const, 0, ""}, - {"NodeBool", Const, 0, ""}, - {"NodeBreak", Const, 18, ""}, - {"NodeChain", Const, 1, ""}, - {"NodeCommand", Const, 0, ""}, - {"NodeComment", Const, 16, ""}, - {"NodeContinue", Const, 18, ""}, - {"NodeDot", Const, 0, ""}, - {"NodeField", Const, 0, ""}, - {"NodeIdentifier", Const, 0, ""}, - {"NodeIf", Const, 0, ""}, - {"NodeList", Const, 0, ""}, - {"NodeNil", Const, 1, ""}, - {"NodeNumber", Const, 0, ""}, - {"NodePipe", Const, 0, ""}, - {"NodeRange", Const, 0, ""}, - {"NodeString", Const, 0, ""}, - {"NodeTemplate", Const, 0, ""}, - {"NodeText", Const, 0, ""}, - {"NodeType", Type, 0, ""}, - {"NodeVariable", Const, 0, ""}, - {"NodeWith", Const, 0, ""}, - {"NumberNode", Type, 0, ""}, - {"NumberNode.Complex128", Field, 0, ""}, - {"NumberNode.Float64", Field, 0, ""}, - {"NumberNode.Int64", Field, 0, ""}, - {"NumberNode.IsComplex", Field, 0, ""}, - {"NumberNode.IsFloat", Field, 0, ""}, - {"NumberNode.IsInt", Field, 0, ""}, - {"NumberNode.IsUint", Field, 0, ""}, - {"NumberNode.NodeType", Field, 0, ""}, - {"NumberNode.Pos", Field, 1, ""}, - {"NumberNode.Text", Field, 0, ""}, - {"NumberNode.Uint64", Field, 0, ""}, - {"Parse", Func, 0, "func(name string, text string, leftDelim string, rightDelim string, funcs ...map[string]any) (map[string]*Tree, error)"}, - {"ParseComments", Const, 16, ""}, - {"PipeNode", Type, 0, ""}, - {"PipeNode.Cmds", Field, 0, ""}, - {"PipeNode.Decl", Field, 0, ""}, - {"PipeNode.IsAssign", Field, 11, ""}, - {"PipeNode.Line", Field, 0, ""}, - {"PipeNode.NodeType", Field, 0, ""}, - {"PipeNode.Pos", Field, 1, ""}, - {"Pos", Type, 1, ""}, - {"RangeNode", Type, 0, ""}, - {"RangeNode.BranchNode", Field, 0, ""}, - {"SkipFuncCheck", Const, 17, ""}, - {"StringNode", Type, 0, ""}, - {"StringNode.NodeType", Field, 0, ""}, - {"StringNode.Pos", Field, 1, ""}, - {"StringNode.Quoted", Field, 0, ""}, - {"StringNode.Text", Field, 0, ""}, - {"TemplateNode", Type, 0, ""}, - {"TemplateNode.Line", Field, 0, ""}, - {"TemplateNode.Name", Field, 0, ""}, - {"TemplateNode.NodeType", Field, 0, ""}, - {"TemplateNode.Pipe", Field, 0, ""}, - {"TemplateNode.Pos", Field, 1, ""}, - {"TextNode", Type, 0, ""}, - {"TextNode.NodeType", Field, 0, ""}, - {"TextNode.Pos", Field, 1, ""}, - {"TextNode.Text", Field, 0, ""}, - {"Tree", Type, 0, ""}, - {"Tree.Mode", Field, 16, ""}, - {"Tree.Name", Field, 0, ""}, - {"Tree.ParseName", Field, 1, ""}, - {"Tree.Root", Field, 0, ""}, - {"VariableNode", Type, 0, ""}, - {"VariableNode.Ident", Field, 0, ""}, - {"VariableNode.NodeType", Field, 0, ""}, - {"VariableNode.Pos", Field, 1, ""}, - {"WithNode", Type, 0, ""}, - {"WithNode.BranchNode", Field, 0, ""}, - }, - "time": { - {"(*Location).String", Method, 0, ""}, - {"(*ParseError).Error", Method, 0, ""}, - {"(*Ticker).Reset", Method, 15, ""}, - {"(*Ticker).Stop", Method, 0, ""}, - {"(*Time).GobDecode", Method, 0, ""}, - {"(*Time).UnmarshalBinary", Method, 2, ""}, - {"(*Time).UnmarshalJSON", Method, 0, ""}, - {"(*Time).UnmarshalText", Method, 2, ""}, - {"(*Timer).Reset", Method, 1, ""}, - {"(*Timer).Stop", Method, 0, ""}, - {"(Duration).Abs", Method, 19, ""}, - {"(Duration).Hours", Method, 0, ""}, - {"(Duration).Microseconds", Method, 13, ""}, - {"(Duration).Milliseconds", Method, 13, ""}, - {"(Duration).Minutes", Method, 0, ""}, - {"(Duration).Nanoseconds", Method, 0, ""}, - {"(Duration).Round", Method, 9, ""}, - {"(Duration).Seconds", Method, 0, ""}, - {"(Duration).String", Method, 0, ""}, - {"(Duration).Truncate", Method, 9, ""}, - {"(Month).String", Method, 0, ""}, - {"(Time).Add", Method, 0, ""}, - {"(Time).AddDate", Method, 0, ""}, - {"(Time).After", Method, 0, ""}, - {"(Time).AppendBinary", Method, 24, ""}, - {"(Time).AppendFormat", Method, 5, ""}, - {"(Time).AppendText", Method, 24, ""}, - {"(Time).Before", Method, 0, ""}, - {"(Time).Clock", Method, 0, ""}, - {"(Time).Compare", Method, 20, ""}, - {"(Time).Date", Method, 0, ""}, - {"(Time).Day", Method, 0, ""}, - {"(Time).Equal", Method, 0, ""}, - {"(Time).Format", Method, 0, ""}, - {"(Time).GoString", Method, 17, ""}, - {"(Time).GobEncode", Method, 0, ""}, - {"(Time).Hour", Method, 0, ""}, - {"(Time).ISOWeek", Method, 0, ""}, - {"(Time).In", Method, 0, ""}, - {"(Time).IsDST", Method, 17, ""}, - {"(Time).IsZero", Method, 0, ""}, - {"(Time).Local", Method, 0, ""}, - {"(Time).Location", Method, 0, ""}, - {"(Time).MarshalBinary", Method, 2, ""}, - {"(Time).MarshalJSON", Method, 0, ""}, - {"(Time).MarshalText", Method, 2, ""}, - {"(Time).Minute", Method, 0, ""}, - {"(Time).Month", Method, 0, ""}, - {"(Time).Nanosecond", Method, 0, ""}, - {"(Time).Round", Method, 1, ""}, - {"(Time).Second", Method, 0, ""}, - {"(Time).String", Method, 0, ""}, - {"(Time).Sub", Method, 0, ""}, - {"(Time).Truncate", Method, 1, ""}, - {"(Time).UTC", Method, 0, ""}, - {"(Time).Unix", Method, 0, ""}, - {"(Time).UnixMicro", Method, 17, ""}, - {"(Time).UnixMilli", Method, 17, ""}, - {"(Time).UnixNano", Method, 0, ""}, - {"(Time).Weekday", Method, 0, ""}, - {"(Time).Year", Method, 0, ""}, - {"(Time).YearDay", Method, 1, ""}, - {"(Time).Zone", Method, 0, ""}, - {"(Time).ZoneBounds", Method, 19, ""}, - {"(Weekday).String", Method, 0, ""}, - {"ANSIC", Const, 0, ""}, - {"After", Func, 0, "func(d Duration) <-chan Time"}, - {"AfterFunc", Func, 0, "func(d Duration, f func()) *Timer"}, - {"April", Const, 0, ""}, - {"August", Const, 0, ""}, - {"Date", Func, 0, "func(year int, month Month, day int, hour int, min int, sec int, nsec int, loc *Location) Time"}, - {"DateOnly", Const, 20, ""}, - {"DateTime", Const, 20, ""}, - {"December", Const, 0, ""}, - {"Duration", Type, 0, ""}, - {"February", Const, 0, ""}, - {"FixedZone", Func, 0, "func(name string, offset int) *Location"}, - {"Friday", Const, 0, ""}, - {"Hour", Const, 0, ""}, - {"January", Const, 0, ""}, - {"July", Const, 0, ""}, - {"June", Const, 0, ""}, - {"Kitchen", Const, 0, ""}, - {"Layout", Const, 17, ""}, - {"LoadLocation", Func, 0, "func(name string) (*Location, error)"}, - {"LoadLocationFromTZData", Func, 10, "func(name string, data []byte) (*Location, error)"}, - {"Local", Var, 0, ""}, - {"Location", Type, 0, ""}, - {"March", Const, 0, ""}, - {"May", Const, 0, ""}, - {"Microsecond", Const, 0, ""}, - {"Millisecond", Const, 0, ""}, - {"Minute", Const, 0, ""}, - {"Monday", Const, 0, ""}, - {"Month", Type, 0, ""}, - {"Nanosecond", Const, 0, ""}, - {"NewTicker", Func, 0, "func(d Duration) *Ticker"}, - {"NewTimer", Func, 0, "func(d Duration) *Timer"}, - {"November", Const, 0, ""}, - {"Now", Func, 0, "func() Time"}, - {"October", Const, 0, ""}, - {"Parse", Func, 0, "func(layout string, value string) (Time, error)"}, - {"ParseDuration", Func, 0, "func(s string) (Duration, error)"}, - {"ParseError", Type, 0, ""}, - {"ParseError.Layout", Field, 0, ""}, - {"ParseError.LayoutElem", Field, 0, ""}, - {"ParseError.Message", Field, 0, ""}, - {"ParseError.Value", Field, 0, ""}, - {"ParseError.ValueElem", Field, 0, ""}, - {"ParseInLocation", Func, 1, "func(layout string, value string, loc *Location) (Time, error)"}, - {"RFC1123", Const, 0, ""}, - {"RFC1123Z", Const, 0, ""}, - {"RFC3339", Const, 0, ""}, - {"RFC3339Nano", Const, 0, ""}, - {"RFC822", Const, 0, ""}, - {"RFC822Z", Const, 0, ""}, - {"RFC850", Const, 0, ""}, - {"RubyDate", Const, 0, ""}, - {"Saturday", Const, 0, ""}, - {"Second", Const, 0, ""}, - {"September", Const, 0, ""}, - {"Since", Func, 0, "func(t Time) Duration"}, - {"Sleep", Func, 0, "func(d Duration)"}, - {"Stamp", Const, 0, ""}, - {"StampMicro", Const, 0, ""}, - {"StampMilli", Const, 0, ""}, - {"StampNano", Const, 0, ""}, - {"Sunday", Const, 0, ""}, - {"Thursday", Const, 0, ""}, - {"Tick", Func, 0, "func(d Duration) <-chan Time"}, - {"Ticker", Type, 0, ""}, - {"Ticker.C", Field, 0, ""}, - {"Time", Type, 0, ""}, - {"TimeOnly", Const, 20, ""}, - {"Timer", Type, 0, ""}, - {"Timer.C", Field, 0, ""}, - {"Tuesday", Const, 0, ""}, - {"UTC", Var, 0, ""}, - {"Unix", Func, 0, "func(sec int64, nsec int64) Time"}, - {"UnixDate", Const, 0, ""}, - {"UnixMicro", Func, 17, "func(usec int64) Time"}, - {"UnixMilli", Func, 17, "func(msec int64) Time"}, - {"Until", Func, 8, "func(t Time) Duration"}, - {"Wednesday", Const, 0, ""}, - {"Weekday", Type, 0, ""}, - }, - "unicode": { - {"(SpecialCase).ToLower", Method, 0, ""}, - {"(SpecialCase).ToTitle", Method, 0, ""}, - {"(SpecialCase).ToUpper", Method, 0, ""}, - {"ASCII_Hex_Digit", Var, 0, ""}, - {"Adlam", Var, 7, ""}, - {"Ahom", Var, 5, ""}, - {"Anatolian_Hieroglyphs", Var, 5, ""}, - {"Arabic", Var, 0, ""}, - {"Armenian", Var, 0, ""}, - {"Avestan", Var, 0, ""}, - {"AzeriCase", Var, 0, ""}, - {"Balinese", Var, 0, ""}, - {"Bamum", Var, 0, ""}, - {"Bassa_Vah", Var, 4, ""}, - {"Batak", Var, 0, ""}, - {"Bengali", Var, 0, ""}, - {"Bhaiksuki", Var, 7, ""}, - {"Bidi_Control", Var, 0, ""}, - {"Bopomofo", Var, 0, ""}, - {"Brahmi", Var, 0, ""}, - {"Braille", Var, 0, ""}, - {"Buginese", Var, 0, ""}, - {"Buhid", Var, 0, ""}, - {"C", Var, 0, ""}, - {"Canadian_Aboriginal", Var, 0, ""}, - {"Carian", Var, 0, ""}, - {"CaseRange", Type, 0, ""}, - {"CaseRange.Delta", Field, 0, ""}, - {"CaseRange.Hi", Field, 0, ""}, - {"CaseRange.Lo", Field, 0, ""}, - {"CaseRanges", Var, 0, ""}, - {"Categories", Var, 0, ""}, - {"CategoryAliases", Var, 25, ""}, - {"Caucasian_Albanian", Var, 4, ""}, - {"Cc", Var, 0, ""}, - {"Cf", Var, 0, ""}, - {"Chakma", Var, 1, ""}, - {"Cham", Var, 0, ""}, - {"Cherokee", Var, 0, ""}, - {"Chorasmian", Var, 16, ""}, - {"Cn", Var, 25, ""}, - {"Co", Var, 0, ""}, - {"Common", Var, 0, ""}, - {"Coptic", Var, 0, ""}, - {"Cs", Var, 0, ""}, - {"Cuneiform", Var, 0, ""}, - {"Cypriot", Var, 0, ""}, - {"Cypro_Minoan", Var, 21, ""}, - {"Cyrillic", Var, 0, ""}, - {"Dash", Var, 0, ""}, - {"Deprecated", Var, 0, ""}, - {"Deseret", Var, 0, ""}, - {"Devanagari", Var, 0, ""}, - {"Diacritic", Var, 0, ""}, - {"Digit", Var, 0, ""}, - {"Dives_Akuru", Var, 16, ""}, - {"Dogra", Var, 13, ""}, - {"Duployan", Var, 4, ""}, - {"Egyptian_Hieroglyphs", Var, 0, ""}, - {"Elbasan", Var, 4, ""}, - {"Elymaic", Var, 14, ""}, - {"Ethiopic", Var, 0, ""}, - {"Extender", Var, 0, ""}, - {"FoldCategory", Var, 0, ""}, - {"FoldScript", Var, 0, ""}, - {"Georgian", Var, 0, ""}, - {"Glagolitic", Var, 0, ""}, - {"Gothic", Var, 0, ""}, - {"Grantha", Var, 4, ""}, - {"GraphicRanges", Var, 0, ""}, - {"Greek", Var, 0, ""}, - {"Gujarati", Var, 0, ""}, - {"Gunjala_Gondi", Var, 13, ""}, - {"Gurmukhi", Var, 0, ""}, - {"Han", Var, 0, ""}, - {"Hangul", Var, 0, ""}, - {"Hanifi_Rohingya", Var, 13, ""}, - {"Hanunoo", Var, 0, ""}, - {"Hatran", Var, 5, ""}, - {"Hebrew", Var, 0, ""}, - {"Hex_Digit", Var, 0, ""}, - {"Hiragana", Var, 0, ""}, - {"Hyphen", Var, 0, ""}, - {"IDS_Binary_Operator", Var, 0, ""}, - {"IDS_Trinary_Operator", Var, 0, ""}, - {"Ideographic", Var, 0, ""}, - {"Imperial_Aramaic", Var, 0, ""}, - {"In", Func, 2, "func(r rune, ranges ...*RangeTable) bool"}, - {"Inherited", Var, 0, ""}, - {"Inscriptional_Pahlavi", Var, 0, ""}, - {"Inscriptional_Parthian", Var, 0, ""}, - {"Is", Func, 0, "func(rangeTab *RangeTable, r rune) bool"}, - {"IsControl", Func, 0, "func(r rune) bool"}, - {"IsDigit", Func, 0, "func(r rune) bool"}, - {"IsGraphic", Func, 0, "func(r rune) bool"}, - {"IsLetter", Func, 0, "func(r rune) bool"}, - {"IsLower", Func, 0, "func(r rune) bool"}, - {"IsMark", Func, 0, "func(r rune) bool"}, - {"IsNumber", Func, 0, "func(r rune) bool"}, - {"IsOneOf", Func, 0, "func(ranges []*RangeTable, r rune) bool"}, - {"IsPrint", Func, 0, "func(r rune) bool"}, - {"IsPunct", Func, 0, "func(r rune) bool"}, - {"IsSpace", Func, 0, "func(r rune) bool"}, - {"IsSymbol", Func, 0, "func(r rune) bool"}, - {"IsTitle", Func, 0, "func(r rune) bool"}, - {"IsUpper", Func, 0, "func(r rune) bool"}, - {"Javanese", Var, 0, ""}, - {"Join_Control", Var, 0, ""}, - {"Kaithi", Var, 0, ""}, - {"Kannada", Var, 0, ""}, - {"Katakana", Var, 0, ""}, - {"Kawi", Var, 21, ""}, - {"Kayah_Li", Var, 0, ""}, - {"Kharoshthi", Var, 0, ""}, - {"Khitan_Small_Script", Var, 16, ""}, - {"Khmer", Var, 0, ""}, - {"Khojki", Var, 4, ""}, - {"Khudawadi", Var, 4, ""}, - {"L", Var, 0, ""}, - {"LC", Var, 25, ""}, - {"Lao", Var, 0, ""}, - {"Latin", Var, 0, ""}, - {"Lepcha", Var, 0, ""}, - {"Letter", Var, 0, ""}, - {"Limbu", Var, 0, ""}, - {"Linear_A", Var, 4, ""}, - {"Linear_B", Var, 0, ""}, - {"Lisu", Var, 0, ""}, - {"Ll", Var, 0, ""}, - {"Lm", Var, 0, ""}, - {"Lo", Var, 0, ""}, - {"Logical_Order_Exception", Var, 0, ""}, - {"Lower", Var, 0, ""}, - {"LowerCase", Const, 0, ""}, - {"Lt", Var, 0, ""}, - {"Lu", Var, 0, ""}, - {"Lycian", Var, 0, ""}, - {"Lydian", Var, 0, ""}, - {"M", Var, 0, ""}, - {"Mahajani", Var, 4, ""}, - {"Makasar", Var, 13, ""}, - {"Malayalam", Var, 0, ""}, - {"Mandaic", Var, 0, ""}, - {"Manichaean", Var, 4, ""}, - {"Marchen", Var, 7, ""}, - {"Mark", Var, 0, ""}, - {"Masaram_Gondi", Var, 10, ""}, - {"MaxASCII", Const, 0, ""}, - {"MaxCase", Const, 0, ""}, - {"MaxLatin1", Const, 0, ""}, - {"MaxRune", Const, 0, ""}, - {"Mc", Var, 0, ""}, - {"Me", Var, 0, ""}, - {"Medefaidrin", Var, 13, ""}, - {"Meetei_Mayek", Var, 0, ""}, - {"Mende_Kikakui", Var, 4, ""}, - {"Meroitic_Cursive", Var, 1, ""}, - {"Meroitic_Hieroglyphs", Var, 1, ""}, - {"Miao", Var, 1, ""}, - {"Mn", Var, 0, ""}, - {"Modi", Var, 4, ""}, - {"Mongolian", Var, 0, ""}, - {"Mro", Var, 4, ""}, - {"Multani", Var, 5, ""}, - {"Myanmar", Var, 0, ""}, - {"N", Var, 0, ""}, - {"Nabataean", Var, 4, ""}, - {"Nag_Mundari", Var, 21, ""}, - {"Nandinagari", Var, 14, ""}, - {"Nd", Var, 0, ""}, - {"New_Tai_Lue", Var, 0, ""}, - {"Newa", Var, 7, ""}, - {"Nko", Var, 0, ""}, - {"Nl", Var, 0, ""}, - {"No", Var, 0, ""}, - {"Noncharacter_Code_Point", Var, 0, ""}, - {"Number", Var, 0, ""}, - {"Nushu", Var, 10, ""}, - {"Nyiakeng_Puachue_Hmong", Var, 14, ""}, - {"Ogham", Var, 0, ""}, - {"Ol_Chiki", Var, 0, ""}, - {"Old_Hungarian", Var, 5, ""}, - {"Old_Italic", Var, 0, ""}, - {"Old_North_Arabian", Var, 4, ""}, - {"Old_Permic", Var, 4, ""}, - {"Old_Persian", Var, 0, ""}, - {"Old_Sogdian", Var, 13, ""}, - {"Old_South_Arabian", Var, 0, ""}, - {"Old_Turkic", Var, 0, ""}, - {"Old_Uyghur", Var, 21, ""}, - {"Oriya", Var, 0, ""}, - {"Osage", Var, 7, ""}, - {"Osmanya", Var, 0, ""}, - {"Other", Var, 0, ""}, - {"Other_Alphabetic", Var, 0, ""}, - {"Other_Default_Ignorable_Code_Point", Var, 0, ""}, - {"Other_Grapheme_Extend", Var, 0, ""}, - {"Other_ID_Continue", Var, 0, ""}, - {"Other_ID_Start", Var, 0, ""}, - {"Other_Lowercase", Var, 0, ""}, - {"Other_Math", Var, 0, ""}, - {"Other_Uppercase", Var, 0, ""}, - {"P", Var, 0, ""}, - {"Pahawh_Hmong", Var, 4, ""}, - {"Palmyrene", Var, 4, ""}, - {"Pattern_Syntax", Var, 0, ""}, - {"Pattern_White_Space", Var, 0, ""}, - {"Pau_Cin_Hau", Var, 4, ""}, - {"Pc", Var, 0, ""}, - {"Pd", Var, 0, ""}, - {"Pe", Var, 0, ""}, - {"Pf", Var, 0, ""}, - {"Phags_Pa", Var, 0, ""}, - {"Phoenician", Var, 0, ""}, - {"Pi", Var, 0, ""}, - {"Po", Var, 0, ""}, - {"Prepended_Concatenation_Mark", Var, 7, ""}, - {"PrintRanges", Var, 0, ""}, - {"Properties", Var, 0, ""}, - {"Ps", Var, 0, ""}, - {"Psalter_Pahlavi", Var, 4, ""}, - {"Punct", Var, 0, ""}, - {"Quotation_Mark", Var, 0, ""}, - {"Radical", Var, 0, ""}, - {"Range16", Type, 0, ""}, - {"Range16.Hi", Field, 0, ""}, - {"Range16.Lo", Field, 0, ""}, - {"Range16.Stride", Field, 0, ""}, - {"Range32", Type, 0, ""}, - {"Range32.Hi", Field, 0, ""}, - {"Range32.Lo", Field, 0, ""}, - {"Range32.Stride", Field, 0, ""}, - {"RangeTable", Type, 0, ""}, - {"RangeTable.LatinOffset", Field, 1, ""}, - {"RangeTable.R16", Field, 0, ""}, - {"RangeTable.R32", Field, 0, ""}, - {"Regional_Indicator", Var, 10, ""}, - {"Rejang", Var, 0, ""}, - {"ReplacementChar", Const, 0, ""}, - {"Runic", Var, 0, ""}, - {"S", Var, 0, ""}, - {"STerm", Var, 0, ""}, - {"Samaritan", Var, 0, ""}, - {"Saurashtra", Var, 0, ""}, - {"Sc", Var, 0, ""}, - {"Scripts", Var, 0, ""}, - {"Sentence_Terminal", Var, 7, ""}, - {"Sharada", Var, 1, ""}, - {"Shavian", Var, 0, ""}, - {"Siddham", Var, 4, ""}, - {"SignWriting", Var, 5, ""}, - {"SimpleFold", Func, 0, "func(r rune) rune"}, - {"Sinhala", Var, 0, ""}, - {"Sk", Var, 0, ""}, - {"Sm", Var, 0, ""}, - {"So", Var, 0, ""}, - {"Soft_Dotted", Var, 0, ""}, - {"Sogdian", Var, 13, ""}, - {"Sora_Sompeng", Var, 1, ""}, - {"Soyombo", Var, 10, ""}, - {"Space", Var, 0, ""}, - {"SpecialCase", Type, 0, ""}, - {"Sundanese", Var, 0, ""}, - {"Syloti_Nagri", Var, 0, ""}, - {"Symbol", Var, 0, ""}, - {"Syriac", Var, 0, ""}, - {"Tagalog", Var, 0, ""}, - {"Tagbanwa", Var, 0, ""}, - {"Tai_Le", Var, 0, ""}, - {"Tai_Tham", Var, 0, ""}, - {"Tai_Viet", Var, 0, ""}, - {"Takri", Var, 1, ""}, - {"Tamil", Var, 0, ""}, - {"Tangsa", Var, 21, ""}, - {"Tangut", Var, 7, ""}, - {"Telugu", Var, 0, ""}, - {"Terminal_Punctuation", Var, 0, ""}, - {"Thaana", Var, 0, ""}, - {"Thai", Var, 0, ""}, - {"Tibetan", Var, 0, ""}, - {"Tifinagh", Var, 0, ""}, - {"Tirhuta", Var, 4, ""}, - {"Title", Var, 0, ""}, - {"TitleCase", Const, 0, ""}, - {"To", Func, 0, "func(_case int, r rune) rune"}, - {"ToLower", Func, 0, "func(r rune) rune"}, - {"ToTitle", Func, 0, "func(r rune) rune"}, - {"ToUpper", Func, 0, "func(r rune) rune"}, - {"Toto", Var, 21, ""}, - {"TurkishCase", Var, 0, ""}, - {"Ugaritic", Var, 0, ""}, - {"Unified_Ideograph", Var, 0, ""}, - {"Upper", Var, 0, ""}, - {"UpperCase", Const, 0, ""}, - {"UpperLower", Const, 0, ""}, - {"Vai", Var, 0, ""}, - {"Variation_Selector", Var, 0, ""}, - {"Version", Const, 0, ""}, - {"Vithkuqi", Var, 21, ""}, - {"Wancho", Var, 14, ""}, - {"Warang_Citi", Var, 4, ""}, - {"White_Space", Var, 0, ""}, - {"Yezidi", Var, 16, ""}, - {"Yi", Var, 0, ""}, - {"Z", Var, 0, ""}, - {"Zanabazar_Square", Var, 10, ""}, - {"Zl", Var, 0, ""}, - {"Zp", Var, 0, ""}, - {"Zs", Var, 0, ""}, - }, - "unicode/utf16": { - {"AppendRune", Func, 20, "func(a []uint16, r rune) []uint16"}, - {"Decode", Func, 0, "func(s []uint16) []rune"}, - {"DecodeRune", Func, 0, "func(r1 rune, r2 rune) rune"}, - {"Encode", Func, 0, "func(s []rune) []uint16"}, - {"EncodeRune", Func, 0, "func(r rune) (r1 rune, r2 rune)"}, - {"IsSurrogate", Func, 0, "func(r rune) bool"}, - {"RuneLen", Func, 23, "func(r rune) int"}, - }, - "unicode/utf8": { - {"AppendRune", Func, 18, "func(p []byte, r rune) []byte"}, - {"DecodeLastRune", Func, 0, "func(p []byte) (r rune, size int)"}, - {"DecodeLastRuneInString", Func, 0, "func(s string) (r rune, size int)"}, - {"DecodeRune", Func, 0, "func(p []byte) (r rune, size int)"}, - {"DecodeRuneInString", Func, 0, "func(s string) (r rune, size int)"}, - {"EncodeRune", Func, 0, "func(p []byte, r rune) int"}, - {"FullRune", Func, 0, "func(p []byte) bool"}, - {"FullRuneInString", Func, 0, "func(s string) bool"}, - {"MaxRune", Const, 0, ""}, - {"RuneCount", Func, 0, "func(p []byte) int"}, - {"RuneCountInString", Func, 0, "func(s string) (n int)"}, - {"RuneError", Const, 0, ""}, - {"RuneLen", Func, 0, "func(r rune) int"}, - {"RuneSelf", Const, 0, ""}, - {"RuneStart", Func, 0, "func(b byte) bool"}, - {"UTFMax", Const, 0, ""}, - {"Valid", Func, 0, "func(p []byte) bool"}, - {"ValidRune", Func, 1, "func(r rune) bool"}, - {"ValidString", Func, 0, "func(s string) bool"}, - }, - "unique": { - {"(Handle).Value", Method, 23, ""}, - {"Handle", Type, 23, ""}, - {"Make", Func, 23, "func[T comparable](value T) Handle[T]"}, - }, - "unsafe": { - {"Add", Func, 0, ""}, - {"Alignof", Func, 0, ""}, - {"Offsetof", Func, 0, ""}, - {"Pointer", Type, 0, ""}, - {"Sizeof", Func, 0, ""}, - {"Slice", Func, 0, ""}, - {"SliceData", Func, 0, ""}, - {"String", Func, 0, ""}, - {"StringData", Func, 0, ""}, - }, - "weak": { - {"(Pointer).Value", Method, 24, ""}, - {"Make", Func, 24, "func[T any](ptr *T) Pointer[T]"}, - {"Pointer", Type, 24, ""}, - }, -} diff --git a/vendor/golang.org/x/tools/internal/stdlib/stdlib.go b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go deleted file mode 100644 index 59a5de36..00000000 --- a/vendor/golang.org/x/tools/internal/stdlib/stdlib.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:generate go run generate.go - -// Package stdlib provides a table of all exported symbols in the -// standard library, along with the version at which they first -// appeared. It also provides the import graph of std packages. -package stdlib - -import ( - "fmt" - "strings" -) - -type Symbol struct { - Name string - Kind Kind - Version Version // Go version that first included the symbol - // Signature provides the type of a function (defined only for Kind=Func). - // Imported types are denoted as pkg.T; pkg is not fully qualified. - // TODO(adonovan): use an unambiguous encoding that is parseable. - // - // Example2: - // func[M ~map[K]V, K comparable, V any](m M) M - // func(fi fs.FileInfo, link string) (*Header, error) - Signature string // if Kind == stdlib.Func -} - -// A Kind indicates the kind of a symbol: -// function, variable, constant, type, and so on. -type Kind int8 - -const ( - Invalid Kind = iota // Example name: - Type // "Buffer" - Func // "Println" - Var // "EOF" - Const // "Pi" - Field // "Point.X" - Method // "(*Buffer).Grow" or "(Reader).Read" -) - -func (kind Kind) String() string { - return [...]string{ - Invalid: "invalid", - Type: "type", - Func: "func", - Var: "var", - Const: "const", - Field: "field", - Method: "method", - }[kind] -} - -// A Version represents a version of Go of the form "go1.%d". -type Version int8 - -// String returns a version string of the form "go1.23", without allocating. -func (v Version) String() string { return versions[v] } - -var versions [30]string // (increase constant as needed) - -func init() { - for i := range versions { - versions[i] = fmt.Sprintf("go1.%d", i) - } -} - -// HasPackage reports whether the specified package path is part of -// the standard library's public API. -func HasPackage(path string) bool { - _, ok := PackageSymbols[path] - return ok -} - -// SplitField splits the field symbol name into type and field -// components. It must be called only on Field symbols. -// -// Example: "File.Package" -> ("File", "Package") -func (sym *Symbol) SplitField() (typename, name string) { - if sym.Kind != Field { - panic("not a field") - } - typename, name, _ = strings.Cut(sym.Name, ".") - return -} - -// SplitMethod splits the method symbol name into pointer, receiver, -// and method components. It must be called only on Method symbols. -// -// Example: "(*Buffer).Grow" -> (true, "Buffer", "Grow") -func (sym *Symbol) SplitMethod() (ptr bool, recv, name string) { - if sym.Kind != Method { - panic("not a method") - } - recv, name, _ = strings.Cut(sym.Name, ".") - recv = recv[len("(") : len(recv)-len(")")] - ptr = recv[0] == '*' - if ptr { - recv = recv[len("*"):] - } - return -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/common.go b/vendor/golang.org/x/tools/internal/typeparams/common.go deleted file mode 100644 index cdae2b8e..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/common.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package typeparams contains common utilities for writing tools that -// interact with generic Go code, as introduced with Go 1.18. It -// supplements the standard library APIs. Notably, the StructuralTerms -// API computes a minimal representation of the structural -// restrictions on a type parameter. -// -// An external version of these APIs is available in the -// golang.org/x/exp/typeparams module. -package typeparams - -import ( - "go/ast" - "go/token" - "go/types" -) - -// UnpackIndexExpr extracts data from AST nodes that represent index -// expressions. -// -// For an ast.IndexExpr, the resulting indices slice will contain exactly one -// index expression. For an ast.IndexListExpr (go1.18+), it may have a variable -// number of index expressions. -// -// For nodes that don't represent index expressions, the first return value of -// UnpackIndexExpr will be nil. -func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) { - switch e := n.(type) { - case *ast.IndexExpr: - return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack - case *ast.IndexListExpr: - return e.X, e.Lbrack, e.Indices, e.Rbrack - } - return nil, token.NoPos, nil, token.NoPos -} - -// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on -// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0 -// will panic. -func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr { - switch len(indices) { - case 0: - panic("empty indices") - case 1: - return &ast.IndexExpr{ - X: x, - Lbrack: lbrack, - Index: indices[0], - Rbrack: rbrack, - } - default: - return &ast.IndexListExpr{ - X: x, - Lbrack: lbrack, - Indices: indices, - Rbrack: rbrack, - } - } -} - -// IsTypeParam reports whether t is a type parameter (or an alias of one). -func IsTypeParam(t types.Type) bool { - _, ok := types.Unalias(t).(*types.TypeParam) - return ok -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go deleted file mode 100644 index 2e05de46..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/coretype.go +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeparams - -import ( - "fmt" - "go/types" -) - -// CoreType returns the core type of T or nil if T does not have a core type. -// -// As of Go1.25, the notion of a core type has been removed from the language spec. -// See https://go.dev/blog/coretypes for more details. -// TODO(mkalil): We should eventually consider removing all uses of CoreType. -func CoreType(T types.Type) types.Type { - U := T.Underlying() - if _, ok := U.(*types.Interface); !ok { - return U // for non-interface types, - } - - terms, err := NormalTerms(U) - if len(terms) == 0 || err != nil { - // len(terms) -> empty type set of interface. - // err != nil => U is invalid, exceeds complexity bounds, or has an empty type set. - return nil // no core type. - } - - U = terms[0].Type().Underlying() - var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying()) - for identical = 1; identical < len(terms); identical++ { - if !types.Identical(U, terms[identical].Type().Underlying()) { - break - } - } - - if identical == len(terms) { - // From the deprecated core types spec: - // "There is a single type U which is the underlying type of all types in the type set of T" - return U - } - ch, ok := U.(*types.Chan) - if !ok { - return nil // no core type as identical < len(terms) and U is not a channel. - } - // From the deprecated core types spec: - // "the type chan E if T contains only bidirectional channels, or the type chan<- E or - // <-chan E depending on the direction of the directional channels present." - for chans := identical; chans < len(terms); chans++ { - curr, ok := terms[chans].Type().Underlying().(*types.Chan) - if !ok { - return nil - } - if !types.Identical(ch.Elem(), curr.Elem()) { - return nil // channel elements are not identical. - } - if ch.Dir() == types.SendRecv { - // ch is bidirectional. We can safely always use curr's direction. - ch = curr - } else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() { - // ch and curr are not bidirectional and not the same direction. - return nil - } - } - return ch -} - -// NormalTerms returns a slice of terms representing the normalized structural -// type restrictions of a type, if any. -// -// For all types other than *types.TypeParam, *types.Interface, and -// *types.Union, this is just a single term with Tilde() == false and -// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see -// below. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration type -// T[P interface{~int; m()}] int the structural restriction of the type -// parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// NormalTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, NormalTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the type is -// invalid, exceeds complexity bounds, or has an empty type set. In the latter -// case, NormalTerms returns ErrEmptyTypeSet. -// -// NormalTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func NormalTerms(T types.Type) ([]*types.Term, error) { - // typeSetOf(T) == typeSetOf(Unalias(T)) - typ := types.Unalias(T) - if named, ok := typ.(*types.Named); ok { - typ = named.Underlying() - } - switch typ := typ.(type) { - case *types.TypeParam: - return StructuralTerms(typ) - case *types.Union: - return UnionTermSet(typ) - case *types.Interface: - return InterfaceTermSet(typ) - default: - return []*types.Term{types.NewTerm(false, T)}, nil - } -} - -// Deref returns the type of the variable pointed to by t, -// if t's core type is a pointer; otherwise it returns t. -// -// Do not assume that Deref(T)==T implies T is not a pointer: -// consider "type T *T", for example. -// -// TODO(adonovan): ideally this would live in typesinternal, but that -// creates an import cycle. Move there when we melt this package down. -func Deref(t types.Type) types.Type { - if ptr, ok := CoreType(t).(*types.Pointer); ok { - return ptr.Elem() - } - return t -} - -// MustDeref returns the type of the variable pointed to by t. -// It panics if t's core type is not a pointer. -// -// TODO(adonovan): ideally this would live in typesinternal, but that -// creates an import cycle. Move there when we melt this package down. -func MustDeref(t types.Type) types.Type { - if ptr, ok := CoreType(t).(*types.Pointer); ok { - return ptr.Elem() - } - panic(fmt.Sprintf("%v is not a pointer", t)) -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/free.go b/vendor/golang.org/x/tools/internal/typeparams/free.go deleted file mode 100644 index 4c391876..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/free.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2024 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 typeparams - -import ( - "go/types" -) - -// Free is a memoization of the set of free type parameters within a -// type. It makes a sequence of calls to [Free.Has] for overlapping -// types more efficient. The zero value is ready for use. -// -// NOTE: Adapted from go/types/infer.go. If it is later exported, factor. -type Free struct { - seen map[types.Type]bool -} - -// Has reports whether the specified type has a free type parameter. -func (w *Free) Has(typ types.Type) (res bool) { - // detect cycles - if x, ok := w.seen[typ]; ok { - return x - } - if w.seen == nil { - w.seen = make(map[types.Type]bool) - } - w.seen[typ] = false - defer func() { - w.seen[typ] = res - }() - - switch t := typ.(type) { - case nil, *types.Basic: // TODO(gri) should nil be handled here? - break - - case *types.Alias: - if t.TypeParams().Len() > t.TypeArgs().Len() { - return true // This is an uninstantiated Alias. - } - // The expansion of an alias can have free type parameters, - // whether or not the alias itself has type parameters: - // - // func _[K comparable]() { - // type Set = map[K]bool // free(Set) = {K} - // type MapTo[V] = map[K]V // free(Map[foo]) = {V} - // } - // - // So, we must Unalias. - return w.Has(types.Unalias(t)) - - case *types.Array: - return w.Has(t.Elem()) - - case *types.Slice: - return w.Has(t.Elem()) - - case *types.Struct: - for i, n := 0, t.NumFields(); i < n; i++ { - if w.Has(t.Field(i).Type()) { - return true - } - } - - case *types.Pointer: - return w.Has(t.Elem()) - - case *types.Tuple: - n := t.Len() - for i := range n { - if w.Has(t.At(i).Type()) { - return true - } - } - - case *types.Signature: - // t.tparams may not be nil if we are looking at a signature - // of a generic function type (or an interface method) that is - // part of the type we're testing. We don't care about these type - // parameters. - // Similarly, the receiver of a method may declare (rather than - // use) type parameters, we don't care about those either. - // Thus, we only need to look at the input and result parameters. - return w.Has(t.Params()) || w.Has(t.Results()) - - case *types.Interface: - for i, n := 0, t.NumMethods(); i < n; i++ { - if w.Has(t.Method(i).Type()) { - return true - } - } - terms, err := InterfaceTermSet(t) - if err != nil { - return false // ill typed - } - for _, term := range terms { - if w.Has(term.Type()) { - return true - } - } - - case *types.Map: - return w.Has(t.Key()) || w.Has(t.Elem()) - - case *types.Chan: - return w.Has(t.Elem()) - - case *types.Named: - args := t.TypeArgs() - if params := t.TypeParams(); params.Len() > args.Len() { - return true // this is an uninstantiated named type. - } - for i, n := 0, args.Len(); i < n; i++ { - if w.Has(args.At(i)) { - return true - } - } - return w.Has(t.Underlying()) // recurse for types local to parameterized functions - - case *types.TypeParam: - return true - - default: - panic(t) // unreachable - } - - return false -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/vendor/golang.org/x/tools/internal/typeparams/normalize.go deleted file mode 100644 index 8d13f121..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/normalize.go +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeparams - -import ( - "errors" - "fmt" - "go/types" - "os" - "strings" -) - -//go:generate go run copytermlist.go - -const debug = false - -var ErrEmptyTypeSet = errors.New("empty type set") - -// StructuralTerms returns a slice of terms representing the normalized -// structural type restrictions of a type parameter, if any. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration -// -// type T[P interface{~int; m()}] int -// -// the structural restriction of the type parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// StructuralTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, StructuralTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the -// constraint interface is invalid, exceeds complexity bounds, or has an empty -// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet. -// -// StructuralTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) { - constraint := tparam.Constraint() - if constraint == nil { - return nil, fmt.Errorf("%s has nil constraint", tparam) - } - iface, _ := constraint.Underlying().(*types.Interface) - if iface == nil { - return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) - } - return InterfaceTermSet(iface) -} - -// InterfaceTermSet computes the normalized terms for a constraint interface, -// returning an error if the term set cannot be computed or is empty. In the -// latter case, the error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) { - return computeTermSet(iface) -} - -// UnionTermSet computes the normalized terms for a union, returning an error -// if the term set cannot be computed or is empty. In the latter case, the -// error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func UnionTermSet(union *types.Union) ([]*types.Term, error) { - return computeTermSet(union) -} - -func computeTermSet(typ types.Type) ([]*types.Term, error) { - tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) - if err != nil { - return nil, err - } - if tset.terms.isEmpty() { - return nil, ErrEmptyTypeSet - } - if tset.terms.isAll() { - return nil, nil - } - var terms []*types.Term - for _, term := range tset.terms { - terms = append(terms, types.NewTerm(term.tilde, term.typ)) - } - return terms, nil -} - -// A termSet holds the normalized set of terms for a given type. -// -// The name termSet is intentionally distinct from 'type set': a type set is -// all types that implement a type (and includes method restrictions), whereas -// a term set just represents the structural restrictions on a type. -type termSet struct { - complete bool - terms termlist -} - -func indentf(depth int, format string, args ...any) { - fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...) -} - -func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { - if t == nil { - panic("nil type") - } - - if debug { - indentf(depth, "%s", t.String()) - defer func() { - if err != nil { - indentf(depth, "=> %s", err) - } else { - indentf(depth, "=> %s", res.terms.String()) - } - }() - } - - const maxTermCount = 100 - if tset, ok := seen[t]; ok { - if !tset.complete { - return nil, fmt.Errorf("cycle detected in the declaration of %s", t) - } - return tset, nil - } - - // Mark the current type as seen to avoid infinite recursion. - tset := new(termSet) - defer func() { - tset.complete = true - }() - seen[t] = tset - - switch u := t.Underlying().(type) { - case *types.Interface: - // The term set of an interface is the intersection of the term sets of its - // embedded types. - tset.terms = allTermlist - for embedded := range u.EmbeddedTypes() { - if _, ok := embedded.Underlying().(*types.TypeParam); ok { - return nil, fmt.Errorf("invalid embedded type %T", embedded) - } - tset2, err := computeTermSetInternal(embedded, seen, depth+1) - if err != nil { - return nil, err - } - tset.terms = tset.terms.intersect(tset2.terms) - } - case *types.Union: - // The term set of a union is the union of term sets of its terms. - tset.terms = nil - for t := range u.Terms() { - var terms termlist - switch t.Type().Underlying().(type) { - case *types.Interface: - tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) - if err != nil { - return nil, err - } - terms = tset2.terms - case *types.TypeParam, *types.Union: - // A stand-alone type parameter or union is not permitted as union - // term. - return nil, fmt.Errorf("invalid union term %T", t) - default: - if t.Type() == types.Typ[types.Invalid] { - continue - } - terms = termlist{{t.Tilde(), t.Type()}} - } - tset.terms = tset.terms.union(terms) - if len(tset.terms) > maxTermCount { - return nil, fmt.Errorf("exceeded max term count %d", maxTermCount) - } - } - case *types.TypeParam: - panic("unreachable") - default: - // For all other types, the term set is just a single non-tilde term - // holding the type itself. - if u != types.Typ[types.Invalid] { - tset.terms = termlist{{false, t}} - } - } - return tset, nil -} - -// under is a facade for the go/types internal function of the same name. It is -// used by typeterm.go. -func under(t types.Type) types.Type { - return t.Underlying() -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/termlist.go b/vendor/golang.org/x/tools/internal/typeparams/termlist.go deleted file mode 100644 index 9bc29143..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/termlist.go +++ /dev/null @@ -1,169 +0,0 @@ -// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT. -// Source: ../../cmd/compile/internal/types2/termlist.go - -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import ( - "go/types" - "strings" -) - -// A termlist represents the type set represented by the union -// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn. -// A termlist is in normal form if all terms are disjoint. -// termlist operations don't require the operands to be in -// normal form. -type termlist []*term - -// allTermlist represents the set of all types. -// It is in normal form. -var allTermlist = termlist{new(term)} - -// termSep is the separator used between individual terms. -const termSep = " | " - -// String prints the termlist exactly (without normalization). -func (xl termlist) String() string { - if len(xl) == 0 { - return "∅" - } - var buf strings.Builder - for i, x := range xl { - if i > 0 { - buf.WriteString(termSep) - } - buf.WriteString(x.String()) - } - return buf.String() -} - -// isEmpty reports whether the termlist xl represents the empty set of types. -func (xl termlist) isEmpty() bool { - // If there's a non-nil term, the entire list is not empty. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil { - return false - } - } - return true -} - -// isAll reports whether the termlist xl represents the set of all types. -func (xl termlist) isAll() bool { - // If there's a 𝓤 term, the entire list is 𝓤. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil && x.typ == nil { - return true - } - } - return false -} - -// norm returns the normal form of xl. -func (xl termlist) norm() termlist { - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - used := make([]bool, len(xl)) - var rl termlist - for i, xi := range xl { - if xi == nil || used[i] { - continue - } - for j := i + 1; j < len(xl); j++ { - xj := xl[j] - if xj == nil || used[j] { - continue - } - if u1, u2 := xi.union(xj); u2 == nil { - // If we encounter a 𝓤 term, the entire list is 𝓤. - // Exit early. - // (Note that this is not just an optimization; - // if we continue, we may end up with a 𝓤 term - // and other terms and the result would not be - // in normal form.) - if u1.typ == nil { - return allTermlist - } - xi = u1 - used[j] = true // xj is now unioned into xi - ignore it in future iterations - } - } - rl = append(rl, xi) - } - return rl -} - -// union returns the union xl ∪ yl. -func (xl termlist) union(yl termlist) termlist { - return append(xl, yl...).norm() -} - -// intersect returns the intersection xl ∩ yl. -func (xl termlist) intersect(yl termlist) termlist { - if xl.isEmpty() || yl.isEmpty() { - return nil - } - - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - var rl termlist - for _, x := range xl { - for _, y := range yl { - if r := x.intersect(y); r != nil { - rl = append(rl, r) - } - } - } - return rl.norm() -} - -// equal reports whether xl and yl represent the same type set. -func (xl termlist) equal(yl termlist) bool { - // TODO(gri) this should be more efficient - return xl.subsetOf(yl) && yl.subsetOf(xl) -} - -// includes reports whether t ∈ xl. -func (xl termlist) includes(t types.Type) bool { - for _, x := range xl { - if x.includes(t) { - return true - } - } - return false -} - -// supersetOf reports whether y ⊆ xl. -func (xl termlist) supersetOf(y *term) bool { - for _, x := range xl { - if y.subsetOf(x) { - return true - } - } - return false -} - -// subsetOf reports whether xl ⊆ yl. -func (xl termlist) subsetOf(yl termlist) bool { - if yl.isEmpty() { - return xl.isEmpty() - } - - // each term x of xl must be a subset of yl - for _, x := range xl { - if !yl.supersetOf(x) { - return false // x is not a subset yl - } - } - return true -} diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go b/vendor/golang.org/x/tools/internal/typeparams/typeterm.go deleted file mode 100644 index fa758cdc..00000000 --- a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go +++ /dev/null @@ -1,172 +0,0 @@ -// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT. -// Source: ../../cmd/compile/internal/types2/typeterm.go - -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import "go/types" - -// A term describes elementary type sets: -// -// ∅: (*term)(nil) == ∅ // set of no types (empty set) -// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse) -// T: &term{false, T} == {T} // set of type T -// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t -type term struct { - tilde bool // valid if typ != nil - typ types.Type -} - -func (x *term) String() string { - switch { - case x == nil: - return "∅" - case x.typ == nil: - return "𝓤" - case x.tilde: - return "~" + x.typ.String() - default: - return x.typ.String() - } -} - -// equal reports whether x and y represent the same type set. -func (x *term) equal(y *term) bool { - // easy cases - switch { - case x == nil || y == nil: - return x == y - case x.typ == nil || y.typ == nil: - return x.typ == y.typ - } - // ∅ ⊂ x, y ⊂ 𝓤 - - return x.tilde == y.tilde && types.Identical(x.typ, y.typ) -} - -// union returns the union x ∪ y: zero, one, or two non-nil terms. -func (x *term) union(y *term) (_, _ *term) { - // easy cases - switch { - case x == nil && y == nil: - return nil, nil // ∅ ∪ ∅ == ∅ - case x == nil: - return y, nil // ∅ ∪ y == y - case y == nil: - return x, nil // x ∪ ∅ == x - case x.typ == nil: - return x, nil // 𝓤 ∪ y == 𝓤 - case y.typ == nil: - return y, nil // x ∪ 𝓤 == 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return x, y // x ∪ y == (x, y) if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∪ ~t == ~t - // ~t ∪ T == ~t - // T ∪ ~t == ~t - // T ∪ T == T - if x.tilde || !y.tilde { - return x, nil - } - return y, nil -} - -// intersect returns the intersection x ∩ y. -func (x *term) intersect(y *term) *term { - // easy cases - switch { - case x == nil || y == nil: - return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅ - case x.typ == nil: - return y // 𝓤 ∩ y == y - case y.typ == nil: - return x // x ∩ 𝓤 == x - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return nil // x ∩ y == ∅ if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∩ ~t == ~t - // ~t ∩ T == T - // T ∩ ~t == T - // T ∩ T == T - if !x.tilde || y.tilde { - return x - } - return y -} - -// includes reports whether t ∈ x. -func (x *term) includes(t types.Type) bool { - // easy cases - switch { - case x == nil: - return false // t ∈ ∅ == false - case x.typ == nil: - return true // t ∈ 𝓤 == true - } - // ∅ ⊂ x ⊂ 𝓤 - - u := t - if x.tilde { - u = under(u) - } - return types.Identical(x.typ, u) -} - -// subsetOf reports whether x ⊆ y. -func (x *term) subsetOf(y *term) bool { - // easy cases - switch { - case x == nil: - return true // ∅ ⊆ y == true - case y == nil: - return false // x ⊆ ∅ == false since x != ∅ - case y.typ == nil: - return true // x ⊆ 𝓤 == true - case x.typ == nil: - return false // 𝓤 ⊆ y == false since y != 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return false // x ⊆ y == false if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ⊆ ~t == true - // ~t ⊆ T == false - // T ⊆ ~t == true - // T ⊆ T == true - return !x.tilde || y.tilde -} - -// disjoint reports whether x ∩ y == ∅. -// x.typ and y.typ must not be nil. -func (x *term) disjoint(y *term) bool { - if debug && (x.typ == nil || y.typ == nil) { - panic("invalid argument(s)") - } - ux := x.typ - if y.tilde { - ux = under(ux) - } - uy := y.typ - if x.tilde { - uy = under(uy) - } - return !types.Identical(ux, uy) -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go b/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go deleted file mode 100644 index 7ebe9768..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -import ( - "fmt" - "go/ast" - "go/types" - _ "unsafe" // for go:linkname hack -) - -// CallKind describes the function position of an [*ast.CallExpr]. -type CallKind int - -const ( - CallStatic CallKind = iota // static call to known function - CallInterface // dynamic call through an interface method - CallDynamic // dynamic call of a func value - CallBuiltin // call to a builtin function - CallConversion // a conversion (not a call) -) - -var callKindNames = []string{ - "CallStatic", - "CallInterface", - "CallDynamic", - "CallBuiltin", - "CallConversion", -} - -func (k CallKind) String() string { - if i := int(k); i >= 0 && i < len(callKindNames) { - return callKindNames[i] - } - return fmt.Sprintf("typeutil.CallKind(%d)", k) -} - -// ClassifyCall classifies the function position of a call expression ([*ast.CallExpr]). -// It distinguishes among true function calls, calls to builtins, and type conversions, -// and further classifies function calls as static calls (where the function is known), -// dynamic interface calls, and other dynamic calls. -// -// For the declarations: -// -// func f() {} -// func g[T any]() {} -// var v func() -// var s []func() -// type I interface { M() } -// var i I -// -// ClassifyCall returns the following: -// -// f() CallStatic -// g[int]() CallStatic -// i.M() CallInterface -// min(1, 2) CallBuiltin -// v() CallDynamic -// s[0]() CallDynamic -// int(x) CallConversion -// []byte("") CallConversion -func ClassifyCall(info *types.Info, call *ast.CallExpr) CallKind { - if info.Types == nil { - panic("ClassifyCall: info.Types is nil") - } - tv := info.Types[call.Fun] - if tv.IsType() { - return CallConversion - } - if tv.IsBuiltin() { - return CallBuiltin - } - obj := info.Uses[UsedIdent(info, call.Fun)] - // Classify the call by the type of the object, if any. - switch obj := obj.(type) { - case *types.Func: - if interfaceMethod(obj) { - return CallInterface - } - return CallStatic - default: - return CallDynamic - } -} - -// UsedIdent returns the identifier such that info.Uses[UsedIdent(info, e)] -// is the [types.Object] used by e, if any. -// -// If e is one of various forms of reference: -// -// f, c, v, T lexical reference -// pkg.X qualified identifier -// f[T] or pkg.F[K,V] instantiations of the above kinds -// expr.f field or method value selector -// T.f method expression selector -// -// UsedIdent returns the identifier whose is associated value in [types.Info.Uses] -// is the object to which it refers. -// -// For the declarations: -// -// func F[T any] {...} -// type I interface { M() } -// var ( -// x int -// s struct { f int } -// a []int -// i I -// ) -// -// UsedIdent returns the following: -// -// Expr UsedIdent -// x x -// s.f f -// F[int] F -// i.M M -// I.M M -// min min -// int int -// 1 nil -// a[0] nil -// []byte nil -// -// Note: if e is an instantiated function or method, UsedIdent returns -// the corresponding generic function or method on the generic type. -func UsedIdent(info *types.Info, e ast.Expr) *ast.Ident { - return usedIdent(info, e) -} - -//go:linkname usedIdent golang.org/x/tools/go/types/typeutil.usedIdent -func usedIdent(info *types.Info, e ast.Expr) *ast.Ident - -//go:linkname interfaceMethod golang.org/x/tools/go/types/typeutil.interfaceMethod -func interfaceMethod(f *types.Func) bool diff --git a/vendor/golang.org/x/tools/internal/typesinternal/element.go b/vendor/golang.org/x/tools/internal/typesinternal/element.go deleted file mode 100644 index 5fe4d8ab..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/element.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -import ( - "fmt" - "go/types" - - "golang.org/x/tools/go/types/typeutil" -) - -// ForEachElement calls f for type T and each type reachable from its -// type through reflection. It does this by recursively stripping off -// type constructors; in addition, for each named type N, the type *N -// is added to the result as it may have additional methods. -// -// The caller must provide an initially empty set used to de-duplicate -// identical types, potentially across multiple calls to ForEachElement. -// (Its final value holds all the elements seen, matching the arguments -// passed to f.) -// -// TODO(adonovan): share/harmonize with go/callgraph/rta. -func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T types.Type, f func(types.Type)) { - var visit func(T types.Type, skip bool) - visit = func(T types.Type, skip bool) { - if !skip { - if seen, _ := rtypes.Set(T, true).(bool); seen { - return // de-dup - } - - f(T) // notify caller of new element type - } - - // Recursion over signatures of each method. - tmset := msets.MethodSet(T) - for method := range tmset.Methods() { - sig := method.Type().(*types.Signature) - // It is tempting to call visit(sig, false) - // but, as noted in golang.org/cl/65450043, - // the Signature.Recv field is ignored by - // types.Identical and typeutil.Map, which - // is confusing at best. - // - // More importantly, the true signature rtype - // reachable from a method using reflection - // has no receiver but an extra ordinary parameter. - // For the Read method of io.Reader we want: - // func(Reader, []byte) (int, error) - // but here sig is: - // func([]byte) (int, error) - // with .Recv = Reader (though it is hard to - // notice because it doesn't affect Signature.String - // or types.Identical). - // - // TODO(adonovan): construct and visit the correct - // non-method signature with an extra parameter - // (though since unnamed func types have no methods - // there is essentially no actual demand for this). - // - // TODO(adonovan): document whether or not it is - // safe to skip non-exported methods (as RTA does). - visit(sig.Params(), true) // skip the Tuple - visit(sig.Results(), true) // skip the Tuple - } - - switch T := T.(type) { - case *types.Alias: - visit(types.Unalias(T), skip) // emulates the pre-Alias behavior - - case *types.Basic: - // nop - - case *types.Interface: - // nop---handled by recursion over method set. - - case *types.Pointer: - visit(T.Elem(), false) - - case *types.Slice: - visit(T.Elem(), false) - - case *types.Chan: - visit(T.Elem(), false) - - case *types.Map: - visit(T.Key(), false) - visit(T.Elem(), false) - - case *types.Signature: - if T.Recv() != nil { - panic(fmt.Sprintf("Signature %s has Recv %s", T, T.Recv())) - } - visit(T.Params(), true) // skip the Tuple - visit(T.Results(), true) // skip the Tuple - - case *types.Named: - // A pointer-to-named type can be derived from a named - // type via reflection. It may have methods too. - visit(types.NewPointer(T), false) - - // Consider 'type T struct{S}' where S has methods. - // Reflection provides no way to get from T to struct{S}, - // only to S, so the method set of struct{S} is unwanted, - // so set 'skip' flag during recursion. - visit(T.Underlying(), true) // skip the unnamed type - - case *types.Array: - visit(T.Elem(), false) - - case *types.Struct: - for i, n := 0, T.NumFields(); i < n; i++ { - // TODO(adonovan): document whether or not - // it is safe to skip non-exported fields. - visit(T.Field(i).Type(), false) - } - - case *types.Tuple: - for i, n := 0, T.Len(); i < n; i++ { - visit(T.At(i).Type(), false) - } - - case *types.TypeParam, *types.Union: - // forEachReachable must not be called on parameterized types. - panic(T) - - default: - panic(T) - } - } - visit(T, false) -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go deleted file mode 100644 index 235a6def..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go +++ /dev/null @@ -1,1560 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -//go:generate stringer -type=ErrorCode - -type ErrorCode int - -// This file defines the error codes that can be produced during type-checking. -// Collectively, these codes provide an identifier that may be used to -// implement special handling for certain types of errors. -// -// Error codes should be fine-grained enough that the exact nature of the error -// can be easily determined, but coarse enough that they are not an -// implementation detail of the type checking algorithm. As a rule-of-thumb, -// errors should be considered equivalent if there is a theoretical refactoring -// of the type checker in which they are emitted in exactly one place. For -// example, the type checker emits different error messages for "too many -// arguments" and "too few arguments", but one can imagine an alternative type -// checker where this check instead just emits a single "wrong number of -// arguments", so these errors should have the same code. -// -// Error code names should be as brief as possible while retaining accuracy and -// distinctiveness. In most cases names should start with an adjective -// describing the nature of the error (e.g. "invalid", "unused", "misplaced"), -// and end with a noun identifying the relevant language object. For example, -// "DuplicateDecl" or "InvalidSliceExpr". For brevity, naming follows the -// convention that "bad" implies a problem with syntax, and "invalid" implies a -// problem with types. - -const ( - // InvalidSyntaxTree occurs if an invalid syntax tree is provided - // to the type checker. It should never happen. - InvalidSyntaxTree ErrorCode = -1 -) - -const ( - _ ErrorCode = iota - - // Test is reserved for errors that only apply while in self-test mode. - Test - - /* package names */ - - // BlankPkgName occurs when a package name is the blank identifier "_". - // - // Per the spec: - // "The PackageName must not be the blank identifier." - BlankPkgName - - // MismatchedPkgName occurs when a file's package name doesn't match the - // package name already established by other files. - MismatchedPkgName - - // InvalidPkgUse occurs when a package identifier is used outside of a - // selector expression. - // - // Example: - // import "fmt" - // - // var _ = fmt - InvalidPkgUse - - /* imports */ - - // BadImportPath occurs when an import path is not valid. - BadImportPath - - // BrokenImport occurs when importing a package fails. - // - // Example: - // import "amissingpackage" - BrokenImport - - // ImportCRenamed occurs when the special import "C" is renamed. "C" is a - // pseudo-package, and must not be renamed. - // - // Example: - // import _ "C" - ImportCRenamed - - // UnusedImport occurs when an import is unused. - // - // Example: - // import "fmt" - // - // func main() {} - UnusedImport - - /* initialization */ - - // InvalidInitCycle occurs when an invalid cycle is detected within the - // initialization graph. - // - // Example: - // var x int = f() - // - // func f() int { return x } - InvalidInitCycle - - /* decls */ - - // DuplicateDecl occurs when an identifier is declared multiple times. - // - // Example: - // var x = 1 - // var x = 2 - DuplicateDecl - - // InvalidDeclCycle occurs when a declaration cycle is not valid. - // - // Example: - // import "unsafe" - // - // type T struct { - // a [n]int - // } - // - // var n = unsafe.Sizeof(T{}) - InvalidDeclCycle - - // InvalidTypeCycle occurs when a cycle in type definitions results in a - // type that is not well-defined. - // - // Example: - // import "unsafe" - // - // type T [unsafe.Sizeof(T{})]int - InvalidTypeCycle - - /* decls > const */ - - // InvalidConstInit occurs when a const declaration has a non-constant - // initializer. - // - // Example: - // var x int - // const _ = x - InvalidConstInit - - // InvalidConstVal occurs when a const value cannot be converted to its - // target type. - // - // TODO(findleyr): this error code and example are not very clear. Consider - // removing it. - // - // Example: - // const _ = 1 << "hello" - InvalidConstVal - - // InvalidConstType occurs when the underlying type in a const declaration - // is not a valid constant type. - // - // Example: - // const c *int = 4 - InvalidConstType - - /* decls > var (+ other variable assignment codes) */ - - // UntypedNilUse occurs when the predeclared (untyped) value nil is used to - // initialize a variable declared without an explicit type. - // - // Example: - // var x = nil - UntypedNilUse - - // WrongAssignCount occurs when the number of values on the right-hand side - // of an assignment or initialization expression does not match the number - // of variables on the left-hand side. - // - // Example: - // var x = 1, 2 - WrongAssignCount - - // UnassignableOperand occurs when the left-hand side of an assignment is - // not assignable. - // - // Example: - // func f() { - // const c = 1 - // c = 2 - // } - UnassignableOperand - - // NoNewVar occurs when a short variable declaration (':=') does not declare - // new variables. - // - // Example: - // func f() { - // x := 1 - // x := 2 - // } - NoNewVar - - // MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does - // not have single-valued left-hand or right-hand side. - // - // Per the spec: - // "In assignment operations, both the left- and right-hand expression lists - // must contain exactly one single-valued expression" - // - // Example: - // func f() int { - // x, y := 1, 2 - // x, y += 1 - // return x + y - // } - MultiValAssignOp - - // InvalidIfaceAssign occurs when a value of type T is used as an - // interface, but T does not implement a method of the expected interface. - // - // Example: - // type I interface { - // f() - // } - // - // type T int - // - // var x I = T(1) - InvalidIfaceAssign - - // InvalidChanAssign occurs when a chan assignment is invalid. - // - // Per the spec, a value x is assignable to a channel type T if: - // "x is a bidirectional channel value, T is a channel type, x's type V and - // T have identical element types, and at least one of V or T is not a - // defined type." - // - // Example: - // type T1 chan int - // type T2 chan int - // - // var x T1 - // // Invalid assignment because both types are named - // var _ T2 = x - InvalidChanAssign - - // IncompatibleAssign occurs when the type of the right-hand side expression - // in an assignment cannot be assigned to the type of the variable being - // assigned. - // - // Example: - // var x []int - // var _ int = x - IncompatibleAssign - - // UnaddressableFieldAssign occurs when trying to assign to a struct field - // in a map value. - // - // Example: - // func f() { - // m := make(map[string]struct{i int}) - // m["foo"].i = 42 - // } - UnaddressableFieldAssign - - /* decls > type (+ other type expression codes) */ - - // NotAType occurs when the identifier used as the underlying type in a type - // declaration or the right-hand side of a type alias does not denote a type. - // - // Example: - // var S = 2 - // - // type T S - NotAType - - // InvalidArrayLen occurs when an array length is not a constant value. - // - // Example: - // var n = 3 - // var _ = [n]int{} - InvalidArrayLen - - // BlankIfaceMethod occurs when a method name is '_'. - // - // Per the spec: - // "The name of each explicitly specified method must be unique and not - // blank." - // - // Example: - // type T interface { - // _(int) - // } - BlankIfaceMethod - - // IncomparableMapKey occurs when a map key type does not support the == and - // != operators. - // - // Per the spec: - // "The comparison operators == and != must be fully defined for operands of - // the key type; thus the key type must not be a function, map, or slice." - // - // Example: - // var x map[T]int - // - // type T []int - IncomparableMapKey - - // InvalidIfaceEmbed occurs when a non-interface type is embedded in an - // interface. - // - // Example: - // type T struct {} - // - // func (T) m() - // - // type I interface { - // T - // } - InvalidIfaceEmbed - - // InvalidPtrEmbed occurs when an embedded field is of the pointer form *T, - // and T itself is itself a pointer, an unsafe.Pointer, or an interface. - // - // Per the spec: - // "An embedded field must be specified as a type name T or as a pointer to - // a non-interface type name *T, and T itself may not be a pointer type." - // - // Example: - // type T *int - // - // type S struct { - // *T - // } - InvalidPtrEmbed - - /* decls > func and method */ - - // BadRecv occurs when a method declaration does not have exactly one - // receiver parameter. - // - // Example: - // func () _() {} - BadRecv - - // InvalidRecv occurs when a receiver type expression is not of the form T - // or *T, or T is a pointer type. - // - // Example: - // type T struct {} - // - // func (**T) m() {} - InvalidRecv - - // DuplicateFieldAndMethod occurs when an identifier appears as both a field - // and method name. - // - // Example: - // type T struct { - // m int - // } - // - // func (T) m() {} - DuplicateFieldAndMethod - - // DuplicateMethod occurs when two methods on the same receiver type have - // the same name. - // - // Example: - // type T struct {} - // func (T) m() {} - // func (T) m(i int) int { return i } - DuplicateMethod - - /* decls > special */ - - // InvalidBlank occurs when a blank identifier is used as a value or type. - // - // Per the spec: - // "The blank identifier may appear as an operand only on the left-hand side - // of an assignment." - // - // Example: - // var x = _ - InvalidBlank - - // InvalidIota occurs when the predeclared identifier iota is used outside - // of a constant declaration. - // - // Example: - // var x = iota - InvalidIota - - // MissingInitBody occurs when an init function is missing its body. - // - // Example: - // func init() - MissingInitBody - - // InvalidInitSig occurs when an init function declares parameters or - // results. - // - // Example: - // func init() int { return 1 } - InvalidInitSig - - // InvalidInitDecl occurs when init is declared as anything other than a - // function. - // - // Example: - // var init = 1 - InvalidInitDecl - - // InvalidMainDecl occurs when main is declared as anything other than a - // function, in a main package. - InvalidMainDecl - - /* exprs */ - - // TooManyValues occurs when a function returns too many values for the - // expression context in which it is used. - // - // Example: - // func ReturnTwo() (int, int) { - // return 1, 2 - // } - // - // var x = ReturnTwo() - TooManyValues - - // NotAnExpr occurs when a type expression is used where a value expression - // is expected. - // - // Example: - // type T struct {} - // - // func f() { - // T - // } - NotAnExpr - - /* exprs > const */ - - // TruncatedFloat occurs when a float constant is truncated to an integer - // value. - // - // Example: - // var _ int = 98.6 - TruncatedFloat - - // NumericOverflow occurs when a numeric constant overflows its target type. - // - // Example: - // var x int8 = 1000 - NumericOverflow - - /* exprs > operation */ - - // UndefinedOp occurs when an operator is not defined for the type(s) used - // in an operation. - // - // Example: - // var c = "a" - "b" - UndefinedOp - - // MismatchedTypes occurs when operand types are incompatible in a binary - // operation. - // - // Example: - // var a = "hello" - // var b = 1 - // var c = a - b - MismatchedTypes - - // DivByZero occurs when a division operation is provable at compile - // time to be a division by zero. - // - // Example: - // const divisor = 0 - // var x int = 1/divisor - DivByZero - - // NonNumericIncDec occurs when an increment or decrement operator is - // applied to a non-numeric value. - // - // Example: - // func f() { - // var c = "c" - // c++ - // } - NonNumericIncDec - - /* exprs > ptr */ - - // UnaddressableOperand occurs when the & operator is applied to an - // unaddressable expression. - // - // Example: - // var x = &1 - UnaddressableOperand - - // InvalidIndirection occurs when a non-pointer value is indirected via the - // '*' operator. - // - // Example: - // var x int - // var y = *x - InvalidIndirection - - /* exprs > [] */ - - // NonIndexableOperand occurs when an index operation is applied to a value - // that cannot be indexed. - // - // Example: - // var x = 1 - // var y = x[1] - NonIndexableOperand - - // InvalidIndex occurs when an index argument is not of integer type, - // negative, or out-of-bounds. - // - // Example: - // var s = [...]int{1,2,3} - // var x = s[5] - // - // Example: - // var s = []int{1,2,3} - // var _ = s[-1] - // - // Example: - // var s = []int{1,2,3} - // var i string - // var _ = s[i] - InvalidIndex - - // SwappedSliceIndices occurs when constant indices in a slice expression - // are decreasing in value. - // - // Example: - // var _ = []int{1,2,3}[2:1] - SwappedSliceIndices - - /* operators > slice */ - - // NonSliceableOperand occurs when a slice operation is applied to a value - // whose type is not sliceable, or is unaddressable. - // - // Example: - // var x = [...]int{1, 2, 3}[:1] - // - // Example: - // var x = 1 - // var y = 1[:1] - NonSliceableOperand - - // InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is - // applied to a string. - // - // Example: - // var s = "hello" - // var x = s[1:2:3] - InvalidSliceExpr - - /* exprs > shift */ - - // InvalidShiftCount occurs when the right-hand side of a shift operation is - // either non-integer, negative, or too large. - // - // Example: - // var ( - // x string - // y int = 1 << x - // ) - InvalidShiftCount - - // InvalidShiftOperand occurs when the shifted operand is not an integer. - // - // Example: - // var s = "hello" - // var x = s << 2 - InvalidShiftOperand - - /* exprs > chan */ - - // InvalidReceive occurs when there is a channel receive from a value that - // is either not a channel, or is a send-only channel. - // - // Example: - // func f() { - // var x = 1 - // <-x - // } - InvalidReceive - - // InvalidSend occurs when there is a channel send to a value that is not a - // channel, or is a receive-only channel. - // - // Example: - // func f() { - // var x = 1 - // x <- "hello!" - // } - InvalidSend - - /* exprs > literal */ - - // DuplicateLitKey occurs when an index is duplicated in a slice, array, or - // map literal. - // - // Example: - // var _ = []int{0:1, 0:2} - // - // Example: - // var _ = map[string]int{"a": 1, "a": 2} - DuplicateLitKey - - // MissingLitKey occurs when a map literal is missing a key expression. - // - // Example: - // var _ = map[string]int{1} - MissingLitKey - - // InvalidLitIndex occurs when the key in a key-value element of a slice or - // array literal is not an integer constant. - // - // Example: - // var i = 0 - // var x = []string{i: "world"} - InvalidLitIndex - - // OversizeArrayLit occurs when an array literal exceeds its length. - // - // Example: - // var _ = [2]int{1,2,3} - OversizeArrayLit - - // MixedStructLit occurs when a struct literal contains a mix of positional - // and named elements. - // - // Example: - // var _ = struct{i, j int}{i: 1, 2} - MixedStructLit - - // InvalidStructLit occurs when a positional struct literal has an incorrect - // number of values. - // - // Example: - // var _ = struct{i, j int}{1,2,3} - InvalidStructLit - - // MissingLitField occurs when a struct literal refers to a field that does - // not exist on the struct type. - // - // Example: - // var _ = struct{i int}{j: 2} - MissingLitField - - // DuplicateLitField occurs when a struct literal contains duplicated - // fields. - // - // Example: - // var _ = struct{i int}{i: 1, i: 2} - DuplicateLitField - - // UnexportedLitField occurs when a positional struct literal implicitly - // assigns an unexported field of an imported type. - UnexportedLitField - - // InvalidLitField occurs when a field name is not a valid identifier. - // - // Example: - // var _ = struct{i int}{1: 1} - InvalidLitField - - // UntypedLit occurs when a composite literal omits a required type - // identifier. - // - // Example: - // type outer struct{ - // inner struct { i int } - // } - // - // var _ = outer{inner: {1}} - UntypedLit - - // InvalidLit occurs when a composite literal expression does not match its - // type. - // - // Example: - // type P *struct{ - // x int - // } - // var _ = P {} - InvalidLit - - /* exprs > selector */ - - // AmbiguousSelector occurs when a selector is ambiguous. - // - // Example: - // type E1 struct { i int } - // type E2 struct { i int } - // type T struct { E1; E2 } - // - // var x T - // var _ = x.i - AmbiguousSelector - - // UndeclaredImportedName occurs when a package-qualified identifier is - // undeclared by the imported package. - // - // Example: - // import "go/types" - // - // var _ = types.NotAnActualIdentifier - UndeclaredImportedName - - // UnexportedName occurs when a selector refers to an unexported identifier - // of an imported package. - // - // Example: - // import "reflect" - // - // type _ reflect.flag - UnexportedName - - // UndeclaredName occurs when an identifier is not declared in the current - // scope. - // - // Example: - // var x T - UndeclaredName - - // MissingFieldOrMethod occurs when a selector references a field or method - // that does not exist. - // - // Example: - // type T struct {} - // - // var x = T{}.f - MissingFieldOrMethod - - /* exprs > ... */ - - // BadDotDotDotSyntax occurs when a "..." occurs in a context where it is - // not valid. - // - // Example: - // var _ = map[int][...]int{0: {}} - BadDotDotDotSyntax - - // NonVariadicDotDotDot occurs when a "..." is used on the final argument to - // a non-variadic function. - // - // Example: - // func printArgs(s []string) { - // for _, a := range s { - // println(a) - // } - // } - // - // func f() { - // s := []string{"a", "b", "c"} - // printArgs(s...) - // } - NonVariadicDotDotDot - - // MisplacedDotDotDot occurs when a "..." is used somewhere other than the - // final argument to a function call. - // - // Example: - // func printArgs(args ...int) { - // for _, a := range args { - // println(a) - // } - // } - // - // func f() { - // a := []int{1,2,3} - // printArgs(0, a...) - // } - MisplacedDotDotDot - - // InvalidDotDotDotOperand occurs when a "..." operator is applied to a - // single-valued operand. - // - // Example: - // func printArgs(args ...int) { - // for _, a := range args { - // println(a) - // } - // } - // - // func f() { - // a := 1 - // printArgs(a...) - // } - // - // Example: - // func args() (int, int) { - // return 1, 2 - // } - // - // func printArgs(args ...int) { - // for _, a := range args { - // println(a) - // } - // } - // - // func g() { - // printArgs(args()...) - // } - InvalidDotDotDotOperand - - // InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in - // function. - // - // Example: - // var s = []int{1, 2, 3} - // var l = len(s...) - InvalidDotDotDot - - /* exprs > built-in */ - - // UncalledBuiltin occurs when a built-in function is used as a - // function-valued expression, instead of being called. - // - // Per the spec: - // "The built-in functions do not have standard Go types, so they can only - // appear in call expressions; they cannot be used as function values." - // - // Example: - // var _ = copy - UncalledBuiltin - - // InvalidAppend occurs when append is called with a first argument that is - // not a slice. - // - // Example: - // var _ = append(1, 2) - InvalidAppend - - // InvalidCap occurs when an argument to the cap built-in function is not of - // supported type. - // - // See https://golang.org/ref/spec#Length_and_capacity for information on - // which underlying types are supported as arguments to cap and len. - // - // Example: - // var s = 2 - // var x = cap(s) - InvalidCap - - // InvalidClose occurs when close(...) is called with an argument that is - // not of channel type, or that is a receive-only channel. - // - // Example: - // func f() { - // var x int - // close(x) - // } - InvalidClose - - // InvalidCopy occurs when the arguments are not of slice type or do not - // have compatible type. - // - // See https://golang.org/ref/spec#Appending_and_copying_slices for more - // information on the type requirements for the copy built-in. - // - // Example: - // func f() { - // var x []int - // y := []int64{1,2,3} - // copy(x, y) - // } - InvalidCopy - - // InvalidComplex occurs when the complex built-in function is called with - // arguments with incompatible types. - // - // Example: - // var _ = complex(float32(1), float64(2)) - InvalidComplex - - // InvalidDelete occurs when the delete built-in function is called with a - // first argument that is not a map. - // - // Example: - // func f() { - // m := "hello" - // delete(m, "e") - // } - InvalidDelete - - // InvalidImag occurs when the imag built-in function is called with an - // argument that does not have complex type. - // - // Example: - // var _ = imag(int(1)) - InvalidImag - - // InvalidLen occurs when an argument to the len built-in function is not of - // supported type. - // - // See https://golang.org/ref/spec#Length_and_capacity for information on - // which underlying types are supported as arguments to cap and len. - // - // Example: - // var s = 2 - // var x = len(s) - InvalidLen - - // SwappedMakeArgs occurs when make is called with three arguments, and its - // length argument is larger than its capacity argument. - // - // Example: - // var x = make([]int, 3, 2) - SwappedMakeArgs - - // InvalidMake occurs when make is called with an unsupported type argument. - // - // See https://golang.org/ref/spec#Making_slices_maps_and_channels for - // information on the types that may be created using make. - // - // Example: - // var x = make(int) - InvalidMake - - // InvalidReal occurs when the real built-in function is called with an - // argument that does not have complex type. - // - // Example: - // var _ = real(int(1)) - InvalidReal - - /* exprs > assertion */ - - // InvalidAssert occurs when a type assertion is applied to a - // value that is not of interface type. - // - // Example: - // var x = 1 - // var _ = x.(float64) - InvalidAssert - - // ImpossibleAssert occurs for a type assertion x.(T) when the value x of - // interface cannot have dynamic type T, due to a missing or mismatching - // method on T. - // - // Example: - // type T int - // - // func (t *T) m() int { return int(*t) } - // - // type I interface { m() int } - // - // var x I - // var _ = x.(T) - ImpossibleAssert - - /* exprs > conversion */ - - // InvalidConversion occurs when the argument type cannot be converted to the - // target. - // - // See https://golang.org/ref/spec#Conversions for the rules of - // convertibility. - // - // Example: - // var x float64 - // var _ = string(x) - InvalidConversion - - // InvalidUntypedConversion occurs when there is no valid implicit - // conversion from an untyped value satisfying the type constraints of the - // context in which it is used. - // - // Example: - // var _ = 1 + "" - InvalidUntypedConversion - - /* offsetof */ - - // BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument - // that is not a selector expression. - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Offsetof(x) - BadOffsetofSyntax - - // InvalidOffsetof occurs when unsafe.Offsetof is called with a method - // selector, rather than a field selector, or when the field is embedded via - // a pointer. - // - // Per the spec: - // - // "If f is an embedded field, it must be reachable without pointer - // indirections through fields of the struct. " - // - // Example: - // import "unsafe" - // - // type T struct { f int } - // type S struct { *T } - // var s S - // var _ = unsafe.Offsetof(s.f) - // - // Example: - // import "unsafe" - // - // type S struct{} - // - // func (S) m() {} - // - // var s S - // var _ = unsafe.Offsetof(s.m) - InvalidOffsetof - - /* control flow > scope */ - - // UnusedExpr occurs when a side-effect free expression is used as a - // statement. Such a statement has no effect. - // - // Example: - // func f(i int) { - // i*i - // } - UnusedExpr - - // UnusedVar occurs when a variable is declared but unused. - // - // Example: - // func f() { - // x := 1 - // } - UnusedVar - - // MissingReturn occurs when a function with results is missing a return - // statement. - // - // Example: - // func f() int {} - MissingReturn - - // WrongResultCount occurs when a return statement returns an incorrect - // number of values. - // - // Example: - // func ReturnOne() int { - // return 1, 2 - // } - WrongResultCount - - // OutOfScopeResult occurs when the name of a value implicitly returned by - // an empty return statement is shadowed in a nested scope. - // - // Example: - // func factor(n int) (i int) { - // for i := 2; i < n; i++ { - // if n%i == 0 { - // return - // } - // } - // return 0 - // } - OutOfScopeResult - - /* control flow > if */ - - // InvalidCond occurs when an if condition is not a boolean expression. - // - // Example: - // func checkReturn(i int) { - // if i { - // panic("non-zero return") - // } - // } - InvalidCond - - /* control flow > for */ - - // InvalidPostDecl occurs when there is a declaration in a for-loop post - // statement. - // - // Example: - // func f() { - // for i := 0; i < 10; j := 0 {} - // } - InvalidPostDecl - - // InvalidChanRange occurs when a send-only channel used in a range - // expression. - // - // Example: - // func sum(c chan<- int) { - // s := 0 - // for i := range c { - // s += i - // } - // } - InvalidChanRange - - // InvalidIterVar occurs when two iteration variables are used while ranging - // over a channel. - // - // Example: - // func f(c chan int) { - // for k, v := range c { - // println(k, v) - // } - // } - InvalidIterVar - - // InvalidRangeExpr occurs when the type of a range expression is not array, - // slice, string, map, or channel. - // - // Example: - // func f(i int) { - // for j := range i { - // println(j) - // } - // } - InvalidRangeExpr - - /* control flow > switch */ - - // MisplacedBreak occurs when a break statement is not within a for, switch, - // or select statement of the innermost function definition. - // - // Example: - // func f() { - // break - // } - MisplacedBreak - - // MisplacedContinue occurs when a continue statement is not within a for - // loop of the innermost function definition. - // - // Example: - // func sumeven(n int) int { - // proceed := func() { - // continue - // } - // sum := 0 - // for i := 1; i <= n; i++ { - // if i % 2 != 0 { - // proceed() - // } - // sum += i - // } - // return sum - // } - MisplacedContinue - - // MisplacedFallthrough occurs when a fallthrough statement is not within an - // expression switch. - // - // Example: - // func typename(i interface{}) string { - // switch i.(type) { - // case int64: - // fallthrough - // case int: - // return "int" - // } - // return "unsupported" - // } - MisplacedFallthrough - - // DuplicateCase occurs when a type or expression switch has duplicate - // cases. - // - // Example: - // func printInt(i int) { - // switch i { - // case 1: - // println("one") - // case 1: - // println("One") - // } - // } - DuplicateCase - - // DuplicateDefault occurs when a type or expression switch has multiple - // default clauses. - // - // Example: - // func printInt(i int) { - // switch i { - // case 1: - // println("one") - // default: - // println("One") - // default: - // println("1") - // } - // } - DuplicateDefault - - // BadTypeKeyword occurs when a .(type) expression is used anywhere other - // than a type switch. - // - // Example: - // type I interface { - // m() - // } - // var t I - // var _ = t.(type) - BadTypeKeyword - - // InvalidTypeSwitch occurs when .(type) is used on an expression that is - // not of interface type. - // - // Example: - // func f(i int) { - // switch x := i.(type) {} - // } - InvalidTypeSwitch - - // InvalidExprSwitch occurs when a switch expression is not comparable. - // - // Example: - // func _() { - // var a struct{ _ func() } - // switch a /* ERROR cannot switch on a */ { - // } - // } - InvalidExprSwitch - - /* control flow > select */ - - // InvalidSelectCase occurs when a select case is not a channel send or - // receive. - // - // Example: - // func checkChan(c <-chan int) bool { - // select { - // case c: - // return true - // default: - // return false - // } - // } - InvalidSelectCase - - /* control flow > labels and jumps */ - - // UndeclaredLabel occurs when an undeclared label is jumped to. - // - // Example: - // func f() { - // goto L - // } - UndeclaredLabel - - // DuplicateLabel occurs when a label is declared more than once. - // - // Example: - // func f() int { - // L: - // L: - // return 1 - // } - DuplicateLabel - - // MisplacedLabel occurs when a break or continue label is not on a for, - // switch, or select statement. - // - // Example: - // func f() { - // L: - // a := []int{1,2,3} - // for _, e := range a { - // if e > 10 { - // break L - // } - // println(a) - // } - // } - MisplacedLabel - - // UnusedLabel occurs when a label is declared but not used. - // - // Example: - // func f() { - // L: - // } - UnusedLabel - - // JumpOverDecl occurs when a label jumps over a variable declaration. - // - // Example: - // func f() int { - // goto L - // x := 2 - // L: - // x++ - // return x - // } - JumpOverDecl - - // JumpIntoBlock occurs when a forward jump goes to a label inside a nested - // block. - // - // Example: - // func f(x int) { - // goto L - // if x > 0 { - // L: - // print("inside block") - // } - // } - JumpIntoBlock - - /* control flow > calls */ - - // InvalidMethodExpr occurs when a pointer method is called but the argument - // is not addressable. - // - // Example: - // type T struct {} - // - // func (*T) m() int { return 1 } - // - // var _ = T.m(T{}) - InvalidMethodExpr - - // WrongArgCount occurs when too few or too many arguments are passed by a - // function call. - // - // Example: - // func f(i int) {} - // var x = f() - WrongArgCount - - // InvalidCall occurs when an expression is called that is not of function - // type. - // - // Example: - // var x = "x" - // var y = x() - InvalidCall - - /* control flow > suspended */ - - // UnusedResults occurs when a restricted expression-only built-in function - // is suspended via go or defer. Such a suspension discards the results of - // these side-effect free built-in functions, and therefore is ineffectual. - // - // Example: - // func f(a []int) int { - // defer len(a) - // return i - // } - UnusedResults - - // InvalidDefer occurs when a deferred expression is not a function call, - // for example if the expression is a type conversion. - // - // Example: - // func f(i int) int { - // defer int32(i) - // return i - // } - InvalidDefer - - // InvalidGo occurs when a go expression is not a function call, for example - // if the expression is a type conversion. - // - // Example: - // func f(i int) int { - // go int32(i) - // return i - // } - InvalidGo - - // All codes below were added in Go 1.17. - - /* decl */ - - // BadDecl occurs when a declaration has invalid syntax. - BadDecl - - // RepeatedDecl occurs when an identifier occurs more than once on the left - // hand side of a short variable declaration. - // - // Example: - // func _() { - // x, y, y := 1, 2, 3 - // } - RepeatedDecl - - /* unsafe */ - - // InvalidUnsafeAdd occurs when unsafe.Add is called with a - // length argument that is not of integer type. - // - // Example: - // import "unsafe" - // - // var p unsafe.Pointer - // var _ = unsafe.Add(p, float64(1)) - InvalidUnsafeAdd - - // InvalidUnsafeSlice occurs when unsafe.Slice is called with a - // pointer argument that is not of pointer type or a length argument - // that is not of integer type, negative, or out of bounds. - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(x, 1) - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(&x, float64(1)) - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(&x, -1) - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.Slice(&x, uint64(1) << 63) - InvalidUnsafeSlice - - // All codes below were added in Go 1.18. - - /* features */ - - // UnsupportedFeature occurs when a language feature is used that is not - // supported at this Go version. - UnsupportedFeature - - /* type params */ - - // NotAGenericType occurs when a non-generic type is used where a generic - // type is expected: in type or function instantiation. - // - // Example: - // type T int - // - // var _ T[int] - NotAGenericType - - // WrongTypeArgCount occurs when a type or function is instantiated with an - // incorrect number of type arguments, including when a generic type or - // function is used without instantiation. - // - // Errors involving failed type inference are assigned other error codes. - // - // Example: - // type T[p any] int - // - // var _ T[int, string] - // - // Example: - // func f[T any]() {} - // - // var x = f - WrongTypeArgCount - - // CannotInferTypeArgs occurs when type or function type argument inference - // fails to infer all type arguments. - // - // Example: - // func f[T any]() {} - // - // func _() { - // f() - // } - // - // Example: - // type N[P, Q any] struct{} - // - // var _ N[int] - CannotInferTypeArgs - - // InvalidTypeArg occurs when a type argument does not satisfy its - // corresponding type parameter constraints. - // - // Example: - // type T[P ~int] struct{} - // - // var _ T[string] - InvalidTypeArg // arguments? InferenceFailed - - // InvalidInstanceCycle occurs when an invalid cycle is detected - // within the instantiation graph. - // - // Example: - // func f[T any]() { f[*T]() } - InvalidInstanceCycle - - // InvalidUnion occurs when an embedded union or approximation element is - // not valid. - // - // Example: - // type _ interface { - // ~int | interface{ m() } - // } - InvalidUnion - - // MisplacedConstraintIface occurs when a constraint-type interface is used - // outside of constraint position. - // - // Example: - // type I interface { ~int } - // - // var _ I - MisplacedConstraintIface - - // InvalidMethodTypeParams occurs when methods have type parameters. - // - // It cannot be encountered with an AST parsed using go/parser. - InvalidMethodTypeParams - - // MisplacedTypeParam occurs when a type parameter is used in a place where - // it is not permitted. - // - // Example: - // type T[P any] P - // - // Example: - // type T[P any] struct{ *P } - MisplacedTypeParam - - // InvalidUnsafeSliceData occurs when unsafe.SliceData is called with - // an argument that is not of slice type. It also occurs if it is used - // in a package compiled for a language version before go1.20. - // - // Example: - // import "unsafe" - // - // var x int - // var _ = unsafe.SliceData(x) - InvalidUnsafeSliceData - - // InvalidUnsafeString occurs when unsafe.String is called with - // a length argument that is not of integer type, negative, or - // out of bounds. It also occurs if it is used in a package - // compiled for a language version before go1.20. - // - // Example: - // import "unsafe" - // - // var b [10]byte - // var _ = unsafe.String(&b[0], -1) - InvalidUnsafeString - - // InvalidUnsafeStringData occurs if it is used in a package - // compiled for a language version before go1.20. - _ // not used anymore - -) diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go deleted file mode 100644 index 15ecf7c5..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go +++ /dev/null @@ -1,179 +0,0 @@ -// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT. - -package typesinternal - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[InvalidSyntaxTree - -1] - _ = x[Test-1] - _ = x[BlankPkgName-2] - _ = x[MismatchedPkgName-3] - _ = x[InvalidPkgUse-4] - _ = x[BadImportPath-5] - _ = x[BrokenImport-6] - _ = x[ImportCRenamed-7] - _ = x[UnusedImport-8] - _ = x[InvalidInitCycle-9] - _ = x[DuplicateDecl-10] - _ = x[InvalidDeclCycle-11] - _ = x[InvalidTypeCycle-12] - _ = x[InvalidConstInit-13] - _ = x[InvalidConstVal-14] - _ = x[InvalidConstType-15] - _ = x[UntypedNilUse-16] - _ = x[WrongAssignCount-17] - _ = x[UnassignableOperand-18] - _ = x[NoNewVar-19] - _ = x[MultiValAssignOp-20] - _ = x[InvalidIfaceAssign-21] - _ = x[InvalidChanAssign-22] - _ = x[IncompatibleAssign-23] - _ = x[UnaddressableFieldAssign-24] - _ = x[NotAType-25] - _ = x[InvalidArrayLen-26] - _ = x[BlankIfaceMethod-27] - _ = x[IncomparableMapKey-28] - _ = x[InvalidIfaceEmbed-29] - _ = x[InvalidPtrEmbed-30] - _ = x[BadRecv-31] - _ = x[InvalidRecv-32] - _ = x[DuplicateFieldAndMethod-33] - _ = x[DuplicateMethod-34] - _ = x[InvalidBlank-35] - _ = x[InvalidIota-36] - _ = x[MissingInitBody-37] - _ = x[InvalidInitSig-38] - _ = x[InvalidInitDecl-39] - _ = x[InvalidMainDecl-40] - _ = x[TooManyValues-41] - _ = x[NotAnExpr-42] - _ = x[TruncatedFloat-43] - _ = x[NumericOverflow-44] - _ = x[UndefinedOp-45] - _ = x[MismatchedTypes-46] - _ = x[DivByZero-47] - _ = x[NonNumericIncDec-48] - _ = x[UnaddressableOperand-49] - _ = x[InvalidIndirection-50] - _ = x[NonIndexableOperand-51] - _ = x[InvalidIndex-52] - _ = x[SwappedSliceIndices-53] - _ = x[NonSliceableOperand-54] - _ = x[InvalidSliceExpr-55] - _ = x[InvalidShiftCount-56] - _ = x[InvalidShiftOperand-57] - _ = x[InvalidReceive-58] - _ = x[InvalidSend-59] - _ = x[DuplicateLitKey-60] - _ = x[MissingLitKey-61] - _ = x[InvalidLitIndex-62] - _ = x[OversizeArrayLit-63] - _ = x[MixedStructLit-64] - _ = x[InvalidStructLit-65] - _ = x[MissingLitField-66] - _ = x[DuplicateLitField-67] - _ = x[UnexportedLitField-68] - _ = x[InvalidLitField-69] - _ = x[UntypedLit-70] - _ = x[InvalidLit-71] - _ = x[AmbiguousSelector-72] - _ = x[UndeclaredImportedName-73] - _ = x[UnexportedName-74] - _ = x[UndeclaredName-75] - _ = x[MissingFieldOrMethod-76] - _ = x[BadDotDotDotSyntax-77] - _ = x[NonVariadicDotDotDot-78] - _ = x[MisplacedDotDotDot-79] - _ = x[InvalidDotDotDotOperand-80] - _ = x[InvalidDotDotDot-81] - _ = x[UncalledBuiltin-82] - _ = x[InvalidAppend-83] - _ = x[InvalidCap-84] - _ = x[InvalidClose-85] - _ = x[InvalidCopy-86] - _ = x[InvalidComplex-87] - _ = x[InvalidDelete-88] - _ = x[InvalidImag-89] - _ = x[InvalidLen-90] - _ = x[SwappedMakeArgs-91] - _ = x[InvalidMake-92] - _ = x[InvalidReal-93] - _ = x[InvalidAssert-94] - _ = x[ImpossibleAssert-95] - _ = x[InvalidConversion-96] - _ = x[InvalidUntypedConversion-97] - _ = x[BadOffsetofSyntax-98] - _ = x[InvalidOffsetof-99] - _ = x[UnusedExpr-100] - _ = x[UnusedVar-101] - _ = x[MissingReturn-102] - _ = x[WrongResultCount-103] - _ = x[OutOfScopeResult-104] - _ = x[InvalidCond-105] - _ = x[InvalidPostDecl-106] - _ = x[InvalidChanRange-107] - _ = x[InvalidIterVar-108] - _ = x[InvalidRangeExpr-109] - _ = x[MisplacedBreak-110] - _ = x[MisplacedContinue-111] - _ = x[MisplacedFallthrough-112] - _ = x[DuplicateCase-113] - _ = x[DuplicateDefault-114] - _ = x[BadTypeKeyword-115] - _ = x[InvalidTypeSwitch-116] - _ = x[InvalidExprSwitch-117] - _ = x[InvalidSelectCase-118] - _ = x[UndeclaredLabel-119] - _ = x[DuplicateLabel-120] - _ = x[MisplacedLabel-121] - _ = x[UnusedLabel-122] - _ = x[JumpOverDecl-123] - _ = x[JumpIntoBlock-124] - _ = x[InvalidMethodExpr-125] - _ = x[WrongArgCount-126] - _ = x[InvalidCall-127] - _ = x[UnusedResults-128] - _ = x[InvalidDefer-129] - _ = x[InvalidGo-130] - _ = x[BadDecl-131] - _ = x[RepeatedDecl-132] - _ = x[InvalidUnsafeAdd-133] - _ = x[InvalidUnsafeSlice-134] - _ = x[UnsupportedFeature-135] - _ = x[NotAGenericType-136] - _ = x[WrongTypeArgCount-137] - _ = x[CannotInferTypeArgs-138] - _ = x[InvalidTypeArg-139] - _ = x[InvalidInstanceCycle-140] - _ = x[InvalidUnion-141] - _ = x[MisplacedConstraintIface-142] - _ = x[InvalidMethodTypeParams-143] - _ = x[MisplacedTypeParam-144] - _ = x[InvalidUnsafeSliceData-145] - _ = x[InvalidUnsafeString-146] -} - -const ( - _ErrorCode_name_0 = "InvalidSyntaxTree" - _ErrorCode_name_1 = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilUseWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParamInvalidUnsafeSliceDataInvalidUnsafeString" -) - -var ( - _ErrorCode_index_1 = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 218, 234, 253, 261, 277, 295, 312, 330, 354, 362, 377, 393, 411, 428, 443, 450, 461, 484, 499, 511, 522, 537, 551, 566, 581, 594, 603, 617, 632, 643, 658, 667, 683, 703, 721, 740, 752, 771, 790, 806, 823, 842, 856, 867, 882, 895, 910, 926, 940, 956, 971, 988, 1006, 1021, 1031, 1041, 1058, 1080, 1094, 1108, 1128, 1146, 1166, 1184, 1207, 1223, 1238, 1251, 1261, 1273, 1284, 1298, 1311, 1322, 1332, 1347, 1358, 1369, 1382, 1398, 1415, 1439, 1456, 1471, 1481, 1490, 1503, 1519, 1535, 1546, 1561, 1577, 1591, 1607, 1621, 1638, 1658, 1671, 1687, 1701, 1718, 1735, 1752, 1767, 1781, 1795, 1806, 1818, 1831, 1848, 1861, 1872, 1885, 1897, 1906, 1913, 1925, 1941, 1959, 1977, 1992, 2009, 2028, 2042, 2062, 2074, 2098, 2121, 2139, 2161, 2180} -) - -func (i ErrorCode) String() string { - switch { - case i == -1: - return _ErrorCode_name_0 - case 1 <= i && i <= 146: - i -= 1 - return _ErrorCode_name_1[_ErrorCode_index_1[i]:_ErrorCode_index_1[i+1]] - default: - return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")" - } -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/fx.go b/vendor/golang.org/x/tools/internal/typesinternal/fx.go deleted file mode 100644 index c846a53d..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/fx.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2025 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -import ( - "go/ast" - "go/token" - "go/types" -) - -// NoEffects reports whether the expression has no side effects, i.e., it -// does not modify the memory state. This function is conservative: it may -// return false even when the expression has no effect. -func NoEffects(info *types.Info, expr ast.Expr) bool { - noEffects := true - ast.Inspect(expr, func(n ast.Node) bool { - switch v := n.(type) { - case nil, *ast.Ident, *ast.BasicLit, *ast.BinaryExpr, *ast.ParenExpr, - *ast.SelectorExpr, *ast.IndexExpr, *ast.SliceExpr, *ast.TypeAssertExpr, - *ast.StarExpr, *ast.CompositeLit, - // non-expressions that may appear within expressions - *ast.KeyValueExpr, - *ast.FieldList, - *ast.Field, - *ast.Ellipsis, - *ast.IndexListExpr: - // No effect. - - case *ast.ArrayType, - *ast.StructType, - *ast.ChanType, - *ast.FuncType, - *ast.MapType, - *ast.InterfaceType: - // Type syntax: no effects, recursively. - // Prune descent. - return false - - case *ast.UnaryExpr: - // Channel send <-ch has effects. - if v.Op == token.ARROW { - noEffects = false - } - - case *ast.CallExpr: - // Type conversion has no effects. - if !info.Types[v.Fun].IsType() { - if CallsPureBuiltin(info, v) { - // A call such as len(e) has no effects of its - // own, though the subexpression e might. - } else { - noEffects = false - } - } - - case *ast.FuncLit: - // A FuncLit has no effects, but do not descend into it. - return false - - default: - // All other expressions have effects - noEffects = false - } - - return noEffects - }) - return noEffects -} - -// CallsPureBuiltin reports whether call is a call of a built-in -// function that is a pure computation over its operands (analogous to -// a + operator). Because it does not depend on program state, it may -// be evaluated at any point--though not necessarily at multiple -// points (consider new, make). -func CallsPureBuiltin(info *types.Info, call *ast.CallExpr) bool { - if id, ok := ast.Unparen(call.Fun).(*ast.Ident); ok { - if b, ok := info.ObjectOf(id).(*types.Builtin); ok { - switch b.Name() { - case "len", "cap", "complex", "imag", "real", "make", "new", "max", "min": - return true - } - // Not: append clear close copy delete panic print println recover - } - } - return false -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go b/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go deleted file mode 100644 index e0d63c46..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2025 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -import ( - "go/types" - "slices" -) - -// IsTypeNamed reports whether t is (or is an alias for) a -// package-level defined type with the given package path and one of -// the given names. It returns false if t is nil. -// -// This function avoids allocating the concatenation of "pkg.Name", -// which is important for the performance of syntax matching. -func IsTypeNamed(t types.Type, pkgPath string, names ...string) bool { - if named, ok := types.Unalias(t).(*types.Named); ok { - tname := named.Obj() - return tname != nil && - IsPackageLevel(tname) && - tname.Pkg().Path() == pkgPath && - slices.Contains(names, tname.Name()) - } - return false -} - -// IsPointerToNamed reports whether t is (or is an alias for) a pointer to a -// package-level defined type with the given package path and one of the given -// names. It returns false if t is not a pointer type. -func IsPointerToNamed(t types.Type, pkgPath string, names ...string) bool { - r := Unpointer(t) - if r == t { - return false - } - return IsTypeNamed(r, pkgPath, names...) -} - -// IsFunctionNamed reports whether obj is a package-level function -// defined in the given package and has one of the given names. -// It returns false if obj is nil. -// -// This function avoids allocating the concatenation of "pkg.Name", -// which is important for the performance of syntax matching. -func IsFunctionNamed(obj types.Object, pkgPath string, names ...string) bool { - f, ok := obj.(*types.Func) - return ok && - IsPackageLevel(obj) && - f.Pkg().Path() == pkgPath && - f.Signature().Recv() == nil && - slices.Contains(names, f.Name()) -} - -// IsMethodNamed reports whether obj is a method defined on a -// package-level type with the given package and type name, and has -// one of the given names. It returns false if obj is nil. -// -// This function avoids allocating the concatenation of "pkg.TypeName.Name", -// which is important for the performance of syntax matching. -func IsMethodNamed(obj types.Object, pkgPath string, typeName string, names ...string) bool { - if fn, ok := obj.(*types.Func); ok { - if recv := fn.Signature().Recv(); recv != nil { - _, T := ReceiverNamed(recv) - return T != nil && - IsTypeNamed(T, pkgPath, typeName) && - slices.Contains(names, fn.Name()) - } - } - return false -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go b/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go deleted file mode 100644 index 4e2756fc..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -import ( - "go/ast" - "go/types" - "strconv" -) - -// FileQualifier returns a [types.Qualifier] function that qualifies -// imported symbols appropriately based on the import environment of a given -// file. -// If the same package is imported multiple times, the last appearance is -// recorded. -// -// TODO(adonovan): this function ignores the effect of shadowing. It -// should accept a [token.Pos] and a [types.Info] and compute only the -// set of imports that are not shadowed at that point, analogous to -// [analysis.AddImport]. It could also compute (as a side -// effect) the set of additional imports required to ensure that there -// is an accessible import for each necessary package, making it -// converge even more closely with AddImport. -func FileQualifier(f *ast.File, pkg *types.Package) types.Qualifier { - // Construct mapping of import paths to their defined names. - // It is only necessary to look at renaming imports. - imports := make(map[string]string) - for _, imp := range f.Imports { - if imp.Name != nil && imp.Name.Name != "_" { - path, _ := strconv.Unquote(imp.Path.Value) - imports[path] = imp.Name.Name - } - } - - // Define qualifier to replace full package paths with names of the imports. - return func(p *types.Package) string { - if p == nil || p == pkg { - return "" - } - - if name, ok := imports[p.Path()]; ok { - if name == "." { - return "" - } else { - return name - } - } - - // If there is no local renaming, fall back to the package name. - return p.Name() - } -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/recv.go b/vendor/golang.org/x/tools/internal/typesinternal/recv.go deleted file mode 100644 index 8352ea76..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/recv.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -import ( - "go/types" -) - -// ReceiverNamed returns the named type (if any) associated with the -// type of recv, which may be of the form N or *N, or aliases thereof. -// It also reports whether a Pointer was present. -// -// The named result may be nil if recv is from a method on an -// anonymous interface or struct types or in ill-typed code. -func ReceiverNamed(recv *types.Var) (isPtr bool, named *types.Named) { - t := recv.Type() - if ptr, ok := types.Unalias(t).(*types.Pointer); ok { - isPtr = true - t = ptr.Elem() - } - named, _ = types.Unalias(t).(*types.Named) - return -} - -// Unpointer returns T given *T or an alias thereof. -// For all other types it is the identity function. -// It does not look at underlying types. -// The result may be an alias. -// -// Use this function to strip off the optional pointer on a receiver -// in a field or method selection, without losing the named type -// (which is needed to compute the method set). -// -// See also [typeparams.MustDeref], which removes one level of -// indirection from the type, regardless of named types (analogous to -// a LOAD instruction). -func Unpointer(t types.Type) types.Type { - if ptr, ok := types.Unalias(t).(*types.Pointer); ok { - return ptr.Elem() - } - return t -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go deleted file mode 100644 index cc86487e..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -import ( - "go/types" - - "golang.org/x/tools/internal/stdlib" - "golang.org/x/tools/internal/versions" -) - -// TooNewStdSymbols computes the set of package-level symbols -// exported by pkg that are not available at the specified version. -// The result maps each symbol to its minimum version. -// -// The pkg is allowed to contain type errors. -func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]string { - disallowed := make(map[types.Object]string) - - // Pass 1: package-level symbols. - symbols := stdlib.PackageSymbols[pkg.Path()] - for _, sym := range symbols { - symver := sym.Version.String() - if versions.Before(version, symver) { - switch sym.Kind { - case stdlib.Func, stdlib.Var, stdlib.Const, stdlib.Type: - disallowed[pkg.Scope().Lookup(sym.Name)] = symver - } - } - } - - // Pass 2: fields and methods. - // - // We allow fields and methods if their associated type is - // disallowed, as otherwise we would report false positives - // for compatibility shims. Consider: - // - // //go:build go1.22 - // type T struct { F std.Real } // correct new API - // - // //go:build !go1.22 - // type T struct { F fake } // shim - // type fake struct { ... } - // func (fake) M () {} - // - // These alternative declarations of T use either the std.Real - // type, introduced in go1.22, or a fake type, for the field - // F. (The fakery could be arbitrarily deep, involving more - // nested fields and methods than are shown here.) Clients - // that use the compatibility shim T will compile with any - // version of go, whether older or newer than go1.22, but only - // the newer version will use the std.Real implementation. - // - // Now consider a reference to method M in new(T).F.M() in a - // module that requires a minimum of go1.21. The analysis may - // occur using a version of Go higher than 1.21, selecting the - // first version of T, so the method M is Real.M. This would - // spuriously cause the analyzer to report a reference to a - // too-new symbol even though this expression compiles just - // fine (with the fake implementation) using go1.21. - for _, sym := range symbols { - symVersion := sym.Version.String() - if !versions.Before(version, symVersion) { - continue // allowed - } - - var obj types.Object - switch sym.Kind { - case stdlib.Field: - typename, name := sym.SplitField() - if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == "" { - obj, _, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name) - } - - case stdlib.Method: - ptr, recvname, name := sym.SplitMethod() - if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == "" { - obj, _, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name) - } - } - if obj != nil { - disallowed[obj] = symVersion - } - } - - return disallowed -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go deleted file mode 100644 index 6582cc81..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package typesinternal provides helpful operators for dealing with -// go/types: -// -// - operators for querying typed syntax trees (e.g. [Imports], [IsFunctionNamed]); -// - functions for converting types to strings or syntax (e.g. [TypeExpr], FileQualifier]); -// - helpers for working with the [go/types] API (e.g. [NewTypesInfo]); -// - access to internal go/types APIs that are not yet -// exported (e.g. [SetUsesCgo], [ErrorCodeStartEnd], [VarKind]); and -// - common algorithms related to types (e.g. [TooNewStdSymbols]). -// -// See also: -// - [golang.org/x/tools/internal/astutil], for operations on untyped syntax; -// - [golang.org/x/tools/internal/analysisinernal], for helpers for analyzers; -// - [golang.org/x/tools/internal/refactor], for operators to compute text edits. -package typesinternal - -import ( - "go/ast" - "go/token" - "go/types" - "reflect" - - "golang.org/x/tools/go/ast/inspector" -) - -func SetUsesCgo(conf *types.Config) bool { - v := reflect.ValueOf(conf).Elem() - - f := v.FieldByName("go115UsesCgo") - if !f.IsValid() { - f = v.FieldByName("UsesCgo") - if !f.IsValid() { - return false - } - } - - *(*bool)(f.Addr().UnsafePointer()) = true - - return true -} - -// ErrorCodeStartEnd extracts additional information from types.Error values -// generated by Go version 1.16 and later: the error code, start position, and -// end position. If all positions are valid, start <= err.Pos <= end. -// -// If the data could not be read, the final result parameter will be false. -// -// TODO(adonovan): eliminate start/end when proposal #71803 is accepted. -func ErrorCodeStartEnd(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) { - var data [3]int - // By coincidence all of these fields are ints, which simplifies things. - v := reflect.ValueOf(err) - for i, name := range []string{"go116code", "go116start", "go116end"} { - f := v.FieldByName(name) - if !f.IsValid() { - return 0, 0, 0, false - } - data[i] = int(f.Int()) - } - return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true -} - -// NameRelativeTo returns a types.Qualifier that qualifies members of -// all packages other than pkg, using only the package name. -// (By contrast, [types.RelativeTo] uses the complete package path, -// which is often excessive.) -// -// If pkg is nil, it is equivalent to [*types.Package.Name]. -// -// TODO(adonovan): all uses of this with TypeString should be -// eliminated when https://go.dev/issues/75604 is resolved. -func NameRelativeTo(pkg *types.Package) types.Qualifier { - return func(other *types.Package) string { - if pkg != nil && pkg == other { - return "" // same package; unqualified - } - return other.Name() - } -} - -// TypeNameFor returns the type name symbol for the specified type, if -// it is a [*types.Alias], [*types.Named], [*types.TypeParam], or a -// [*types.Basic] representing a type. -// -// For all other types, and for Basic types representing a builtin, -// constant, or nil, it returns nil. Be careful not to convert the -// resulting nil pointer to a [types.Object]! -// -// If t is the type of a constant, it may be an "untyped" type, which -// has no TypeName. To access the name of such types (e.g. "untyped -// int"), use [types.Basic.Name]. -func TypeNameFor(t types.Type) *types.TypeName { - switch t := t.(type) { - case *types.Alias: - return t.Obj() - case *types.Named: - return t.Obj() - case *types.TypeParam: - return t.Obj() - case *types.Basic: - // See issues #71886 and #66890 for some history. - if tname, ok := types.Universe.Lookup(t.Name()).(*types.TypeName); ok { - return tname - } - } - return nil -} - -// A NamedOrAlias is a [types.Type] that is named (as -// defined by the spec) and capable of bearing type parameters: it -// abstracts aliases ([types.Alias]) and defined types -// ([types.Named]). -// -// Every type declared by an explicit "type" declaration is a -// NamedOrAlias. (Built-in type symbols may additionally -// have type [types.Basic], which is not a NamedOrAlias, -// though the spec regards them as "named"; see [TypeNameFor].) -// -// NamedOrAlias cannot expose the Origin method, because -// [types.Alias.Origin] and [types.Named.Origin] have different -// (covariant) result types; use [Origin] instead. -type NamedOrAlias interface { - types.Type - Obj() *types.TypeName - TypeArgs() *types.TypeList - TypeParams() *types.TypeParamList - SetTypeParams(tparams []*types.TypeParam) -} - -var ( - _ NamedOrAlias = (*types.Alias)(nil) - _ NamedOrAlias = (*types.Named)(nil) -) - -// Origin returns the generic type of the Named or Alias type t if it -// is instantiated, otherwise it returns t. -func Origin(t NamedOrAlias) NamedOrAlias { - switch t := t.(type) { - case *types.Alias: - return t.Origin() - case *types.Named: - return t.Origin() - } - return t -} - -// IsPackageLevel reports whether obj is a package-level symbol. -func IsPackageLevel(obj types.Object) bool { - return obj.Pkg() != nil && obj.Parent() == obj.Pkg().Scope() -} - -// NewTypesInfo returns a *types.Info with all maps populated. -func NewTypesInfo() *types.Info { - return &types.Info{ - Types: map[ast.Expr]types.TypeAndValue{}, - Instances: map[*ast.Ident]types.Instance{}, - Defs: map[*ast.Ident]types.Object{}, - Uses: map[*ast.Ident]types.Object{}, - Implicits: map[ast.Node]types.Object{}, - Selections: map[*ast.SelectorExpr]*types.Selection{}, - Scopes: map[ast.Node]*types.Scope{}, - FileVersions: map[*ast.File]string{}, - } -} - -// EnclosingScope returns the innermost block logically enclosing the cursor. -func EnclosingScope(info *types.Info, cur inspector.Cursor) *types.Scope { - for cur := range cur.Enclosing() { - n := cur.Node() - // A function's Scope is associated with its FuncType. - switch f := n.(type) { - case *ast.FuncDecl: - n = f.Type - case *ast.FuncLit: - n = f.Type - } - if b := info.Scopes[n]; b != nil { - return b - } - } - panic("no Scope for *ast.File") -} - -// Imports reports whether path is imported by pkg. -func Imports(pkg *types.Package, path string) bool { - for _, imp := range pkg.Imports() { - if imp.Path() == path { - return true - } - } - return false -} - -// ObjectKind returns a description of the object's kind. -// -// from objectKind in go/types -func ObjectKind(obj types.Object) string { - switch obj := obj.(type) { - case *types.PkgName: - return "package name" - case *types.Const: - return "constant" - case *types.TypeName: - if obj.IsAlias() { - return "type alias" - } else if _, ok := obj.Type().(*types.TypeParam); ok { - return "type parameter" - } else { - return "defined type" - } - case *types.Var: - switch obj.Kind() { - case PackageVar: - return "package-level variable" - case LocalVar: - return "local variable" - case RecvVar: - return "receiver" - case ParamVar: - return "parameter" - case ResultVar: - return "result variable" - case FieldVar: - return "struct field" - } - case *types.Func: - if obj.Signature().Recv() != nil { - return "method" - } else { - return "function" - } - case *types.Label: - return "label" - case *types.Builtin: - return "built-in function" - case *types.Nil: - return "untyped nil" - } - return "unknown symbol" -} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/varkind.go b/vendor/golang.org/x/tools/internal/typesinternal/varkind.go deleted file mode 100644 index 26499cdd..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/varkind.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.25 - -package typesinternal - -import "go/types" - -type VarKind = types.VarKind - -const ( - PackageVar = types.PackageVar - LocalVar = types.LocalVar - RecvVar = types.RecvVar - ParamVar = types.ParamVar - ResultVar = types.ResultVar - FieldVar = types.FieldVar -) - -func GetVarKind(v *types.Var) VarKind { return v.Kind() } -func SetVarKind(v *types.Var, kind VarKind) { v.SetKind(kind) } diff --git a/vendor/golang.org/x/tools/internal/typesinternal/varkind_go124.go b/vendor/golang.org/x/tools/internal/typesinternal/varkind_go124.go deleted file mode 100644 index 17b1804b..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/varkind_go124.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.25 - -package typesinternal - -import "go/types" - -type VarKind uint8 - -const ( - _ VarKind = iota // (not meaningful) - PackageVar // a package-level variable - LocalVar // a local variable - RecvVar // a method receiver variable - ParamVar // a function parameter variable - ResultVar // a function result variable - FieldVar // a struct field -) - -func (kind VarKind) String() string { - return [...]string{ - 0: "VarKind(0)", - PackageVar: "PackageVar", - LocalVar: "LocalVar", - RecvVar: "RecvVar", - ParamVar: "ParamVar", - ResultVar: "ResultVar", - FieldVar: "FieldVar", - }[kind] -} - -// GetVarKind returns an invalid VarKind. -func GetVarKind(v *types.Var) VarKind { return 0 } - -// SetVarKind has no effect. -func SetVarKind(v *types.Var, kind VarKind) {} diff --git a/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go b/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go deleted file mode 100644 index d612a710..00000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go +++ /dev/null @@ -1,381 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "strings" -) - -// ZeroString returns the string representation of the zero value for any type t. -// The boolean result indicates whether the type is or contains an invalid type -// or a non-basic (constraint) interface type. -// -// Even for invalid input types, ZeroString may return a partially correct -// string representation. The caller should use the returned isValid boolean -// to determine the validity of the expression. -// -// When assigning to a wider type (such as 'any'), it's the caller's -// responsibility to handle any necessary type conversions. -// -// This string can be used on the right-hand side of an assignment where the -// left-hand side has that explicit type. -// References to named types are qualified by an appropriate (optional) -// qualifier function. -// Exception: This does not apply to tuples. Their string representation is -// informational only and cannot be used in an assignment. -// -// See [ZeroExpr] for a variant that returns an [ast.Expr]. -func ZeroString(t types.Type, qual types.Qualifier) (_ string, isValid bool) { - switch t := t.(type) { - case *types.Basic: - switch { - case t.Info()&types.IsBoolean != 0: - return "false", true - case t.Info()&types.IsNumeric != 0: - return "0", true - case t.Info()&types.IsString != 0: - return `""`, true - case t.Kind() == types.UnsafePointer: - fallthrough - case t.Kind() == types.UntypedNil: - return "nil", true - case t.Kind() == types.Invalid: - return "invalid", false - default: - panic(fmt.Sprintf("ZeroString for unexpected type %v", t)) - } - - case *types.Pointer, *types.Slice, *types.Chan, *types.Map, *types.Signature: - return "nil", true - - case *types.Interface: - if !t.IsMethodSet() { - return "invalid", false - } - return "nil", true - - case *types.Named: - switch under := t.Underlying().(type) { - case *types.Struct, *types.Array: - return types.TypeString(t, qual) + "{}", true - default: - return ZeroString(under, qual) - } - - case *types.Alias: - switch t.Underlying().(type) { - case *types.Struct, *types.Array: - return types.TypeString(t, qual) + "{}", true - default: - // A type parameter can have alias but alias type's underlying type - // can never be a type parameter. - // Use types.Unalias to preserve the info of type parameter instead - // of call Underlying() going right through and get the underlying - // type of the type parameter which is always an interface. - return ZeroString(types.Unalias(t), qual) - } - - case *types.Array, *types.Struct: - return types.TypeString(t, qual) + "{}", true - - case *types.TypeParam: - // Assumes func new is not shadowed. - return "*new(" + types.TypeString(t, qual) + ")", true - - case *types.Tuple: - // Tuples are not normal values. - // We are currently format as "(t[0], ..., t[n])". Could be something else. - isValid := true - components := make([]string, t.Len()) - for i := 0; i < t.Len(); i++ { - comp, ok := ZeroString(t.At(i).Type(), qual) - - components[i] = comp - isValid = isValid && ok - } - return "(" + strings.Join(components, ", ") + ")", isValid - - case *types.Union: - // Variables of these types cannot be created, so it makes - // no sense to ask for their zero value. - panic(fmt.Sprintf("invalid type for a variable: %v", t)) - - default: - panic(t) // unreachable. - } -} - -// ZeroExpr returns the ast.Expr representation of the zero value for any type t. -// The boolean result indicates whether the type is or contains an invalid type -// or a non-basic (constraint) interface type. -// -// Even for invalid input types, ZeroExpr may return a partially correct ast.Expr -// representation. The caller should use the returned isValid boolean to determine -// the validity of the expression. -// -// This function is designed for types suitable for variables and should not be -// used with Tuple or Union types.References to named types are qualified by an -// appropriate (optional) qualifier function. -// -// See [ZeroString] for a variant that returns a string. -func ZeroExpr(t types.Type, qual types.Qualifier) (_ ast.Expr, isValid bool) { - switch t := t.(type) { - case *types.Basic: - switch { - case t.Info()&types.IsBoolean != 0: - return &ast.Ident{Name: "false"}, true - case t.Info()&types.IsNumeric != 0: - return &ast.BasicLit{Kind: token.INT, Value: "0"}, true - case t.Info()&types.IsString != 0: - return &ast.BasicLit{Kind: token.STRING, Value: `""`}, true - case t.Kind() == types.UnsafePointer: - fallthrough - case t.Kind() == types.UntypedNil: - return ast.NewIdent("nil"), true - case t.Kind() == types.Invalid: - return &ast.BasicLit{Kind: token.STRING, Value: `"invalid"`}, false - default: - panic(fmt.Sprintf("ZeroExpr for unexpected type %v", t)) - } - - case *types.Pointer, *types.Slice, *types.Chan, *types.Map, *types.Signature: - return ast.NewIdent("nil"), true - - case *types.Interface: - if !t.IsMethodSet() { - return &ast.BasicLit{Kind: token.STRING, Value: `"invalid"`}, false - } - return ast.NewIdent("nil"), true - - case *types.Named: - switch under := t.Underlying().(type) { - case *types.Struct, *types.Array: - return &ast.CompositeLit{ - Type: TypeExpr(t, qual), - }, true - default: - return ZeroExpr(under, qual) - } - - case *types.Alias: - switch t.Underlying().(type) { - case *types.Struct, *types.Array: - return &ast.CompositeLit{ - Type: TypeExpr(t, qual), - }, true - default: - return ZeroExpr(types.Unalias(t), qual) - } - - case *types.Array, *types.Struct: - return &ast.CompositeLit{ - Type: TypeExpr(t, qual), - }, true - - case *types.TypeParam: - return &ast.StarExpr{ // *new(T) - X: &ast.CallExpr{ - // Assumes func new is not shadowed. - Fun: ast.NewIdent("new"), - Args: []ast.Expr{ - ast.NewIdent(t.Obj().Name()), - }, - }, - }, true - - case *types.Tuple: - // Unlike ZeroString, there is no ast.Expr can express tuple by - // "(t[0], ..., t[n])". - panic(fmt.Sprintf("invalid type for a variable: %v", t)) - - case *types.Union: - // Variables of these types cannot be created, so it makes - // no sense to ask for their zero value. - panic(fmt.Sprintf("invalid type for a variable: %v", t)) - - default: - panic(t) // unreachable. - } -} - -// TypeExpr returns syntax for the specified type. References to named types -// are qualified by an appropriate (optional) qualifier function. -// It may panic for types such as Tuple or Union. -// -// See also https://go.dev/issues/75604, which will provide a robust -// Type-to-valid-Go-syntax formatter. -func TypeExpr(t types.Type, qual types.Qualifier) ast.Expr { - switch t := t.(type) { - case *types.Basic: - switch t.Kind() { - case types.UnsafePointer: - return &ast.SelectorExpr{X: ast.NewIdent(qual(types.NewPackage("unsafe", "unsafe"))), Sel: ast.NewIdent("Pointer")} - default: - return ast.NewIdent(t.Name()) - } - - case *types.Pointer: - return &ast.UnaryExpr{ - Op: token.MUL, - X: TypeExpr(t.Elem(), qual), - } - - case *types.Array: - return &ast.ArrayType{ - Len: &ast.BasicLit{ - Kind: token.INT, - Value: fmt.Sprintf("%d", t.Len()), - }, - Elt: TypeExpr(t.Elem(), qual), - } - - case *types.Slice: - return &ast.ArrayType{ - Elt: TypeExpr(t.Elem(), qual), - } - - case *types.Map: - return &ast.MapType{ - Key: TypeExpr(t.Key(), qual), - Value: TypeExpr(t.Elem(), qual), - } - - case *types.Chan: - dir := ast.ChanDir(t.Dir()) - if t.Dir() == types.SendRecv { - dir = ast.SEND | ast.RECV - } - return &ast.ChanType{ - Dir: dir, - Value: TypeExpr(t.Elem(), qual), - } - - case *types.Signature: - var params []*ast.Field - for v := range t.Params().Variables() { - params = append(params, &ast.Field{ - Type: TypeExpr(v.Type(), qual), - Names: []*ast.Ident{ - { - Name: v.Name(), - }, - }, - }) - } - if t.Variadic() { - last := params[len(params)-1] - last.Type = &ast.Ellipsis{Elt: last.Type.(*ast.ArrayType).Elt} - } - var returns []*ast.Field - for v := range t.Results().Variables() { - returns = append(returns, &ast.Field{ - Type: TypeExpr(v.Type(), qual), - }) - } - return &ast.FuncType{ - Params: &ast.FieldList{ - List: params, - }, - Results: &ast.FieldList{ - List: returns, - }, - } - - case *types.TypeParam: - pkgName := qual(t.Obj().Pkg()) - if pkgName == "" || t.Obj().Pkg() == nil { - return ast.NewIdent(t.Obj().Name()) - } - return &ast.SelectorExpr{ - X: ast.NewIdent(pkgName), - Sel: ast.NewIdent(t.Obj().Name()), - } - - // types.TypeParam also implements interface NamedOrAlias. To differentiate, - // case TypeParam need to be present before case NamedOrAlias. - // TODO(hxjiang): remove this comment once TypeArgs() is added to interface - // NamedOrAlias. - case NamedOrAlias: - var expr ast.Expr = ast.NewIdent(t.Obj().Name()) - if pkgName := qual(t.Obj().Pkg()); pkgName != "." && pkgName != "" { - expr = &ast.SelectorExpr{ - X: ast.NewIdent(pkgName), - Sel: expr.(*ast.Ident), - } - } - - // TODO(hxjiang): call t.TypeArgs after adding method TypeArgs() to - // typesinternal.NamedOrAlias. - if hasTypeArgs, ok := t.(interface{ TypeArgs() *types.TypeList }); ok { - if typeArgs := hasTypeArgs.TypeArgs(); typeArgs != nil && typeArgs.Len() > 0 { - var indices []ast.Expr - for t0 := range typeArgs.Types() { - indices = append(indices, TypeExpr(t0, qual)) - } - expr = &ast.IndexListExpr{ - X: expr, - Indices: indices, - } - } - } - - return expr - - case *types.Struct: - return ast.NewIdent(t.String()) - - case *types.Interface: - return ast.NewIdent(t.String()) - - case *types.Union: - if t.Len() == 0 { - panic("Union type should have at least one term") - } - // Same as go/ast, the return expression will put last term in the - // Y field at topmost level of BinaryExpr. - // For union of type "float32 | float64 | int64", the structure looks - // similar to: - // { - // X: { - // X: float32, - // Op: | - // Y: float64, - // } - // Op: |, - // Y: int64, - // } - var union ast.Expr - for i := range t.Len() { - term := t.Term(i) - termExpr := TypeExpr(term.Type(), qual) - if term.Tilde() { - termExpr = &ast.UnaryExpr{ - Op: token.TILDE, - X: termExpr, - } - } - if i == 0 { - union = termExpr - } else { - union = &ast.BinaryExpr{ - X: union, - Op: token.OR, - Y: termExpr, - } - } - } - return union - - case *types.Tuple: - panic("invalid input type types.Tuple") - - default: - panic("unreachable") - } -} diff --git a/vendor/golang.org/x/tools/internal/versions/features.go b/vendor/golang.org/x/tools/internal/versions/features.go deleted file mode 100644 index 360a5b55..00000000 --- a/vendor/golang.org/x/tools/internal/versions/features.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package versions - -// This file contains predicates for working with file versions to -// decide when a tool should consider a language feature enabled. - -// named constants, to avoid misspelling -const ( - Go1_17 = "go1.17" - Go1_18 = "go1.18" - Go1_19 = "go1.19" - Go1_20 = "go1.20" - Go1_21 = "go1.21" - Go1_22 = "go1.22" - Go1_23 = "go1.23" - Go1_24 = "go1.24" - Go1_25 = "go1.25" - Go1_26 = "go1.26" - Go1_27 = "go1.27" -) - -// Future is an invalid unknown Go version sometime in the future. -// Do not use directly with Compare. -const Future = "" - -// AtLeast reports whether the file version v comes after a Go release. -// -// Use this predicate to enable a behavior once a certain Go release -// has happened (and stays enabled in the future). -func AtLeast(v, release string) bool { - if v == Future { - return true // an unknown future version is always after y. - } - return Compare(Lang(v), Lang(release)) >= 0 -} - -// Before reports whether the file version v is strictly before a Go release. -// -// Use this predicate to disable a behavior once a certain Go release -// has happened (and stays enabled in the future). -func Before(v, release string) bool { - if v == Future { - return false // an unknown future version happens after y. - } - return Compare(Lang(v), Lang(release)) < 0 -} diff --git a/vendor/golang.org/x/tools/internal/versions/gover.go b/vendor/golang.org/x/tools/internal/versions/gover.go deleted file mode 100644 index bbabcd22..00000000 --- a/vendor/golang.org/x/tools/internal/versions/gover.go +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This is a fork of internal/gover for use by x/tools until -// go1.21 and earlier are no longer supported by x/tools. - -package versions - -import "strings" - -// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]] -// The numbers are the original decimal strings to avoid integer overflows -// and since there is very little actual math. (Probably overflow doesn't matter in practice, -// but at the time this code was written, there was an existing test that used -// go1.99999999999, which does not fit in an int on 32-bit platforms. -// The "big decimal" representation avoids the problem entirely.) -type gover struct { - major string // decimal - minor string // decimal or "" - patch string // decimal or "" - kind string // "", "alpha", "beta", "rc" - pre string // decimal or "" -} - -// compare returns -1, 0, or +1 depending on whether -// x < y, x == y, or x > y, interpreted as toolchain versions. -// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21". -// Malformed versions compare less than well-formed versions and equal to each other. -// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0". -func compare(x, y string) int { - vx := parse(x) - vy := parse(y) - - if c := cmpInt(vx.major, vy.major); c != 0 { - return c - } - if c := cmpInt(vx.minor, vy.minor); c != 0 { - return c - } - if c := cmpInt(vx.patch, vy.patch); c != 0 { - return c - } - if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc - return c - } - if c := cmpInt(vx.pre, vy.pre); c != 0 { - return c - } - return 0 -} - -// lang returns the Go language version. For example, lang("1.2.3") == "1.2". -func lang(x string) string { - v := parse(x) - if v.minor == "" || v.major == "1" && v.minor == "0" { - return v.major - } - return v.major + "." + v.minor -} - -// isValid reports whether the version x is valid. -func isValid(x string) bool { - return parse(x) != gover{} -} - -// parse parses the Go version string x into a version. -// It returns the zero version if x is malformed. -func parse(x string) gover { - var v gover - - // Parse major version. - var ok bool - v.major, x, ok = cutInt(x) - if !ok { - return gover{} - } - if x == "" { - // Interpret "1" as "1.0.0". - v.minor = "0" - v.patch = "0" - return v - } - - // Parse . before minor version. - if x[0] != '.' { - return gover{} - } - - // Parse minor version. - v.minor, x, ok = cutInt(x[1:]) - if !ok { - return gover{} - } - if x == "" { - // Patch missing is same as "0" for older versions. - // Starting in Go 1.21, patch missing is different from explicit .0. - if cmpInt(v.minor, "21") < 0 { - v.patch = "0" - } - return v - } - - // Parse patch if present. - if x[0] == '.' { - v.patch, x, ok = cutInt(x[1:]) - if !ok || x != "" { - // Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != ""). - // Allowing them would be a bit confusing because we already have: - // 1.21 < 1.21rc1 - // But a prerelease of a patch would have the opposite effect: - // 1.21.3rc1 < 1.21.3 - // We've never needed them before, so let's not start now. - return gover{} - } - return v - } - - // Parse prerelease. - i := 0 - for i < len(x) && (x[i] < '0' || '9' < x[i]) { - if x[i] < 'a' || 'z' < x[i] { - return gover{} - } - i++ - } - if i == 0 { - return gover{} - } - v.kind, x = x[:i], x[i:] - if x == "" { - return v - } - v.pre, x, ok = cutInt(x) - if !ok || x != "" { - return gover{} - } - - return v -} - -// cutInt scans the leading decimal number at the start of x to an integer -// and returns that value and the rest of the string. -func cutInt(x string) (n, rest string, ok bool) { - i := 0 - for i < len(x) && '0' <= x[i] && x[i] <= '9' { - i++ - } - if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero - return "", "", false - } - return x[:i], x[i:], true -} - -// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers. -// (Copied from golang.org/x/mod/semver's compareInt.) -func cmpInt(x, y string) int { - if x == y { - return 0 - } - if len(x) < len(y) { - return -1 - } - if len(x) > len(y) { - return +1 - } - if x < y { - return -1 - } else { - return +1 - } -} diff --git a/vendor/golang.org/x/tools/internal/versions/types.go b/vendor/golang.org/x/tools/internal/versions/types.go deleted file mode 100644 index 0fc10ce4..00000000 --- a/vendor/golang.org/x/tools/internal/versions/types.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package versions - -import ( - "go/ast" - "go/types" -) - -// FileVersion returns a file's Go version. -// The reported version is an unknown Future version if a -// version cannot be determined. -func FileVersion(info *types.Info, file *ast.File) string { - // In tools built with Go >= 1.22, the Go version of a file - // follow a cascades of sources: - // 1) types.Info.FileVersion, which follows the cascade: - // 1.a) file version (ast.File.GoVersion), - // 1.b) the package version (types.Config.GoVersion), or - // 2) is some unknown Future version. - // - // File versions require a valid package version to be provided to types - // in Config.GoVersion. Config.GoVersion is either from the package's module - // or the toolchain (go run). This value should be provided by go/packages - // or unitchecker.Config.GoVersion. - if v := info.FileVersions[file]; IsValid(v) { - return v - } - // Note: we could instead return runtime.Version() [if valid]. - // This would act as a max version on what a tool can support. - return Future -} diff --git a/vendor/golang.org/x/tools/internal/versions/versions.go b/vendor/golang.org/x/tools/internal/versions/versions.go deleted file mode 100644 index 8d1f7453..00000000 --- a/vendor/golang.org/x/tools/internal/versions/versions.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package versions - -import ( - "strings" -) - -// Note: If we use build tags to use go/versions when go >=1.22, -// we run into go.dev/issue/53737. Under some operations users would see an -// import of "go/versions" even if they would not compile the file. -// For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include -// For this reason, this library just a clone of go/versions for the moment. - -// Lang returns the Go language version for version x. -// If x is not a valid version, Lang returns the empty string. -// For example: -// -// Lang("go1.21rc2") = "go1.21" -// Lang("go1.21.2") = "go1.21" -// Lang("go1.21") = "go1.21" -// Lang("go1") = "go1" -// Lang("bad") = "" -// Lang("1.21") = "" -func Lang(x string) string { - v := lang(stripGo(x)) - if v == "" { - return "" - } - return x[:2+len(v)] // "go"+v without allocation -} - -// Compare returns -1, 0, or +1 depending on whether -// x < y, x == y, or x > y, interpreted as Go versions. -// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21". -// Invalid versions, including the empty string, compare less than -// valid versions and equal to each other. -// The language version "go1.21" compares less than the -// release candidate and eventual releases "go1.21rc1" and "go1.21.0". -// Custom toolchain suffixes are ignored during comparison: -// "go1.21.0" and "go1.21.0-bigcorp" are equal. -func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) } - -// IsValid reports whether the version x is valid. -func IsValid(x string) bool { return isValid(stripGo(x)) } - -// stripGo converts from a "go1.21" version to a "1.21" version. -// If v does not start with "go", stripGo returns the empty string (a known invalid version). -func stripGo(v string) string { - v, _, _ = strings.Cut(v, "-") // strip -bigcorp suffix. - if len(v) < 2 || v[:2] != "go" { - return "" - } - return v[2:] -} diff --git a/vendor/modules.txt b/vendor/modules.txt index cf914238..f9c3ce02 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -89,9 +89,6 @@ github.com/go-ole/go-ole github.com/go-ole/go-ole/oleutil # github.com/go-playground/validator/v10 v10.15.1 ## explicit; go 1.18 -# github.com/go-task/slim-sprig/v3 v3.0.0 -## explicit; go 1.20 -github.com/go-task/slim-sprig/v3 # github.com/gobwas/httphead v0.1.0 ## explicit; go 1.15 github.com/gobwas/httphead @@ -109,9 +106,6 @@ github.com/gobwas/ws/wsutil ## explicit; go 1.12 github.com/google/gopacket github.com/google/gopacket/layers -# github.com/google/pprof v0.0.0-20250418163039-24c5476c6587 -## explicit; go 1.23 -github.com/google/pprof/profile # github.com/google/uuid v1.6.0 ## explicit github.com/google/uuid @@ -153,24 +147,6 @@ github.com/modern-go/reflect2 # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 ## explicit github.com/munnerz/goautoneg -# github.com/onsi/ginkgo/v2 v2.23.4 -## explicit; go 1.23.0 -github.com/onsi/ginkgo/v2/config -github.com/onsi/ginkgo/v2/formatter -github.com/onsi/ginkgo/v2/ginkgo -github.com/onsi/ginkgo/v2/ginkgo/build -github.com/onsi/ginkgo/v2/ginkgo/command -github.com/onsi/ginkgo/v2/ginkgo/generators -github.com/onsi/ginkgo/v2/ginkgo/internal -github.com/onsi/ginkgo/v2/ginkgo/labels -github.com/onsi/ginkgo/v2/ginkgo/outline -github.com/onsi/ginkgo/v2/ginkgo/run -github.com/onsi/ginkgo/v2/ginkgo/unfocus -github.com/onsi/ginkgo/v2/ginkgo/watch -github.com/onsi/ginkgo/v2/internal/interrupt_handler -github.com/onsi/ginkgo/v2/internal/parallel_support -github.com/onsi/ginkgo/v2/reporters -github.com/onsi/ginkgo/v2/types # github.com/pelletier/go-toml/v2 v2.0.9 ## explicit; go 1.16 # github.com/pkg/errors v0.9.1 @@ -203,20 +179,23 @@ github.com/prometheus/common/model github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util -# github.com/quic-go/quic-go v0.52.0 => github.com/chungthuang/quic-go v0.45.1-0.20250428085412-43229ad201fd -## explicit; go 1.23 +# github.com/quic-go/quic-go v0.59.1 => github.com/chungthuang/quic-go v0.45.1-0.20260529212404-a9fddf436fc4 +## explicit; go 1.24 github.com/quic-go/quic-go github.com/quic-go/quic-go/internal/ackhandler github.com/quic-go/quic-go/internal/congestion github.com/quic-go/quic-go/internal/flowcontrol github.com/quic-go/quic-go/internal/handshake +github.com/quic-go/quic-go/internal/monotime github.com/quic-go/quic-go/internal/protocol github.com/quic-go/quic-go/internal/qerr github.com/quic-go/quic-go/internal/utils github.com/quic-go/quic-go/internal/utils/linkedlist github.com/quic-go/quic-go/internal/utils/ringbuffer github.com/quic-go/quic-go/internal/wire -github.com/quic-go/quic-go/logging +github.com/quic-go/quic-go/qlog +github.com/quic-go/quic-go/qlogwriter +github.com/quic-go/quic-go/qlogwriter/jsontext github.com/quic-go/quic-go/quicvarint # github.com/rs/zerolog v1.20.0 ## explicit @@ -311,15 +290,12 @@ go.opentelemetry.io/proto/otlp/resource/v1 go.opentelemetry.io/proto/otlp/trace/v1 # go.uber.org/automaxprocs v1.6.0 ## explicit; go 1.20 -go.uber.org/automaxprocs go.uber.org/automaxprocs/internal/cgroups go.uber.org/automaxprocs/internal/runtime go.uber.org/automaxprocs/maxprocs -# go.uber.org/mock v0.5.1 -## explicit; go 1.22 +# go.uber.org/mock v0.5.2 +## explicit; go 1.23 go.uber.org/mock/gomock -go.uber.org/mock/mockgen -go.uber.org/mock/mockgen/model # golang.org/x/arch v0.4.0 ## explicit; go 1.17 # golang.org/x/crypto v0.52.0 @@ -339,10 +315,6 @@ golang.org/x/crypto/ssh golang.org/x/crypto/ssh/internal/bcrypt_pbkdf # golang.org/x/mod v0.35.0 ## explicit; go 1.25.0 -golang.org/x/mod/internal/lazyregexp -golang.org/x/mod/modfile -golang.org/x/mod/module -golang.org/x/mod/semver # golang.org/x/net v0.55.0 ## explicit; go 1.25.0 golang.org/x/net/bpf @@ -399,30 +371,6 @@ golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm # golang.org/x/tools v0.44.0 ## explicit; go 1.25.0 -golang.org/x/tools/cover -golang.org/x/tools/go/ast/astutil -golang.org/x/tools/go/ast/edge -golang.org/x/tools/go/ast/inspector -golang.org/x/tools/go/gcexportdata -golang.org/x/tools/go/packages -golang.org/x/tools/go/types/objectpath -golang.org/x/tools/go/types/typeutil -golang.org/x/tools/imports -golang.org/x/tools/internal/aliases -golang.org/x/tools/internal/event -golang.org/x/tools/internal/event/core -golang.org/x/tools/internal/event/keys -golang.org/x/tools/internal/event/label -golang.org/x/tools/internal/gcimporter -golang.org/x/tools/internal/gocommand -golang.org/x/tools/internal/gopathwalk -golang.org/x/tools/internal/imports -golang.org/x/tools/internal/packagesinternal -golang.org/x/tools/internal/pkgbits -golang.org/x/tools/internal/stdlib -golang.org/x/tools/internal/typeparams -golang.org/x/tools/internal/typesinternal -golang.org/x/tools/internal/versions # google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/api/httpbody @@ -569,4 +517,4 @@ zombiezen.com/go/capnproto2/std/capnp/rpc # github.com/urfave/cli/v2 => github.com/ipostelnik/cli/v2 v2.3.1-0.20210324024421-b6ea8234fe3d # github.com/prometheus/golang_client => github.com/prometheus/golang_client v1.12.1 # gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 -# github.com/quic-go/quic-go => github.com/chungthuang/quic-go v0.45.1-0.20250428085412-43229ad201fd +# github.com/quic-go/quic-go => github.com/chungthuang/quic-go v0.45.1-0.20260529212404-a9fddf436fc4