func (s *span) AddMessageReceiveEvent(messageID, uncompressedByteSize, compressedByteSize int64) {
	if !s.IsRecordingEvents() {
		return
	}
	now := time.Now()
	s.mu.Lock()
	s.messageEvents.add(MessageEvent{
		Time:                 now,
		EventType:            MessageEventTypeRecv,
		MessageID:            messageID,
		UncompressedByteSize: uncompressedByteSize,
		CompressedByteSize:   compressedByteSize,
	})
	s.mu.Unlock()
}
AddMessageReceiveEvent adds a message receive event to the span.

messageID is an identifier for the message, which is recommended to be
unique in this span and the same between the send event and the receive
event (this allows to identify a message between the sender and receiver).
For example, this could be a sequence id.
package trace
import (
	"context"
	crand "crypto/rand"
	"encoding/binary"
	"fmt"
	"math/rand"
	"sync"
	"sync/atomic"
	"time"
	"go.opencensus.io/internal"
	"go.opencensus.io/trace/tracestate"
)
type tracer struct{}
var _ Tracer = &tracer{}
type span struct {
	data        *SpanData
	mu          sync.Mutex  
	spanContext SpanContext
	lruAttributes *lruMap
	annotations *evictedQueue
	messageEvents *evictedQueue
	links *evictedQueue
	*spanStore
	endOnce sync.Once
	executionTracerTaskEnd func()  
}
func (s *span) IsRecordingEvents() bool {
	if s == nil {
		return false
	}
	return s.data != nil
}
type TraceOptions uint32
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      TraceID
	SpanID       SpanID
	TraceOptions TraceOptions
	Tracestate   *tracestate.Tracestate
}
type contextKey struct{}
func (t *tracer) FromContext(ctx context.Context) *Span {
	s, _ := ctx.Value(contextKey{}).(*Span)
	return s
}
func (t *tracer) NewContext(parent context.Context, s *Span) context.Context {
	return context.WithValue(parent, contextKey{}, s)
}
const (
	SpanKindUnspecified = iota
	SpanKindServer
	SpanKindClient
)
type StartOptions struct {
	Sampler Sampler
	SpanKind int
}
type StartOption func(*StartOptions)
func WithSpanKind(spanKind int) StartOption {
	return func(o *StartOptions) {
		o.SpanKind = spanKind
	}
}
func WithSampler(sampler Sampler) StartOption {
	return func(o *StartOptions) {
		o.Sampler = sampler
	}
}
func (t *tracer) StartSpan(ctx context.Context, name string, o ...StartOption) (context.Context, *Span) {
	var opts StartOptions
	var parent SpanContext
	if p := t.FromContext(ctx); p != nil {
		if ps, ok := p.internal.(*span); ok {
			ps.addChild()
		}
		parent = p.SpanContext()
	}
	for _, op := range o {
		op(&opts)
	}
	span := startSpanInternal(name, parent != SpanContext{}, parent, false, opts)
	ctx, end := startExecutionTracerTask(ctx, name)
	span.executionTracerTaskEnd = end
	extSpan := NewSpan(span)
	return t.NewContext(ctx, extSpan), extSpan
}
func (t *tracer) StartSpanWithRemoteParent(ctx context.Context, name string, parent SpanContext, o ...StartOption) (context.Context, *Span) {
	var opts StartOptions
	for _, op := range o {
		op(&opts)
	}
	span := startSpanInternal(name, parent != SpanContext{}, parent, true, opts)
	ctx, end := startExecutionTracerTask(ctx, name)
	span.executionTracerTaskEnd = end
	extSpan := NewSpan(span)
	return t.NewContext(ctx, extSpan), extSpan
}
func startSpanInternal(name string, hasParent bool, parent SpanContext, remoteParent bool, o StartOptions) *span {
	s := &span{}
	s.spanContext = parent
	cfg := config.Load().(*Config)
	if gen, ok := cfg.IDGenerator.(*defaultIDGenerator); ok {
		gen.init()
	}
	if !hasParent {
		s.spanContext.TraceID = cfg.IDGenerator.NewTraceID()
	}
	s.spanContext.SpanID = cfg.IDGenerator.NewSpanID()
	sampler := cfg.DefaultSampler
	if !hasParent || remoteParent || o.Sampler != nil {
		if o.Sampler != nil {
			sampler = o.Sampler
		}
		s.spanContext.setIsSampled(sampler(SamplingParameters{
			ParentContext:   parent,
			TraceID:         s.spanContext.TraceID,
			SpanID:          s.spanContext.SpanID,
			Name:            name,
			HasRemoteParent: remoteParent}).Sample)
	}
	if !internal.LocalSpanStoreEnabled && !s.spanContext.IsSampled() {
		return s
	}
	s.data = &SpanData{
		SpanContext:     s.spanContext,
		StartTime:       time.Now(),
		SpanKind:        o.SpanKind,
		Name:            name,
		HasRemoteParent: remoteParent,
	}
	s.lruAttributes = newLruMap(cfg.MaxAttributesPerSpan)
	s.annotations = newEvictedQueue(cfg.MaxAnnotationEventsPerSpan)
	s.messageEvents = newEvictedQueue(cfg.MaxMessageEventsPerSpan)
	s.links = newEvictedQueue(cfg.MaxLinksPerSpan)
	if hasParent {
		s.data.ParentSpanID = parent.SpanID
	}
	if internal.LocalSpanStoreEnabled {
		var ss *spanStore
		ss = spanStoreForNameCreateIfNew(name)
		if ss != nil {
			s.spanStore = ss
			ss.add(s)
		}
	}
	return s
}
func (s *span) End() {
	if s == nil {
		return
	}
	if s.executionTracerTaskEnd != nil {
		s.executionTracerTaskEnd()
	}
	if !s.IsRecordingEvents() {
		return
	}
	s.endOnce.Do(func() {
		exp, _ := exporters.Load().(exportersMap)
		mustExport := s.spanContext.IsSampled() && len(exp) > 0
		if s.spanStore != nil || mustExport {
			sd := s.makeSpanData()
			sd.EndTime = internal.MonotonicEndTime(sd.StartTime)
			if s.spanStore != nil {
				s.spanStore.finished(s, sd)
			}
			if mustExport {
				for e := range exp {
					e.ExportSpan(sd)
				}
			}
		}
	})
}
func (s *span) makeSpanData() *SpanData {
	var sd SpanData
	s.mu.Lock()
	sd = *s.data
	if s.lruAttributes.len() > 0 {
		sd.Attributes = s.lruAttributesToAttributeMap()
		sd.DroppedAttributeCount = s.lruAttributes.droppedCount
	}
	if len(s.annotations.queue) > 0 {
		sd.Annotations = s.interfaceArrayToAnnotationArray()
		sd.DroppedAnnotationCount = s.annotations.droppedCount
	}
	if len(s.messageEvents.queue) > 0 {
		sd.MessageEvents = s.interfaceArrayToMessageEventArray()
		sd.DroppedMessageEventCount = s.messageEvents.droppedCount
	}
	if len(s.links.queue) > 0 {
		sd.Links = s.interfaceArrayToLinksArray()
		sd.DroppedLinkCount = s.links.droppedCount
	}
	s.mu.Unlock()
	return &sd
}
func (s *span) SpanContext() SpanContext {
	if s == nil {
		return SpanContext{}
	}
	return s.spanContext
}
func (s *span) SetName(name string) {
	if !s.IsRecordingEvents() {
		return
	}
	s.mu.Lock()
	s.data.Name = name
	s.mu.Unlock()
}
func (s *span) SetStatus(status Status) {
	if !s.IsRecordingEvents() {
		return
	}
	s.mu.Lock()
	s.data.Status = status
	s.mu.Unlock()
}
func (s *span) interfaceArrayToLinksArray() []Link {
	linksArr := make([]Link, 0, len(s.links.queue))
	for _, value := range s.links.queue {
		linksArr = append(linksArr, value.(Link))
	}
	return linksArr
}
func (s *span) interfaceArrayToMessageEventArray() []MessageEvent {
	messageEventArr := make([]MessageEvent, 0, len(s.messageEvents.queue))
	for _, value := range s.messageEvents.queue {
		messageEventArr = append(messageEventArr, value.(MessageEvent))
	}
	return messageEventArr
}
func (s *span) interfaceArrayToAnnotationArray() []Annotation {
	annotationArr := make([]Annotation, 0, len(s.annotations.queue))
	for _, value := range s.annotations.queue {
		annotationArr = append(annotationArr, value.(Annotation))
	}
	return annotationArr
}
func (s *span) lruAttributesToAttributeMap() map[string]interface{} {
	attributes := make(map[string]interface{}, s.lruAttributes.len())
	for _, key := range s.lruAttributes.keys() {
		value, ok := s.lruAttributes.get(key)
		if ok {
			keyStr := key.(string)
			attributes[keyStr] = value
		}
	}
	return attributes
}
func (s *span) copyToCappedAttributes(attributes []Attribute) {
	for _, a := range attributes {
		s.lruAttributes.add(a.key, a.value)
	}
}
func (s *span) addChild() {
	if !s.IsRecordingEvents() {
		return
	}
	s.mu.Lock()
	s.data.ChildSpanCount++
	s.mu.Unlock()
}
func (s *span) AddAttributes(attributes ...Attribute) {
	if !s.IsRecordingEvents() {
		return
	}
	s.mu.Lock()
	s.copyToCappedAttributes(attributes)
	s.mu.Unlock()
}
func (s *span) printStringInternal(attributes []Attribute, str string) {
	now := time.Now()
	var am map[string]interface{}
	if len(attributes) != 0 {
		am = make(map[string]interface{}, len(attributes))
		for _, attr := range attributes {
			am[attr.key] = attr.value
		}
	}
	s.mu.Lock()
	s.annotations.add(Annotation{
		Time:       now,
		Message:    str,
		Attributes: am,
	})
	s.mu.Unlock()
}
func (s *span) Annotate(attributes []Attribute, str string) {
	if !s.IsRecordingEvents() {
		return
	}
	s.printStringInternal(attributes, str)
}
func (s *span) Annotatef(attributes []Attribute, format string, a ...interface{}) {
	if !s.IsRecordingEvents() {
		return
	}
	s.printStringInternal(attributes, fmt.Sprintf(format, a...))
}
func (s *span) AddMessageSendEvent(messageID, uncompressedByteSize, compressedByteSize int64) {
	if !s.IsRecordingEvents() {
		return
	}
	now := time.Now()
	s.mu.Lock()
	s.messageEvents.add(MessageEvent{
		Time:                 now,
		EventType:            MessageEventTypeSent,
		MessageID:            messageID,
		UncompressedByteSize: uncompressedByteSize,
		CompressedByteSize:   compressedByteSize,
	})
	s.mu.Unlock()
}