// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package trace // import "go.opentelemetry.io/otel/sdk/trace"

import (
	
	
	
	
	rt 
	
	
	
	
	

	
	
	
	
	
	semconv 
	
	
)

// ReadOnlySpan allows reading information from the data structure underlying a
// trace.Span. It is used in places where reading information from a span is
// necessary but changing the span isn't necessary or allowed.
//
// Warning: methods may be added to this interface in minor releases.
type ReadOnlySpan interface {
	// Name returns the name of the span.
	Name() string
	// SpanContext returns the unique SpanContext that identifies the span.
	SpanContext() trace.SpanContext
	// Parent returns the unique SpanContext that identifies the parent of the
	// span if one exists. If the span has no parent the returned SpanContext
	// will be invalid.
	Parent() trace.SpanContext
	// SpanKind returns the role the span plays in a Trace.
	SpanKind() trace.SpanKind
	// StartTime returns the time the span started recording.
	StartTime() time.Time
	// EndTime returns the time the span stopped recording. It will be zero if
	// the span has not ended.
	EndTime() time.Time
	// Attributes returns the defining attributes of the span.
	// The order of the returned attributes is not guaranteed to be stable across invocations.
	Attributes() []attribute.KeyValue
	// Links returns all the links the span has to other spans.
	Links() []Link
	// Events returns all the events that occurred within in the spans
	// lifetime.
	Events() []Event
	// Status returns the spans status.
	Status() Status
	// InstrumentationScope returns information about the instrumentation
	// scope that created the span.
	InstrumentationScope() instrumentation.Scope
	// InstrumentationLibrary returns information about the instrumentation
	// library that created the span.
	//
	// Deprecated: please use InstrumentationScope instead.
	InstrumentationLibrary() instrumentation.Library //nolint:staticcheck // This method needs to be define for backwards compatibility
	// Resource returns information about the entity that produced the span.
	Resource() *resource.Resource
	// DroppedAttributes returns the number of attributes dropped by the span
	// due to limits being reached.
	DroppedAttributes() int
	// DroppedLinks returns the number of links dropped by the span due to
	// limits being reached.
	DroppedLinks() int
	// DroppedEvents returns the number of events dropped by the span due to
	// limits being reached.
	DroppedEvents() int
	// ChildSpanCount returns the count of spans that consider the span a
	// direct parent.
	ChildSpanCount() int

	// A private method to prevent users implementing the
	// interface and so future additions to it will not
	// violate compatibility.
	private()
}

// ReadWriteSpan exposes the same methods as trace.Span and in addition allows
// reading information from the underlying data structure.
// This interface exposes the union of the methods of trace.Span (which is a
// "write-only" span) and ReadOnlySpan. New methods for writing or reading span
// information should be added under trace.Span or ReadOnlySpan, respectively.
//
// Warning: methods may be added to this interface in minor releases.
type ReadWriteSpan interface {
	trace.Span
	ReadOnlySpan
}

// recordingSpan is an implementation of the OpenTelemetry Span API
// representing the individual component of a trace that is sampled.
type recordingSpan struct {
	embedded.Span

	// mu protects the contents of this span.
	mu sync.Mutex

	// parent holds the parent span of this span as a trace.SpanContext.
	parent trace.SpanContext

	// spanKind represents the kind of this span as a trace.SpanKind.
	spanKind trace.SpanKind

	// name is the name of this span.
	name string

	// startTime is the time at which this span was started.
	startTime time.Time

	// endTime is the time at which this span was ended. It contains the zero
	// value of time.Time until the span is ended.
	endTime time.Time

	// status is the status of this span.
	status Status

	// childSpanCount holds the number of child spans created for this span.
	childSpanCount int

	// spanContext holds the SpanContext of this span.
	spanContext trace.SpanContext

	// attributes is a collection of user provided key/values. The collection
	// is constrained by a configurable maximum held by the parent
	// TracerProvider. When additional attributes are added after this maximum
	// is reached these attributes the user is attempting to add are dropped.
	// This dropped number of attributes is tracked and reported in the
	// ReadOnlySpan exported when the span ends.
	attributes        []attribute.KeyValue
	droppedAttributes int
	logDropAttrsOnce  sync.Once

	// events are stored in FIFO queue capped by configured limit.
	events evictedQueue[Event]

	// links are stored in FIFO queue capped by configured limit.
	links evictedQueue[Link]

	// executionTracerTaskEnd ends the execution tracer span.
	executionTracerTaskEnd func()

	// tracer is the SDK tracer that created this span.
	tracer *tracer
}

