func newTraceIDLocked() TraceID {
	var tid TraceID
	binary.LittleEndian.PutUint64(tid[0:8], traceIDRand.Uint64()+traceIDAdd[0])
	binary.LittleEndian.PutUint64(tid[8:16], traceIDRand.Uint64()+traceIDAdd[1])
	return tid
}
newTraceIDLocked returns a non-zero TraceID from a randomly-chosen sequence.
mu should be held while this function is called.
package trace
import (
	"context"
	crand "crypto/rand"
	"encoding/binary"
	"fmt"
	"math/rand"
	"runtime"
	"sync"
	"time"
)
type Span struct {
	data        *SpanData
	mu          sync.Mutex  
	spanContext SpanContext
	*spanStore
}
func IsRecordingEvents(ctx context.Context) bool {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return false
	}
	return s.IsRecordingEvents()
}
func (s *Span) IsRecordingEvents() bool {
	if s == nil {
		return false
	}
	return s.data != nil
}
type TraceOptions uint32
func IsSampled(ctx context.Context) bool {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return false
	}
	return s.IsSampled()
}
func (s *Span) IsSampled() bool {
	if s == nil {
		return false
	}
	return s.spanContext.IsSampled()
}
func (sc SpanContext) IsSampled() bool {
	return sc.TraceOptions.IsSampled()
}
func (sc *SpanContext) setIsSampled(sampled bool) {
	if sampled {
		sc.TraceOptions |= 1
	} else {
		sc.TraceOptions &= ^TraceOptions(1)
	}
}
func (t TraceOptions) IsSampled() bool {
	return t&1 == 1
}
type SpanContext struct {
	TraceID
	SpanID
	TraceOptions
}
type contextKey struct{}
func FromContext(ctx context.Context) *Span {
	s, _ := ctx.Value(contextKey{}).(*Span)
	return s
}
func WithSpan(parent context.Context, s *Span) context.Context {
	return context.WithValue(parent, contextKey{}, s)
}
type StartSpanOptions struct {
	RecordEvents bool
	Sampler       
	RegisterNameForLocalSpanStore bool
}
func StartSpan(ctx context.Context, name string) context.Context {
	parentSpan, _ := ctx.Value(contextKey{}).(*Span)
	return WithSpan(ctx, parentSpan.StartSpanWithOptions(name, StartSpanOptions{}))
}
func StartSpanWithOptions(ctx context.Context, name string, o StartSpanOptions) context.Context {
	parentSpan, _ := ctx.Value(contextKey{}).(*Span)
	return WithSpan(ctx, parentSpan.StartSpanWithOptions(name, o))
}
func StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o StartSpanOptions) context.Context {
	return WithSpan(ctx, NewSpanWithRemoteParent(name, parent, o))
}
func (s *Span) StartSpan(name string) *Span {
	return s.StartSpanWithOptions(name, StartSpanOptions{})
}
func (s *Span) StartSpanWithOptions(name string, o StartSpanOptions) *Span {
	if s != nil {
		return startSpanInternal(name, true, s.spanContext, false, o)
	}
	return startSpanInternal(name, false, SpanContext{}, false, o)
}
func NewSpan(name string, o StartSpanOptions) *Span {
	return startSpanInternal(name, false, SpanContext{}, false, o)
}
func NewSpanWithRemoteParent(name string, parent SpanContext, o StartSpanOptions) *Span {
	return startSpanInternal(name, true, parent, true, o)
}
func startSpanInternal(name string, hasParent bool, parent SpanContext, remoteParent bool, o StartSpanOptions) *Span {
	span := &Span{}
	span.spanContext = parent
	mu.Lock()
	if !hasParent {
		span.spanContext.TraceID = newTraceIDLocked()
	}
	span.spanContext.SpanID = newSpanIDLocked()
	sampler := defaultSampler
	mu.Unlock()
	if !hasParent || remoteParent || o.Sampler != nil {
		if o.Sampler != nil {
			sampler = o.Sampler
		}
		span.spanContext.setIsSampled(sampler.Sample(SamplingParameters{
			ParentContext:   parent,
			TraceID:         span.spanContext.TraceID,
			SpanID:          span.spanContext.SpanID,
			Name:            name,
			HasRemoteParent: remoteParent}).Sample)
	}
	if !o.RecordEvents && !span.spanContext.IsSampled() {
		return span
	}
	span.data = &SpanData{
		SpanContext:     span.spanContext,
		StartTime:       time.Now(),
		Name:            name,
		HasRemoteParent: remoteParent,
	}
	if hasParent {
		span.data.ParentSpanID = parent.SpanID
	}
	if o.RecordEvents {
		var ss *spanStore
		if o.RegisterNameForLocalSpanStore {
			ss = spanStoreForNameCreateIfNew(name)
		} else {
			ss = spanStoreForName(name)
		}
		if ss != nil {
			span.spanStore = ss
			ss.add(span)
		}
	}
	return span
}
func EndSpan(ctx context.Context) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.End()
}
func (s *Span) End() {
	if !s.IsRecordingEvents() {
		return
	}
	sd := s.makeSpanData()
	sd.EndTime = time.Now()
	if s.spanStore != nil {
		s.spanStore.finished(s, sd)
	}
	if s.spanContext.IsSampled() {
		exportersMu.Lock()
		for e := range exporters {
			e.Export(sd)
		}
		exportersMu.Unlock()
	}
}
func (s *Span) makeSpanData() *SpanData {
	var sd SpanData
	s.mu.Lock()
	sd = *s.data
	if s.data.Attributes != nil {
		sd.Attributes = make(map[string]interface{})
		for k, v := range s.data.Attributes {
			sd.Attributes[k] = v
		}
	}
	s.mu.Unlock()
	return &sd
}
func SpanContextFromContext(ctx context.Context) (SpanContext, bool) {
	s, _ := ctx.Value(contextKey{}).(*Span)
	if s == nil {
		return SpanContext{}, false
	}
	return s.SpanContext(), true
}
func (s *Span) SpanContext() SpanContext {
	if s == nil {
		return SpanContext{}
	}
	return s.spanContext
}
func SetSpanStatus(ctx context.Context, status Status) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.SetStatus(status)
}
func (s *Span) SetStatus(status Status) {
	if !s.IsRecordingEvents() {
		return
	}
	s.mu.Lock()
	s.data.Status = status
	s.mu.Unlock()
}
func SetSpanAttributes(ctx context.Context, attributes ...Attribute) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.SetAttributes(attributes...)
}
func (s *Span) SetAttributes(attributes ...Attribute) {
	if !s.IsRecordingEvents() {
		return
	}
	s.mu.Lock()
	if s.data.Attributes == nil {
		s.data.Attributes = make(map[string]interface{})
	}
	copyAttributes(s.data.Attributes, attributes)
	s.mu.Unlock()
}
func copyAttributes(m map[string]interface{}, attributes []Attribute) {
	for _, a := range attributes {
		switch a := a.(type) {
		case BoolAttribute:
			m[a.Key] = a.Value
		case Int64Attribute:
			m[a.Key] = a.Value
		case StringAttribute:
			m[a.Key] = a.Value
		}
	}
}
func LazyPrint(ctx context.Context, str fmt.Stringer) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.LazyPrint(str)
}
func (s *Span) LazyPrint(str fmt.Stringer) {
	if !s.IsRecordingEvents() {
		return
	}
	s.lazyPrintInternal(nil, str)
}
func LazyPrintWithAttributes(ctx context.Context, attributes []Attribute, str fmt.Stringer) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.LazyPrintWithAttributes(attributes, str)
}
func (s *Span) LazyPrintWithAttributes(attributes []Attribute, str fmt.Stringer) {
	if !s.IsRecordingEvents() {
		return
	}
	s.lazyPrintInternal(attributes, str)
}
func (s *Span) lazyPrintInternal(attributes []Attribute, str fmt.Stringer) {
	now := time.Now()
	msg := str.String()
	var a map[string]interface{}
	s.mu.Lock()
	if len(attributes) != 0 {
		a = make(map[string]interface{})
		copyAttributes(a, attributes)
	}
	s.data.Annotations = append(s.data.Annotations, Annotation{
		Time:       now,
		Message:    msg,
		Attributes: a,
	})
	s.mu.Unlock()
}
func LazyPrintf(ctx context.Context, format string, a ...interface{}) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.LazyPrintf(format, a...)
}
func (s *Span) LazyPrintf(format string, a ...interface{}) {
	if !s.IsRecordingEvents() {
		return
	}
	s.lazyPrintfInternal(nil, format, a...)
}
func (s *Span) lazyPrintfInternal(attributes []Attribute, format string, a ...interface{}) {
	now := time.Now()
	msg := fmt.Sprintf(format, a...)
	var m map[string]interface{}
	s.mu.Lock()
	if len(attributes) != 0 {
		m = make(map[string]interface{})
		copyAttributes(m, attributes)
	}
	s.data.Annotations = append(s.data.Annotations, Annotation{
		Time:       now,
		Message:    msg,
		Attributes: m,
	})
	s.mu.Unlock()
}
func LazyPrintfWithAttributes(ctx context.Context, attributes []Attribute, format string, a ...interface{}) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.LazyPrintfWithAttributes(attributes, format, a...)
}
func (s *Span) LazyPrintfWithAttributes(attributes []Attribute, format string, a ...interface{}) {
	if !s.IsRecordingEvents() {
		return
	}
	s.lazyPrintfInternal(attributes, format, a...)
}
func Print(ctx context.Context, str string) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.Print(str)
}
func (s *Span) Print(str string) {
	if !s.IsRecordingEvents() {
		return
	}
	s.printStringInternal(nil, str)
}
func (s *Span) printStringInternal(attributes []Attribute, str string) {
	now := time.Now()
	var a map[string]interface{}
	s.mu.Lock()
	if len(attributes) != 0 {
		a = make(map[string]interface{})
		copyAttributes(a, attributes)
	}
	s.data.Annotations = append(s.data.Annotations, Annotation{
		Time:       now,
		Message:    str,
		Attributes: a,
	})
	s.mu.Unlock()
}
func PrintWithAttributes(ctx context.Context, attributes []Attribute, str string) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.PrintWithAttributes(attributes, str)
}
func (s *Span) PrintWithAttributes(attributes []Attribute, str string) {
	if !s.IsRecordingEvents() {
		return
	}
	s.printStringInternal(attributes, str)
}
func SetStackTrace(ctx context.Context) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.SetStackTrace()
}
func (s *Span) SetStackTrace() {
	if !s.IsRecordingEvents() {
		return
	}
	pcs := make([]uintptr, 20  )
	_ = runtime.Callers(1, pcs[:])
	s.mu.Lock()
	s.data.StackTrace = pcs
	s.mu.Unlock()
}
func AddMessageSendEvent(ctx context.Context, messageID, uncompressedByteSize, compressedByteSize int64) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize)
}
func (s *Span) AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) {
	if !s.IsRecordingEvents() {
		return
	}
	now := time.Now()
	s.mu.Lock()
	s.data.MessageEvents = append(s.data.MessageEvents, MessageEvent{
		Time:                 now,
		EventType:            MessageEventTypeSent,
		MessageID:            messageID,
		UncompressedByteSize: uncompressedByteSize,
		CompressedByteSize:   compressedByteSize,
	})
	s.mu.Unlock()
}
func AddMessageReceiveEvent(ctx context.Context, messageID, uncompressedByteSize, compressedByteSize int64) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize)
}
func (s *Span) AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) {
	if !s.IsRecordingEvents() {
		return
	}
	now := time.Now()
	s.mu.Lock()
	s.data.MessageEvents = append(s.data.MessageEvents, MessageEvent{
		Time:                 now,
		EventType:            MessageEventTypeRecv,
		MessageID:            messageID,
		UncompressedByteSize: uncompressedByteSize,
		CompressedByteSize:   compressedByteSize,
	})
	s.mu.Unlock()
}
func AddLink(ctx context.Context, l Link) {
	s, ok := ctx.Value(contextKey{}).(*Span)
	if !ok {
		return
	}
	s.AddLink(l)
}
func (s *Span) AddLink(l Link) {
	if !s.IsRecordingEvents() {
		return
	}
	s.mu.Lock()
	s.data.Links = append(s.data.Links, l)
	s.mu.Unlock()
}
func (s *Span) String() string {
	if s == nil {
		return "<nil>"
	}
	if s.data == nil {
		return fmt.Sprintf("span %s", s.spanContext.SpanID)
	}
	s.mu.Lock()
	str := fmt.Sprintf("span %s %q", s.spanContext.SpanID, s.data.Name)
	s.mu.Unlock()
	return str
}
var (
	mu          sync.Mutex  
	traceIDRand *rand.Rand
	traceIDAdd  [2]uint64
	nextSpanID  uint64
	spanIDInc   uint64
)
func init() {
	var rngSeed int64
	for _, p := range []interface{}{
		&rngSeed, &traceIDAdd, &nextSpanID, &spanIDInc,
	} {
		binary.Read(crand.Reader, binary.LittleEndian, p)
	}
	traceIDRand = rand.New(rand.NewSource(rngSeed))
	spanIDInc |= 1
}
func newSpanIDLocked() SpanID {
	id := nextSpanID
	nextSpanID += spanIDInc
	if nextSpanID == 0 {
		nextSpanID += spanIDInc
	}
	var sid SpanID
	binary.LittleEndian.PutUint64(sid[:], id)
	return sid
}