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

package propagation // import "go.opentelemetry.io/otel/propagation"

import (
	
	
)

// TextMapCarrier is the storage medium used by a TextMapPropagator.
// See ValuesGetter for how a TextMapCarrier can get multiple values for a key.
type TextMapCarrier interface {
	// DO NOT CHANGE: any modification will not be backwards compatible and
	// must never be done outside of a new major release.

	// Get returns the value associated with the passed key.
	Get(key string) string
	// DO NOT CHANGE: any modification will not be backwards compatible and
	// must never be done outside of a new major release.

	// Set stores the key-value pair.
	Set(key, value string)
	// DO NOT CHANGE: any modification will not be backwards compatible and
	// must never be done outside of a new major release.

	// Keys lists the keys stored in this carrier.
	Keys() []string
	// DO NOT CHANGE: any modification will not be backwards compatible and
	// must never be done outside of a new major release.
}

// ValuesGetter can return multiple values for a single key,
// with contrast to TextMapCarrier.Get which returns a single value.
type ValuesGetter interface {
	// DO NOT CHANGE: any modification will not be backwards compatible and
	// must never be done outside of a new major release.

	// Values returns all values associated with the passed key.
	Values(key string) []string
	// DO NOT CHANGE: any modification will not be backwards compatible and
	// must never be done outside of a new major release.
}

// MapCarrier is a TextMapCarrier that uses a map held in memory as a storage
// medium for propagated key-value pairs.
type MapCarrier map[string]string

// Compile time check that MapCarrier implements the TextMapCarrier.
var _ TextMapCarrier = MapCarrier{}

// Get returns the value associated with the passed key.
func ( MapCarrier) ( string) string {
	return []
}

// Set stores the key-value pair.
func ( MapCarrier) (,  string) {
	[] = 
}

// Keys lists the keys stored in this carrier.
func ( MapCarrier) () []string {
	 := make([]string, 0, len())
	for  := range  {
		 = append(, )
	}
	return 
}

// HeaderCarrier adapts http.Header to satisfy the TextMapCarrier and ValuesGetter interfaces.
type HeaderCarrier http.Header

// Compile time check that HeaderCarrier implements ValuesGetter.
var _ TextMapCarrier = HeaderCarrier{}

// Compile time check that HeaderCarrier implements TextMapCarrier.
var _ ValuesGetter = HeaderCarrier{}

// Get returns the first value associated with the passed key.
func ( HeaderCarrier) ( string) string {
	return http.Header().Get()
}

// Values returns all values associated with the passed key.
func ( HeaderCarrier) ( string) []string {
	return http.Header().Values()
}

// Set stores the key-value pair.
func ( HeaderCarrier) (,  string) {
	http.Header().Set(, )
}

// Keys lists the keys stored in this carrier.
func ( HeaderCarrier) () []string {
	 := make([]string, 0, len())
	for  := range  {
		 = append(, )
	}
	return 
}

// TextMapPropagator propagates cross-cutting concerns as key-value text
// pairs within a carrier that travels in-band across process boundaries.
type TextMapPropagator interface {
	// DO NOT CHANGE: any modification will not be backwards compatible and
	// must never be done outside of a new major release.

	// Inject set cross-cutting concerns from the Context into the carrier.
	Inject(ctx context.Context, carrier TextMapCarrier)
	// DO NOT CHANGE: any modification will not be backwards compatible and
	// must never be done outside of a new major release.

	// Extract reads cross-cutting concerns from the carrier into a Context.
	// Implementations may check if the carrier implements ValuesGetter,
	// to support extraction of multiple values per key.
	Extract(ctx context.Context, carrier TextMapCarrier) context.Context
	// DO NOT CHANGE: any modification will not be backwards compatible and
	// must never be done outside of a new major release.

	// Fields returns the keys whose values are set with Inject.
	Fields() []string
	// DO NOT CHANGE: any modification will not be backwards compatible and
	// must never be done outside of a new major release.
}

type compositeTextMapPropagator []TextMapPropagator

func ( compositeTextMapPropagator) ( context.Context,  TextMapCarrier) {
	for ,  := range  {
		.Inject(, )
	}
}

func ( compositeTextMapPropagator) ( context.Context,  TextMapCarrier) context.Context {
	for ,  := range  {
		 = .Extract(, )
	}
	return 
}

func ( compositeTextMapPropagator) () []string {
	 := make(map[string]struct{})
	for ,  := range  {
		for ,  := range .Fields() {
			[] = struct{}{}
		}
	}

	 := make([]string, 0, len())
	for  := range  {
		 = append(, )
	}
	return 
}

// NewCompositeTextMapPropagator returns a unified TextMapPropagator from the
// group of passed TextMapPropagator. This allows different cross-cutting
// concerns to be propagates in a unified manner.
//
// The returned TextMapPropagator will inject and extract cross-cutting
// concerns in the order the TextMapPropagators were provided. Additionally,
// the Fields method will return a de-duplicated slice of the keys that are
// set with the Inject method.
func ( ...TextMapPropagator) TextMapPropagator {
	return compositeTextMapPropagator()
}