var (
	_ ReadWriteSpan = (*recordingSpan)(nil)
	_ runtimeTracer = (*recordingSpan)(nil)
)

// SpanContext returns the SpanContext of this span.
func ( *recordingSpan) () trace.SpanContext {
	if  == nil {
		return trace.SpanContext{}
	}
	return .spanContext
}

// IsRecording reports whether this span is being recorded. If this span has ended
// this will return false.
func ( *recordingSpan) () bool {
	if  == nil {
		return false
	}
	.mu.Lock()
	defer .mu.Unlock()

	return .isRecording()
}

// isRecording reports whether this span is being recorded. If this span has ended
// this will return false.
//
// This method assumes s.mu.Lock is held by the caller.
func ( *recordingSpan) () bool {
	if  == nil {
		return false
	}
	return .endTime.IsZero()
}

// SetStatus sets the status of the Span in the form of a code and a
// description, overriding previous values set. The description is only
// included in the set status when the code is for an error. If this span is
// not being recorded than this method does nothing.
func ( *recordingSpan) ( codes.Code,  string) {
	if  == nil {
		return
	}

	.mu.Lock()
	defer .mu.Unlock()
	if !.isRecording() {
		return
	}
	if .status.Code >  {
		return
	}

	 := Status{Code: }
	if  == codes.Error {
		.Description = 
	}

	.status = 
}

// SetAttributes sets attributes of this span.
//
// If a key from attributes already exists the value associated with that key
// will be overwritten with the value contained in attributes.
//
// If this span is not being recorded than this method does nothing.
//
// If adding attributes to the span would exceed the maximum amount of
// attributes the span is configured to have, the last added attributes will
// be dropped.
func ( *recordingSpan) ( ...attribute.KeyValue) {
	if  == nil || len() == 0 {
		return
	}

	.mu.Lock()
	defer .mu.Unlock()
	if !.isRecording() {
		return
	}

	 := .tracer.provider.spanLimits.AttributeCountLimit
	if  == 0 {
		// No attributes allowed.
		.addDroppedAttr(len())
		return
	}

	// If adding these attributes could exceed the capacity of s perform a
	// de-duplication and truncation while adding to avoid over allocation.
	if  > 0 && len(.attributes)+len() >  {
		.addOverCapAttrs(, )
		return
	}

	// Otherwise, add without deduplication. When attributes are read they
	// will be deduplicated, optimizing the operation.
	.attributes = slices.Grow(.attributes, len())
	for ,  := range  {
		if !.Valid() {
			// Drop all invalid attributes.
			.addDroppedAttr(1)
			continue
		}
		 = truncateAttr(.tracer.provider.spanLimits.AttributeValueLengthLimit, )
		.attributes = append(.attributes, )
	}
}

// Declared as a var so tests can override.
var logDropAttrs = func() {
	global.Warn("limit reached: dropping trace Span attributes")
}

// addDroppedAttr adds incr to the count of dropped attributes.
//
// The first, and only the first, time this method is called a warning will be
// logged.
//
// This method assumes s.mu.Lock is held by the caller.
func ( *recordingSpan) ( int) {
	.droppedAttributes += 
	.logDropAttrsOnce.Do(logDropAttrs)
}

// addOverCapAttrs adds the attributes attrs to the span s while
// de-duplicating the attributes of s and attrs and dropping attributes that
// exceed the limit.
//
// This method assumes s.mu.Lock is held by the caller.
//
// This method should only be called when there is a possibility that adding
// attrs to s will exceed the limit. Otherwise, attrs should be added to s
// without checking for duplicates and all retrieval methods of the attributes
// for s will de-duplicate as needed.
//
// This method assumes limit is a value > 0. The argument should be validated
// by the caller.
func ( *recordingSpan) ( int,  []attribute.KeyValue) {
	// In order to not allocate more capacity to s.attributes than needed,
	// prune and truncate this addition of attributes while adding.

	// Do not set a capacity when creating this map. Benchmark testing has
	// showed this to only add unused memory allocations in general use.
	 := make(map[attribute.Key]int, len(.attributes))
	.dedupeAttrsFromRecord()

	// Now that s.attributes is deduplicated, adding unique attributes up to
	// the capacity of s will not over allocate s.attributes.

	// max size = limit
	 := min(len()+len(.attributes), )
	if cap(.attributes) <  {
		.attributes = slices.Grow(.attributes, -cap(.attributes))
	}
	for ,  := range  {
		if !.Valid() {
			// Drop all invalid attributes.
			.addDroppedAttr(1)
			continue
		}

		if ,  := [.Key];  {
			// Perform all updates before dropping, even when at capacity.
			 = truncateAttr(.tracer.provider.spanLimits.AttributeValueLengthLimit, )
			.attributes[] = 
			continue
		}

		if len(.attributes) >=  {
			// Do not just drop all of the remaining attributes, make sure
			// updates are checked and performed.
			.addDroppedAttr(1)
		} else {
			 = truncateAttr(.tracer.provider.spanLimits.AttributeValueLengthLimit, )
			.attributes = append(.attributes, )
			[.Key] = len(.attributes) - 1
		}
	}
}

