You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: trace.go
    path of file: ./repos/sliver/vendor/github.com/jackc/pgx/v5/pgproto3
    
    the code of the file until where you have to start completion: package pgproto3

import (
	"bytes"
	"fmt"
	"io"
	"strconv"
	"strings"
	"time"
)

// tracer traces the messages send to and from a Backend or Frontend. The format it produces roughly mimics the
// format produced by the libpq C function PQtrace.
type tracer struct {
	w   io.Writer
	buf *bytes.Buffer
	TracerOptions
}

// TracerOptions controls tracing behavior. It is roughly equivalent to the libpq function PQsetTraceFlags.
type TracerOptions struct {
	// SuppressTimestamps prevents printing of timestamps.
	SuppressTimestamps bool

	// RegressMode redacts fields that may be vary between executions.
	RegressMode bool
}

func (t *tracer) traceMessage(sender byte, encodedLen int32, msg Message) {
	switch msg := msg.(type) {
	case *AuthenticationCleartextPassword:
		t.traceAuthenticationCleartextPassword(sender, encodedLen, msg)
	case *AuthenticationGSS:
		t.traceAuthenticationGSS(sender, encodedLen, msg)
	case *AuthenticationGSSContinue:
		t.traceAuthenticationGSSContinue(sender, encodedLen, msg)
	case *AuthenticationMD5Password:
		t.traceAuthenticationMD5Password(sender, encodedLen, msg)
	case *AuthenticationOk:
		t.traceAuthenticationOk(sender, encodedLen, msg)
	case *AuthenticationSASL:
		t.traceAuthenticationSASL(sender, encodedLen, msg)
	case *AuthenticationSASLContinue:
		t.traceAuthenticationSASLContinue(sender, encodedLen, msg)
	case *AuthenticationSASLFinal:
		t.traceAuthenticationSASLFinal(sender, encodedLen, msg)
	case *BackendKeyData:
		t.traceBackendKeyData(sender, encodedLen, msg)
	case *Bind:
		t.traceBind(sender, encodedLen, msg)
	case *BindComplete:
		t.traceBindComplete(sender, encodedLen, msg)
	case *CancelRequest:
		t.traceCancelRequest(sender, encodedLen, msg)
	case *Close:
		t.traceClose(sender, encodedLen, msg)
	case *CloseComplete:
		t.traceCloseComplete(sender, encodedLen, msg)
	case *CommandComplete:
		t.traceCommandComplete(sender, encodedLen, m
    
func (t *tracer) traceMessage(sender byte, encodedLen int32, msg Message) {
	switch msg := msg.(type) {
	case *AuthenticationCleartextPassword:
		t.traceAuthenticationCleartextPassword(sender, encodedLen, msg)
	case *AuthenticationGSS:
		t.traceAuthenticationGSS(sender, encodedLen, msg)
	case *AuthenticationGSSContinue:
		t.traceAuthenticationGSSContinue(sender, encodedLen, msg)
	case *AuthenticationMD5Password:
		t.traceAuthenticationMD5Password(sender, encodedLen, msg)
	case *AuthenticationOk:
		t.traceAuthenticationOk(sender, encodedLen, msg)
	case *AuthenticationSASL:
		t.traceAuthenticationSASL(sender, encodedLen, msg)
	case *AuthenticationSASLContinue:
		t.traceAuthenticationSASLContinue(sender, encodedLen, msg)
	case *AuthenticationSASLFinal:
		t.traceAuthenticationSASLFinal(sender, encodedLen, msg)
	case *BackendKeyData:
		t.traceBackendKeyData(sender, encodedLen, msg)
	case *Bind:
		t.traceBind(sender, encodedLen, msg)
	case *BindComplete:
		t.traceBindComplete(sender, encodedLen, msg)
	case *CancelRequest:
		t.traceCancelRequest(sender, encodedLen, msg)
	case *Close:
		t.traceClose(sender, encodedLen, msg)
	case *CloseComplete:
		t.traceCloseComplete(sender, encodedLen, msg)
	case *CommandComplete:
		t.traceCommandComplete(sender, encodedLen, msg)
	case *CopyBothResponse:
		t.traceCopyBothResponse(sender, encodedLen, msg)
	case *CopyData:
		t.traceCopyData(sender, encodedLen, msg)
	case *CopyDone:
		t.traceCopyDone(sender, encodedLen, msg)
	case *CopyFail:
		t.traceCopyFail(sender, encodedLen, msg)
	case *CopyInResponse:
		t.traceCopyInResponse(sender, encodedLen, msg)
	case *CopyOutResponse:
		t.traceCopyOutResponse(sender, encodedLen, msg)
	case *DataRow:
		t.traceDataRow(sender, encodedLen, msg)
	case *Describe:
		t.traceDescribe(sender, encodedLen, msg)
	case *EmptyQueryResponse:
		t.traceEmptyQueryResponse(sender, encodedLen, msg)
	case *ErrorResponse:
		t.traceErrorResponse(sender, encodedLen, msg)
	case *Execute:
		t.TraceQueryute(sender, encodedLen, msg)
	case *Flush:
		t.traceFlush(sender, encodedLen, msg)
	case *FunctionCall:
		t.traceFunctionCall(sender, encodedLen, msg)
	case *FunctionCallResponse:
		t.traceFunctionCallResponse(sender, encodedLen, msg)
	case *GSSEncRequest:
		t.traceGSSEncRequest(sender, encodedLen, msg)
	case *NoData:
		t.traceNoData(sender, encodedLen, msg)
	case *NoticeResponse:
		t.traceNoticeResponse(sender, encodedLen, msg)
	case *NotificationResponse:
		t.traceNotificationResponse(sender, encodedLen, msg)
	case *ParameterDescription:
		t.traceParameterDescription(sender, encodedLen, msg)
	case *ParameterStatus:
		t.traceParameterStatus(sender, encodedLen, msg)
	case *Parse:
		t.traceParse(sender, encodedLen, msg)
	case *ParseComplete:
		t.traceParseComplete(sender, encodedLen, msg)
	case *PortalSuspended:
		t.tracePortalSuspended(sender, encodedLen, msg)
	case *Query:
		t.traceQuery(sender, encodedLen, msg)
	case *ReadyForQuery:
		t.traceReadyForQuery(sender, encodedLen, msg)
	case *RowDescription:
		t.traceRowDescription(sender, encodedLen, msg)
	case *SSLRequest:
		t.traceSSLRequest(sender, encodedLen, msg)
	case *StartupMessage:
		t.traceStartupMessage(sender, encodedLen, msg)
	case *Sync:
		t.traceSync(sender, encodedLen, msg)
	case *Terminate:
		t.traceTerminate(sender, encodedLen, msg)
	default:
		t.beginTrace(sender, encodedLen, "Unknown")
		t.finishTrace()
	}
}