Copyright The OpenTelemetry Authors 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 internal
This file contains the forwarding implementation of the trace.Provider used asthe default global instance. Prior to initialization of an SDK, Tracersreturned by the global Provider will provide no-op functionality. This meansthat all Span created prior to initialization are no-op Spans.
Once an SDK has been initialized, all provided no-op Tracers are swapped forTracers provided by the SDK defined Provider. However, any Span started priorto this initialization does not change its behavior. Meaning, the Span remainsa no-op Span.
The implementation to track and swap Tracers locks all new Tracer creationuntil the swap is complete. This assumes that this operation is notperformance-critical. If that assumption is incorrect, be sure to configure anSDK prior to any Tracer creation.

import (
	
	

	
)
traceProvider is a placeholder for a configured SDK Provider. All Provider functionality is forwarded to a delegate once configured.
Compile-time guarantee that traceProvider implements the trace.Provider interface.
setDelegate configures p to delegate all Provider functionality to provider. All Tracers provided prior to this function call are switched out to be Tracers provided by provider. Delegation only happens on the first call to this method. All subsequent calls result in no delegation changes.
func ( *traceProvider) ( trace.Provider) {
	if .delegate != nil {
		return
	}

	.mtx.Lock()
	defer .mtx.Unlock()

	.delegate = 
	for ,  := range .tracers {
		.setDelegate()
	}

	.tracers = nil
}
Tracer implements trace.Provider.
func ( *traceProvider) ( string,  ...trace.TracerOption) trace.Tracer {
	.mtx.Lock()
	defer .mtx.Unlock()

	if .delegate != nil {
		return .delegate.Tracer()
	}

	 := &tracer{name: , opts: }
	.tracers = append(.tracers, )
	return 
}
tracer is a placeholder for a trace.Tracer. All Tracer functionality is forwarded to a delegate once configured. Otherwise, all functionality is forwarded to a NoopTracer.
Compile-time guarantee that tracer implements the trace.Tracer interface.
var _ trace.Tracer = &tracer{}
setDelegate configures t to delegate all Tracer functionality to Tracers created by provider. All subsequent calls to the Tracer methods will be passed to the delegate. Delegation only happens on the first call to this method. All subsequent calls result in no delegation changes.
func ( *tracer) ( trace.Provider) {
	.once.Do(func() { .delegate = .Tracer(.name, .opts...) })
}
Start implements trace.Tracer by forwarding the call to t.delegate if set, otherwise it forwards the call to a NoopTracer.
func ( *tracer) ( context.Context,  string,  ...trace.StartOption) (context.Context, trace.Span) {
	if .delegate != nil {
		return .delegate.Start(, , ...)
	}
	return trace.NoopTracer{}.Start(, , ...)