// truncateAttr returns a truncated version of attr. Only string and string
// slice attribute values are truncated. String values are truncated to at
// most a length of limit. Each string slice value is truncated in this fashion
// (the slice length itself is unaffected).
//
// No truncation is performed for a negative limit.
func truncateAttr( int,  attribute.KeyValue) attribute.KeyValue {
	if  < 0 {
		return 
	}
	switch .Value.Type() {
	case attribute.STRING:
		 := .Value.AsString()
		return .Key.String(truncate(, ))
	case attribute.STRINGSLICE:
		 := .Value.AsStringSlice()
		for  := range  {
			[] = truncate(, [])
		}
		return .Key.StringSlice()
	}
	return 
}

// truncate returns a truncated version of s such that it contains less than
// the limit number of characters. Truncation is applied by returning the limit
// number of valid characters contained in s.
//
// If limit is negative, it returns the original string.
//
// UTF-8 is supported. When truncating, all invalid characters are dropped
// before applying truncation.
//
// If s already contains less than the limit number of bytes, it is returned
// unchanged. No invalid characters are removed.
func truncate( int,  string) string {
	// This prioritize performance in the following order based on the most
	// common expected use-cases.
	//
	//  - Short values less than the default limit (128).
	//  - Strings with valid encodings that exceed the limit.
	//  - No limit.
	//  - Strings with invalid encodings that exceed the limit.
	if  < 0 || len() <=  {
		return 
	}

	// Optimistically, assume all valid UTF-8.
	var  strings.Builder
	 := 0
	for ,  := range  {
		if  != utf8.RuneError {
			++
			if  >  {
				return [:]
			}
			continue
		}

		,  := utf8.DecodeRuneInString([:])
		if  == 1 {
			// Invalid encoding.
			.Grow(len() - 1)
			_, _ = .WriteString([:])
			 = [:]
			break
		}
	}

	// Fast-path, no invalid input.
	if .Cap() == 0 {
		return 
	}

	// Truncate while validating UTF-8.
	for  := 0;  < len() &&  < ; {
		 := []
		if  < utf8.RuneSelf {
			// Optimization for single byte runes (common case).
			_ = .WriteByte()
			++
			++
			continue
		}

		,  := utf8.DecodeRuneInString([:])
		if  == 1 {
			// We checked for all 1-byte runes above, this is a RuneError.
			++
			continue
		}

		_, _ = .WriteString([ : +])
		 += 
		++
	}

	return .String()
}

// End ends the span. This method does nothing if the span is already ended or
// is not being recorded.
//
// The only SpanEndOption currently supported are [trace.WithTimestamp], and
// [trace.WithStackTrace].
//
// If this method is called while panicking an error event is added to the
// Span before ending it and the panic is continued.
func ( *recordingSpan) ( ...trace.SpanEndOption) {
	// Do not start by checking if the span is being recorded which requires
	// acquiring a lock. Make a minimal check that the span is not nil.
	if  == nil {
		return
	}

	// Store the end time as soon as possible to avoid artificially increasing
	// the span's duration in case some operation below takes a while.
	 := monotonicEndTime(.startTime)

	// Lock the span now that we have an end time and see if we need to do any more processing.
	.mu.Lock()
	if !.isRecording() {
		.mu.Unlock()
		return
	}

	 := trace.NewSpanEndConfig(...)
	if  := recover();  != nil {
		// Record but don't stop the panic.
		defer panic()
		 := []trace.EventOption{
			trace.WithAttributes(
				semconv.ExceptionType(typeStr()),
				semconv.ExceptionMessage(fmt.Sprint()),
			),
		}

		if .StackTrace() {
			 = append(, trace.WithAttributes(
				semconv.ExceptionStacktrace(recordStackTrace()),
			))
		}

		.addEvent(semconv.ExceptionEventName, ...)
	}

	if .executionTracerTaskEnd != nil {
		.mu.Unlock()
		.executionTracerTaskEnd()
		.mu.Lock()
	}

	// Setting endTime to non-zero marks the span as ended and not recording.
	if .Timestamp().IsZero() {
		.endTime = 
	} else {
		.endTime = .Timestamp()
	}
	.mu.Unlock()

	if .tracer.selfObservabilityEnabled {
		defer func() {
			// Add the span to the context to ensure the metric is recorded
			// with the correct span context.
			 := trace.ContextWithSpan(context.Background(), )
			 := spanLiveSet(.spanContext.IsSampled())
			.tracer.spanLiveMetric.AddSet(, -1, )
		}()
	}

	 := .tracer.provider.getSpanProcessors()
	if len() == 0 {
		return
	}
	 := .snapshot()
	for ,  := range  {
		.sp.OnEnd()
	}
}

// monotonicEndTime returns the end time at present but offset from start,
// monotonically.
//
// The monotonic clock is used in subtractions hence the duration since start
// added back to start gives end as a monotonic time. See
// https://golang.org/pkg/time/#hdr-Monotonic_Clocks
func monotonicEndTime( time.Time) time.Time {
	return .Add(time.Since())
}

// RecordError will record err as a span event for this span. An additional call to
// SetStatus is required if the Status of the Span should be set to Error, this method
// does not change the Span status. If this span is not being recorded or err is nil
// than this method does nothing.
func ( *recordingSpan) ( error,  ...trace.EventOption) {
	if  == nil ||  == nil {
		return
	}

	.mu.Lock()
	defer .mu.Unlock()
	if !.isRecording() {
		return
	}

	 = append(, trace.WithAttributes(
		semconv.ExceptionType(typeStr()),
		semconv.ExceptionMessage(.Error()),
	))

	 := trace.NewEventConfig(...)
	if .StackTrace() {
		 = append(, trace.WithAttributes(
			semconv.ExceptionStacktrace(recordStackTrace()),
		))
	}

	.addEvent(semconv.ExceptionEventName, ...)
}

func typeStr( any) string {
	 := reflect.TypeOf()
	if .PkgPath() == "" && .Name() == "" {
		// Likely a builtin type.
		return .String()
	}
	return fmt.Sprintf("%s.%s", .PkgPath(), .Name())
}

func recordStackTrace() string {
	 := make([]byte, 2048)
	 := runtime.Stack(, false)

	return string([0:])
}

// AddEvent adds an event with the provided name and options. If this span is
// not being recorded then this method does nothing.
func ( *recordingSpan) ( string,  ...trace.EventOption) {
	if  == nil {
		return
	}

	.mu.Lock()
	defer .mu.Unlock()
	if !.isRecording() {
		return
	}
	.addEvent(, ...)
}

// addEvent adds an event with the provided name and options.
//
// This method assumes s.mu.Lock is held by the caller.
func ( *recordingSpan) ( string,  ...trace.EventOption) {
	 := trace.NewEventConfig(...)
	 := Event{Name: , Attributes: .Attributes(), Time: .Timestamp()}

	// Discard attributes over limit.
	 := .tracer.provider.spanLimits.AttributePerEventCountLimit
	if  == 0 {
		// Drop all attributes.
		.DroppedAttributeCount = len(.Attributes)
		.Attributes = nil
	} else if  > 0 && len(.Attributes) >  {
		// Drop over capacity.
		.DroppedAttributeCount = len(.Attributes) - 
		.Attributes = .Attributes[:]
	}

	.events.add()
}

// SetName sets the name of this span. If this span is not being recorded than
// this method does nothing.
func ( *recordingSpan) ( string) {
	if  == nil {
		return
	}

	.mu.Lock()
	defer .mu.Unlock()
	if !.isRecording() {
		return
	}
	.name = 
}

// Name returns the name of this span.
func ( *recordingSpan) () string {
	.mu.Lock()
	defer .mu.Unlock()
	return .name
}

// Name returns the SpanContext of this span's parent span.
func ( *recordingSpan) () trace.SpanContext {
	.mu.Lock()
	defer .mu.Unlock()
	return .parent
}

// SpanKind returns the SpanKind of this span.
func ( *recordingSpan) () trace.SpanKind {
	.mu.Lock()
	defer .mu.Unlock()
	return .spanKind
}

// StartTime returns the time this span started.
func ( *recordingSpan) () time.Time {
	.mu.Lock()
	defer .mu.Unlock()
	return .startTime
}

// EndTime returns the time this span ended. For spans that have not yet
// ended, the returned value will be the zero value of time.Time.
func ( *recordingSpan) () time.Time {
	.mu.Lock()
	defer .mu.Unlock()
	return .endTime
}

// Attributes returns the attributes of this span.
//
// The order of the returned attributes is not guaranteed to be stable.
func ( *recordingSpan) () []attribute.KeyValue {
	.mu.Lock()
	defer .mu.Unlock()
	.dedupeAttrs()
	return .attributes
}

// dedupeAttrs deduplicates the attributes of s to fit capacity.
//
// This method assumes s.mu.Lock is held by the caller.
func ( *recordingSpan) () {
	// Do not set a capacity when creating this map. Benchmark testing has
	// showed this to only add unused memory allocations in general use.
	 := make(map[attribute.Key]int, len(.attributes))
	.dedupeAttrsFromRecord()
}

// dedupeAttrsFromRecord deduplicates the attributes of s to fit capacity
// using record as the record of unique attribute keys to their index.
//
// This method assumes s.mu.Lock is held by the caller.
func ( *recordingSpan) ( map[attribute.Key]int) {
	// Use the fact that slices share the same backing array.
	 := .attributes[:0]
	for ,  := range .attributes {
		if ,  := [.Key];  {
			[] = 
		} else {
			 = append(, )
			[.Key] = len() - 1
		}
	}
	clear(.attributes[len():]) // Erase unneeded elements to let GC collect objects.
	.attributes = 
}

// Links returns the links of this span.
func ( *recordingSpan) () []Link {
	.mu.Lock()
	defer .mu.Unlock()
	if len(.links.queue) == 0 {
		return []Link{}
	}
	return .links.copy()
}

// Events returns the events of this span.
func ( *recordingSpan) () []Event {
	.mu.Lock()
	defer .mu.Unlock()
	if len(.events.queue) == 0 {
		return []Event{}
	}
	return .events.copy()
}

// Status returns the status of this span.
func ( *recordingSpan) () Status {
	.mu.Lock()
	defer .mu.Unlock()
	return .status
}

// InstrumentationScope returns the instrumentation.Scope associated with
// the Tracer that created this span.
func ( *recordingSpan) () instrumentation.Scope {
	.mu.Lock()
	defer .mu.Unlock()
	return .tracer.instrumentationScope
}

// InstrumentationLibrary returns the instrumentation.Library associated with
// the Tracer that created this span.
func ( *recordingSpan) () instrumentation.Library { //nolint:staticcheck // This method needs to be define for backwards compatibility
	.mu.Lock()
	defer .mu.Unlock()
	return .tracer.instrumentationScope
}

// Resource returns the Resource associated with the Tracer that created this
// span.
func ( *recordingSpan) () *resource.Resource {
	.mu.Lock()
	defer .mu.Unlock()
	return .tracer.provider.resource
}

func ( *recordingSpan) ( trace.Link) {
	if  == nil {
		return
	}
	if !.SpanContext.IsValid() && len(.Attributes) == 0 &&
		.SpanContext.TraceState().Len() == 0 {
		return
	}

	.mu.Lock()
	defer .mu.Unlock()
	if !.isRecording() {
		return
	}

	 := Link{SpanContext: .SpanContext, Attributes: .Attributes}

	// Discard attributes over limit.
	 := .tracer.provider.spanLimits.AttributePerLinkCountLimit
	if  == 0 {
		// Drop all attributes.
		.DroppedAttributeCount = len(.Attributes)
		.Attributes = nil
	} else if  > 0 && len(.Attributes) >  {
		.DroppedAttributeCount = len(.Attributes) - 
		.Attributes = .Attributes[:]
	}

	.links.add()
}

// DroppedAttributes returns the number of attributes dropped by the span
// due to limits being reached.
func ( *recordingSpan) () int {
	.mu.Lock()
	defer .mu.Unlock()
	return .droppedAttributes
}

// DroppedLinks returns the number of links dropped by the span due to limits
// being reached.
func ( *recordingSpan) () int {
	.mu.Lock()
	defer .mu.Unlock()
	return .links.droppedCount
}

// DroppedEvents returns the number of events dropped by the span due to
// limits being reached.
func ( *recordingSpan) () int {
	.mu.Lock()
	defer .mu.Unlock()
	return .events.droppedCount
}

// ChildSpanCount returns the count of spans that consider the span a
// direct parent.
func ( *recordingSpan) () int {
	.mu.Lock()
	defer .mu.Unlock()
	return .childSpanCount
}

// TracerProvider returns a trace.TracerProvider that can be used to generate
// additional Spans on the same telemetry pipeline as the current Span.
func ( *recordingSpan) () trace.TracerProvider {
	return .tracer.provider
}

// snapshot creates a read-only copy of the current state of the span.
func ( *recordingSpan) () ReadOnlySpan {
	var  snapshot
	.mu.Lock()
	defer .mu.Unlock()

	.endTime = .endTime
	.instrumentationScope = .tracer.instrumentationScope
	.name = .name
	.parent = .parent
	.resource = .tracer.provider.resource
	.spanContext = .spanContext
	.spanKind = .spanKind
	.startTime = .startTime
	.status = .status
	.childSpanCount = .childSpanCount

	if len(.attributes) > 0 {
		.dedupeAttrs()
		.attributes = .attributes
	}
	.droppedAttributeCount = .droppedAttributes
	if len(.events.queue) > 0 {
		.events = .events.copy()
		.droppedEventCount = .events.droppedCount
	}
	if len(.links.queue) > 0 {
		.links = .links.copy()
		.droppedLinkCount = .links.droppedCount
	}
	return &
}

func ( *recordingSpan) () {
	if  == nil {
		return
	}

	.mu.Lock()
	defer .mu.Unlock()
	if !.isRecording() {
		return
	}
	.childSpanCount++
}

func (*recordingSpan) () {}

// runtimeTrace starts a "runtime/trace".Task for the span and returns a
// context containing the task.
func ( *recordingSpan) ( context.Context) context.Context {
	if !rt.IsEnabled() {
		// Avoid additional overhead if runtime/trace is not enabled.
		return 
	}
	,  := rt.NewTask(, .name)

	.mu.Lock()
	.executionTracerTaskEnd = .End
	.mu.Unlock()

	return 
}

// nonRecordingSpan is a minimal implementation of the OpenTelemetry Span API
// that wraps a SpanContext. It performs no operations other than to return
// the wrapped SpanContext or TracerProvider that created it.
type nonRecordingSpan struct {
	embedded.Span

	// tracer is the SDK tracer that created this span.
	tracer *tracer
	sc     trace.SpanContext
}

var _ trace.Span = nonRecordingSpan{}

// SpanContext returns the wrapped SpanContext.
func ( nonRecordingSpan) () trace.SpanContext { return .sc }

// IsRecording always returns false.
func (nonRecordingSpan) () bool { return false }

// SetStatus does nothing.
func (nonRecordingSpan) (codes.Code, string) {}

// SetError does nothing.
func (nonRecordingSpan) (bool) {}

// SetAttributes does nothing.
func (nonRecordingSpan) (...attribute.KeyValue) {}

// End does nothing.
func (nonRecordingSpan) (...trace.SpanEndOption) {}

// RecordError does nothing.
func (nonRecordingSpan) (error, ...trace.EventOption) {}

// AddEvent does nothing.
func (nonRecordingSpan) (string, ...trace.EventOption) {}

// AddLink does nothing.
func (nonRecordingSpan) (trace.Link) {}

// SetName does nothing.
func (nonRecordingSpan) (string) {}

// TracerProvider returns the trace.TracerProvider that provided the Tracer
// that created this span.
func ( nonRecordingSpan) () trace.TracerProvider { return .tracer.provider }

func isRecording( SamplingResult) bool {
	return .Decision == RecordOnly || .Decision == RecordAndSample
}

func isSampled( SamplingResult) bool {
	return .Decision == RecordAndSample
}

// Status is the classified state of a Span.
type Status struct {
	// Code is an identifier of a Spans state classification.
	Code codes.Code
	// Description is a user hint about why that status was set. It is only
	// applicable when Code is Error.
	Description string
}