// 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.

// Code generated by "model/internal/cmd/pdatagen/main.go". DO NOT EDIT.
// To regenerate this file run "go run model/internal/cmd/pdatagen/main.go".

package pmetric

import (
	"sort"

	"go.opentelemetry.io/collector/pdata/internal"
	"go.opentelemetry.io/collector/pdata/internal/data"
	otlpmetrics "go.opentelemetry.io/collector/pdata/internal/data/protogen/metrics/v1"
	"go.opentelemetry.io/collector/pdata/pcommon"
)

// ResourceMetricsSlice logically represents a slice of ResourceMetrics.
//
// This is a reference type. If passed by value and callee modifies it, the
// caller will see the modification.
//
// Must use NewResourceMetricsSlice function to create new instances.
// Important: zero-initialized instance is not valid for use.
type ResourceMetricsSlice internal.ResourceMetricsSlice

func newResourceMetricsSlice(orig *[]*otlpmetrics.ResourceMetrics) ResourceMetricsSlice {
	return ResourceMetricsSlice(internal.NewResourceMetricsSlice(orig))
}

func (ms ResourceMetricsSlice) getOrig() *[]*otlpmetrics.ResourceMetrics {
	return internal.GetOrigResourceMetricsSlice(internal.ResourceMetricsSlice(ms))
}

// NewResourceMetricsSlice creates a ResourceMetricsSlice with 0 elements.
// Can use "EnsureCapacity" to initialize with a given capacity.
func NewResourceMetricsSlice() ResourceMetricsSlice {
	orig := []*otlpmetrics.ResourceMetrics(nil)
	return newResourceMetricsSlice(&orig)
}

// Len returns the number of elements in the slice.
//
// Returns "0" for a newly instance created with "NewResourceMetricsSlice()".
func (es ResourceMetricsSlice) Len() int {
	return len(*es.getOrig())
}

// At returns the element at the given index.
//
// This function is used mostly for iterating over all the values in the slice:
//
//	for i := 0; i < es.Len(); i++ {
//	    e := es.At(i)
//	    ... // Do something with the element
//	}
func (es ResourceMetricsSlice) At(ix int) ResourceMetrics {
	return newResourceMetrics((*es.getOrig())[ix])
}

// CopyTo copies all elements from the current slice to the dest.
func (es ResourceMetricsSlice) CopyTo(dest ResourceMetricsSlice) {
	srcLen := es.Len()
	destCap := cap(*dest.getOrig())
	if srcLen <= destCap {
		(*dest.getOrig()) = (*dest.getOrig())[:srcLen:destCap]
		for i := range *es.getOrig() {
			newResourceMetrics((*es.getOrig())[i]).CopyTo(newResourceMetrics((*dest.getOrig())[i]))
		}
		return
	}
	origs := make([]otlpmetrics.ResourceMetrics, srcLen)
	wrappers := make([]*otlpmetrics.ResourceMetrics, srcLen)
	for i := range *es.getOrig() {
		wrappers[i] = &origs[i]
		newResourceMetrics((*es.getOrig())[i]).CopyTo(newResourceMetrics(wrappers[i]))
	}
	*dest.getOrig() = wrappers
}

// EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
// 1. If the newCap <= cap then no change in capacity.
// 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
//
// Here is how a new ResourceMetricsSlice can be initialized:
//
//	es := NewResourceMetricsSlice()
//	es.EnsureCapacity(4)
//	for i := 0; i < 4; i++ {
//	    e := es.AppendEmpty()
//	    // Here should set all the values for e.
//	}
func (es ResourceMetricsSlice) EnsureCapacity(newCap int) {
	oldCap := cap(*es.getOrig())
	if newCap <= oldCap {
		return
	}

	newOrig := make([]*otlpmetrics.ResourceMetrics, len(*es.getOrig()), newCap)
	copy(newOrig, *es.getOrig())
	*es.getOrig() = newOrig
}

// AppendEmpty will append to the end of the slice an empty ResourceMetrics.
// It returns the newly added ResourceMetrics.
func (es ResourceMetricsSlice) AppendEmpty() ResourceMetrics {
	*es.getOrig() = append(*es.getOrig(), &otlpmetrics.ResourceMetrics{})
	return es.At(es.Len() - 1)
}

// Sort sorts the ResourceMetrics elements within ResourceMetricsSlice given the
// provided less function so that two instances of ResourceMetricsSlice
// can be compared.
//
// Returns the same instance to allow nicer code like:
//
//	lessFunc := func(a, b ResourceMetrics) bool {
//	  return a.Name() < b.Name() // choose any comparison here
//	}
//	assert.Equal(t, expected.Sort(lessFunc), actual.Sort(lessFunc))
func (es ResourceMetricsSlice) Sort(less func(a, b ResourceMetrics) bool) ResourceMetricsSlice {
	sort.SliceStable(*es.getOrig(), func(i, j int) bool { return less(es.At(i), es.At(j)) })
	return es
}

// MoveAndAppendTo moves all elements from the current slice and appends them to the dest.
// The current slice will be cleared.
func (es ResourceMetricsSlice) MoveAndAppendTo(dest ResourceMetricsSlice) {
	if *dest.getOrig() == nil {
		// We can simply move the entire vector and avoid any allocations.
		*dest.getOrig() = *es.getOrig()
	} else {
		*dest.getOrig() = append(*dest.getOrig(), *es.getOrig()...)
	}
	*es.getOrig() = nil
}

// RemoveIf calls f sequentially for each element present in the slice.
// If f returns true, the element is removed from the slice.
func (es ResourceMetricsSlice) RemoveIf(f func(ResourceMetrics) bool) {
	newLen := 0
	for i := 0; i < len(*es.getOrig()); i++ {
		if f(es.At(i)) {
			continue
		}
		if newLen == i {
			// Nothing to move, element is at the right place.
			newLen++
			continue
		}
		(*es.getOrig())[newLen] = (*es.getOrig())[i]
		newLen++
	}
	// TODO: Prevent memory leak by erasing truncated values.
	*es.getOrig() = (*es.getOrig())[:newLen]
}

// ResourceMetrics is a collection of metrics from a Resource.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewResourceMetrics function to create new instances.
// Important: zero-initialized instance is not valid for use.

type ResourceMetrics internal.ResourceMetrics

func newResourceMetrics(orig *otlpmetrics.ResourceMetrics) ResourceMetrics {
	return ResourceMetrics(internal.NewResourceMetrics(orig))
}

func (ms ResourceMetrics) getOrig() *otlpmetrics.ResourceMetrics {
	return internal.GetOrigResourceMetrics(internal.ResourceMetrics(ms))
}

// NewResourceMetrics creates a new empty ResourceMetrics.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewResourceMetrics() ResourceMetrics {
	return newResourceMetrics(&otlpmetrics.ResourceMetrics{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms ResourceMetrics) MoveTo(dest ResourceMetrics) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.ResourceMetrics{}
}

// Resource returns the resource associated with this ResourceMetrics.
func (ms ResourceMetrics) Resource() pcommon.Resource {
	return pcommon.Resource(internal.NewResource(&ms.getOrig().Resource))
}

// SchemaUrl returns the schemaurl associated with this ResourceMetrics.
func (ms ResourceMetrics) SchemaUrl() string {
	return ms.getOrig().SchemaUrl
}

// SetSchemaUrl replaces the schemaurl associated with this ResourceMetrics.
func (ms ResourceMetrics) SetSchemaUrl(v string) {
	ms.getOrig().SchemaUrl = v
}

// ScopeMetrics returns the ScopeMetrics associated with this ResourceMetrics.
func (ms ResourceMetrics) ScopeMetrics() ScopeMetricsSlice {
	return ScopeMetricsSlice(internal.NewScopeMetricsSlice(&ms.getOrig().ScopeMetrics))
}

// CopyTo copies all properties from the current struct to the dest.
func (ms ResourceMetrics) CopyTo(dest ResourceMetrics) {
	ms.Resource().CopyTo(dest.Resource())
	dest.SetSchemaUrl(ms.SchemaUrl())
	ms.ScopeMetrics().CopyTo(dest.ScopeMetrics())
}

// ScopeMetricsSlice logically represents a slice of ScopeMetrics.
//
// This is a reference type. If passed by value and callee modifies it, the
// caller will see the modification.
//
// Must use NewScopeMetricsSlice function to create new instances.
// Important: zero-initialized instance is not valid for use.
type ScopeMetricsSlice internal.ScopeMetricsSlice

func newScopeMetricsSlice(orig *[]*otlpmetrics.ScopeMetrics) ScopeMetricsSlice {
	return ScopeMetricsSlice(internal.NewScopeMetricsSlice(orig))
}

func (ms ScopeMetricsSlice) getOrig() *[]*otlpmetrics.ScopeMetrics {
	return internal.GetOrigScopeMetricsSlice(internal.ScopeMetricsSlice(ms))
}

// NewScopeMetricsSlice creates a ScopeMetricsSlice with 0 elements.
// Can use "EnsureCapacity" to initialize with a given capacity.
func NewScopeMetricsSlice() ScopeMetricsSlice {
	orig := []*otlpmetrics.ScopeMetrics(nil)
	return newScopeMetricsSlice(&orig)
}

// Len returns the number of elements in the slice.
//
// Returns "0" for a newly instance created with "NewScopeMetricsSlice()".
func (es ScopeMetricsSlice) Len() int {
	return len(*es.getOrig())
}

// At returns the element at the given index.
//
// This function is used mostly for iterating over all the values in the slice:
//
//	for i := 0; i < es.Len(); i++ {
//	    e := es.At(i)
//	    ... // Do something with the element
//	}
func (es ScopeMetricsSlice) At(ix int) ScopeMetrics {
	return newScopeMetrics((*es.getOrig())[ix])
}

// CopyTo copies all elements from the current slice to the dest.
func (es ScopeMetricsSlice) CopyTo(dest ScopeMetricsSlice) {
	srcLen := es.Len()
	destCap := cap(*dest.getOrig())
	if srcLen <= destCap {
		(*dest.getOrig()) = (*dest.getOrig())[:srcLen:destCap]
		for i := range *es.getOrig() {
			newScopeMetrics((*es.getOrig())[i]).CopyTo(newScopeMetrics((*dest.getOrig())[i]))
		}
		return
	}
	origs := make([]otlpmetrics.ScopeMetrics, srcLen)
	wrappers := make([]*otlpmetrics.ScopeMetrics, srcLen)
	for i := range *es.getOrig() {
		wrappers[i] = &origs[i]
		newScopeMetrics((*es.getOrig())[i]).CopyTo(newScopeMetrics(wrappers[i]))
	}
	*dest.getOrig() = wrappers
}

// EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
// 1. If the newCap <= cap then no change in capacity.
// 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
//
// Here is how a new ScopeMetricsSlice can be initialized:
//
//	es := NewScopeMetricsSlice()
//	es.EnsureCapacity(4)
//	for i := 0; i < 4; i++ {
//	    e := es.AppendEmpty()
//	    // Here should set all the values for e.
//	}
func (es ScopeMetricsSlice) EnsureCapacity(newCap int) {
	oldCap := cap(*es.getOrig())
	if newCap <= oldCap {
		return
	}

	newOrig := make([]*otlpmetrics.ScopeMetrics, len(*es.getOrig()), newCap)
	copy(newOrig, *es.getOrig())
	*es.getOrig() = newOrig
}

// AppendEmpty will append to the end of the slice an empty ScopeMetrics.
// It returns the newly added ScopeMetrics.
func (es ScopeMetricsSlice) AppendEmpty() ScopeMetrics {
	*es.getOrig() = append(*es.getOrig(), &otlpmetrics.ScopeMetrics{})
	return es.At(es.Len() - 1)
}

// Sort sorts the ScopeMetrics elements within ScopeMetricsSlice given the
// provided less function so that two instances of ScopeMetricsSlice
// can be compared.
//
// Returns the same instance to allow nicer code like:
//
//	lessFunc := func(a, b ScopeMetrics) bool {
//	  return a.Name() < b.Name() // choose any comparison here
//	}
//	assert.Equal(t, expected.Sort(lessFunc), actual.Sort(lessFunc))
func (es ScopeMetricsSlice) Sort(less func(a, b ScopeMetrics) bool) ScopeMetricsSlice {
	sort.SliceStable(*es.getOrig(), func(i, j int) bool { return less(es.At(i), es.At(j)) })
	return es
}

// MoveAndAppendTo moves all elements from the current slice and appends them to the dest.
// The current slice will be cleared.
func (es ScopeMetricsSlice) MoveAndAppendTo(dest ScopeMetricsSlice) {
	if *dest.getOrig() == nil {
		// We can simply move the entire vector and avoid any allocations.
		*dest.getOrig() = *es.getOrig()
	} else {
		*dest.getOrig() = append(*dest.getOrig(), *es.getOrig()...)
	}
	*es.getOrig() = nil
}

// RemoveIf calls f sequentially for each element present in the slice.
// If f returns true, the element is removed from the slice.
func (es ScopeMetricsSlice) RemoveIf(f func(ScopeMetrics) bool) {
	newLen := 0
	for i := 0; i < len(*es.getOrig()); i++ {
		if f(es.At(i)) {
			continue
		}
		if newLen == i {
			// Nothing to move, element is at the right place.
			newLen++
			continue
		}
		(*es.getOrig())[newLen] = (*es.getOrig())[i]
		newLen++
	}
	// TODO: Prevent memory leak by erasing truncated values.
	*es.getOrig() = (*es.getOrig())[:newLen]
}

// ScopeMetrics is a collection of metrics from a LibraryInstrumentation.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewScopeMetrics function to create new instances.
// Important: zero-initialized instance is not valid for use.

type ScopeMetrics internal.ScopeMetrics

func newScopeMetrics(orig *otlpmetrics.ScopeMetrics) ScopeMetrics {
	return ScopeMetrics(internal.NewScopeMetrics(orig))
}

func (ms ScopeMetrics) getOrig() *otlpmetrics.ScopeMetrics {
	return internal.GetOrigScopeMetrics(internal.ScopeMetrics(ms))
}

// NewScopeMetrics creates a new empty ScopeMetrics.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewScopeMetrics() ScopeMetrics {
	return newScopeMetrics(&otlpmetrics.ScopeMetrics{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms ScopeMetrics) MoveTo(dest ScopeMetrics) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.ScopeMetrics{}
}

// Scope returns the scope associated with this ScopeMetrics.
func (ms ScopeMetrics) Scope() pcommon.InstrumentationScope {
	return pcommon.InstrumentationScope(internal.NewInstrumentationScope(&ms.getOrig().Scope))
}

// SchemaUrl returns the schemaurl associated with this ScopeMetrics.
func (ms ScopeMetrics) SchemaUrl() string {
	return ms.getOrig().SchemaUrl
}

// SetSchemaUrl replaces the schemaurl associated with this ScopeMetrics.
func (ms ScopeMetrics) SetSchemaUrl(v string) {
	ms.getOrig().SchemaUrl = v
}

// Metrics returns the Metrics associated with this ScopeMetrics.
func (ms ScopeMetrics) Metrics() MetricSlice {
	return MetricSlice(internal.NewMetricSlice(&ms.getOrig().Metrics))
}

// CopyTo copies all properties from the current struct to the dest.
func (ms ScopeMetrics) CopyTo(dest ScopeMetrics) {
	ms.Scope().CopyTo(dest.Scope())
	dest.SetSchemaUrl(ms.SchemaUrl())
	ms.Metrics().CopyTo(dest.Metrics())
}

// MetricSlice logically represents a slice of Metric.
//
// This is a reference type. If passed by value and callee modifies it, the
// caller will see the modification.
//
// Must use NewMetricSlice function to create new instances.
// Important: zero-initialized instance is not valid for use.
type MetricSlice internal.MetricSlice

func newMetricSlice(orig *[]*otlpmetrics.Metric) MetricSlice {
	return MetricSlice(internal.NewMetricSlice(orig))
}

func (ms MetricSlice) getOrig() *[]*otlpmetrics.Metric {
	return internal.GetOrigMetricSlice(internal.MetricSlice(ms))
}

// NewMetricSlice creates a MetricSlice with 0 elements.
// Can use "EnsureCapacity" to initialize with a given capacity.
func NewMetricSlice() MetricSlice {
	orig := []*otlpmetrics.Metric(nil)
	return newMetricSlice(&orig)
}

// Len returns the number of elements in the slice.
//
// Returns "0" for a newly instance created with "NewMetricSlice()".
func (es MetricSlice) Len() int {
	return len(*es.getOrig())
}

// At returns the element at the given index.
//
// This function is used mostly for iterating over all the values in the slice:
//
//	for i := 0; i < es.Len(); i++ {
//	    e := es.At(i)
//	    ... // Do something with the element
//	}
func (es MetricSlice) At(ix int) Metric {
	return newMetric((*es.getOrig())[ix])
}

// CopyTo copies all elements from the current slice to the dest.
func (es MetricSlice) CopyTo(dest MetricSlice) {
	srcLen := es.Len()
	destCap := cap(*dest.getOrig())
	if srcLen <= destCap {
		(*dest.getOrig()) = (*dest.getOrig())[:srcLen:destCap]
		for i := range *es.getOrig() {
			newMetric((*es.getOrig())[i]).CopyTo(newMetric((*dest.getOrig())[i]))
		}
		return
	}
	origs := make([]otlpmetrics.Metric, srcLen)
	wrappers := make([]*otlpmetrics.Metric, srcLen)
	for i := range *es.getOrig() {
		wrappers[i] = &origs[i]
		newMetric((*es.getOrig())[i]).CopyTo(newMetric(wrappers[i]))
	}
	*dest.getOrig() = wrappers
}

// EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
// 1. If the newCap <= cap then no change in capacity.
// 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
//
// Here is how a new MetricSlice can be initialized:
//
//	es := NewMetricSlice()
//	es.EnsureCapacity(4)
//	for i := 0; i < 4; i++ {
//	    e := es.AppendEmpty()
//	    // Here should set all the values for e.
//	}
func (es MetricSlice) EnsureCapacity(newCap int) {
	oldCap := cap(*es.getOrig())
	if newCap <= oldCap {
		return
	}

	newOrig := make([]*otlpmetrics.Metric, len(*es.getOrig()), newCap)
	copy(newOrig, *es.getOrig())
	*es.getOrig() = newOrig
}

// AppendEmpty will append to the end of the slice an empty Metric.
// It returns the newly added Metric.
func (es MetricSlice) AppendEmpty() Metric {
	*es.getOrig() = append(*es.getOrig(), &otlpmetrics.Metric{})
	return es.At(es.Len() - 1)
}

// Sort sorts the Metric elements within MetricSlice given the
// provided less function so that two instances of MetricSlice
// can be compared.
//
// Returns the same instance to allow nicer code like:
//
//	lessFunc := func(a, b Metric) bool {
//	  return a.Name() < b.Name() // choose any comparison here
//	}
//	assert.Equal(t, expected.Sort(lessFunc), actual.Sort(lessFunc))
func (es MetricSlice) Sort(less func(a, b Metric) bool) MetricSlice {
	sort.SliceStable(*es.getOrig(), func(i, j int) bool { return less(es.At(i), es.At(j)) })
	return es
}

// MoveAndAppendTo moves all elements from the current slice and appends them to the dest.
// The current slice will be cleared.
func (es MetricSlice) MoveAndAppendTo(dest MetricSlice) {
	if *dest.getOrig() == nil {
		// We can simply move the entire vector and avoid any allocations.
		*dest.getOrig() = *es.getOrig()
	} else {
		*dest.getOrig() = append(*dest.getOrig(), *es.getOrig()...)
	}
	*es.getOrig() = nil
}

// RemoveIf calls f sequentially for each element present in the slice.
// If f returns true, the element is removed from the slice.
func (es MetricSlice) RemoveIf(f func(Metric) bool) {
	newLen := 0
	for i := 0; i < len(*es.getOrig()); i++ {
		if f(es.At(i)) {
			continue
		}
		if newLen == i {
			// Nothing to move, element is at the right place.
			newLen++
			continue
		}
		(*es.getOrig())[newLen] = (*es.getOrig())[i]
		newLen++
	}
	// TODO: Prevent memory leak by erasing truncated values.
	*es.getOrig() = (*es.getOrig())[:newLen]
}

// Metric represents one metric as a collection of datapoints.
// See Metric definition in OTLP: https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/metrics/v1/metrics.proto
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewMetric function to create new instances.
// Important: zero-initialized instance is not valid for use.

type Metric internal.Metric

func newMetric(orig *otlpmetrics.Metric) Metric {
	return Metric(internal.NewMetric(orig))
}

func (ms Metric) getOrig() *otlpmetrics.Metric {
	return internal.GetOrigMetric(internal.Metric(ms))
}

// NewMetric creates a new empty Metric.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewMetric() Metric {
	return newMetric(&otlpmetrics.Metric{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms Metric) MoveTo(dest Metric) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.Metric{}
}

// Name returns the name associated with this Metric.
func (ms Metric) Name() string {
	return ms.getOrig().Name
}

// SetName replaces the name associated with this Metric.
func (ms Metric) SetName(v string) {
	ms.getOrig().Name = v
}

// Description returns the description associated with this Metric.
func (ms Metric) Description() string {
	return ms.getOrig().Description
}

// SetDescription replaces the description associated with this Metric.
func (ms Metric) SetDescription(v string) {
	ms.getOrig().Description = v
}

// Unit returns the unit associated with this Metric.
func (ms Metric) Unit() string {
	return ms.getOrig().Unit
}

// SetUnit replaces the unit associated with this Metric.
func (ms Metric) SetUnit(v string) {
	ms.getOrig().Unit = v
}

// DataType returns the type of the data for this Metric.
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) DataType() MetricDataType {
	switch ms.getOrig().Data.(type) {
	case *otlpmetrics.Metric_Gauge:
		return MetricDataTypeGauge
	case *otlpmetrics.Metric_Sum:
		return MetricDataTypeSum
	case *otlpmetrics.Metric_Histogram:
		return MetricDataTypeHistogram
	case *otlpmetrics.Metric_ExponentialHistogram:
		return MetricDataTypeExponentialHistogram
	case *otlpmetrics.Metric_Summary:
		return MetricDataTypeSummary
	}
	return MetricDataTypeNone
}

// Gauge returns the gauge associated with this Metric.
//
// Calling this function when DataType() != MetricDataTypeGauge returns an invalid
// zero-initialized instance of Gauge. Note that using such Gauge instance can cause panic.
//
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) Gauge() Gauge {
	v, ok := ms.getOrig().GetData().(*otlpmetrics.Metric_Gauge)
	if !ok {
		return Gauge{}
	}
	return newGauge(v.Gauge)
}

// SetEmptyGauge sets an empty gauge to this Metric.
//
// After this, DataType() function will return MetricDataTypeGauge".
//
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) SetEmptyGauge() Gauge {
	val := &otlpmetrics.Gauge{}
	ms.getOrig().Data = &otlpmetrics.Metric_Gauge{Gauge: val}
	return newGauge(val)
}

// Sum returns the sum associated with this Metric.
//
// Calling this function when DataType() != MetricDataTypeSum returns an invalid
// zero-initialized instance of Sum. Note that using such Sum instance can cause panic.
//
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) Sum() Sum {
	v, ok := ms.getOrig().GetData().(*otlpmetrics.Metric_Sum)
	if !ok {
		return Sum{}
	}
	return newSum(v.Sum)
}

// SetEmptySum sets an empty sum to this Metric.
//
// After this, DataType() function will return MetricDataTypeSum".
//
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) SetEmptySum() Sum {
	val := &otlpmetrics.Sum{}
	ms.getOrig().Data = &otlpmetrics.Metric_Sum{Sum: val}
	return newSum(val)
}

// Histogram returns the histogram associated with this Metric.
//
// Calling this function when DataType() != MetricDataTypeHistogram returns an invalid
// zero-initialized instance of Histogram. Note that using such Histogram instance can cause panic.
//
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) Histogram() Histogram {
	v, ok := ms.getOrig().GetData().(*otlpmetrics.Metric_Histogram)
	if !ok {
		return Histogram{}
	}
	return newHistogram(v.Histogram)
}

// SetEmptyHistogram sets an empty histogram to this Metric.
//
// After this, DataType() function will return MetricDataTypeHistogram".
//
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) SetEmptyHistogram() Histogram {
	val := &otlpmetrics.Histogram{}
	ms.getOrig().Data = &otlpmetrics.Metric_Histogram{Histogram: val}
	return newHistogram(val)
}

// ExponentialHistogram returns the exponentialhistogram associated with this Metric.
//
// Calling this function when DataType() != MetricDataTypeExponentialHistogram returns an invalid
// zero-initialized instance of ExponentialHistogram. Note that using such ExponentialHistogram instance can cause panic.
//
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) ExponentialHistogram() ExponentialHistogram {
	v, ok := ms.getOrig().GetData().(*otlpmetrics.Metric_ExponentialHistogram)
	if !ok {
		return ExponentialHistogram{}
	}
	return newExponentialHistogram(v.ExponentialHistogram)
}

// SetEmptyExponentialHistogram sets an empty exponentialhistogram to this Metric.
//
// After this, DataType() function will return MetricDataTypeExponentialHistogram".
//
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) SetEmptyExponentialHistogram() ExponentialHistogram {
	val := &otlpmetrics.ExponentialHistogram{}
	ms.getOrig().Data = &otlpmetrics.Metric_ExponentialHistogram{ExponentialHistogram: val}
	return newExponentialHistogram(val)
}

// Summary returns the summary associated with this Metric.
//
// Calling this function when DataType() != MetricDataTypeSummary returns an invalid
// zero-initialized instance of Summary. Note that using such Summary instance can cause panic.
//
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) Summary() Summary {
	v, ok := ms.getOrig().GetData().(*otlpmetrics.Metric_Summary)
	if !ok {
		return Summary{}
	}
	return newSummary(v.Summary)
}

// SetEmptySummary sets an empty summary to this Metric.
//
// After this, DataType() function will return MetricDataTypeSummary".
//
// Calling this function on zero-initialized Metric will cause a panic.
func (ms Metric) SetEmptySummary() Summary {
	val := &otlpmetrics.Summary{}
	ms.getOrig().Data = &otlpmetrics.Metric_Summary{Summary: val}
	return newSummary(val)
}

// CopyTo copies all properties from the current struct to the dest.
func (ms Metric) CopyTo(dest Metric) {
	dest.SetName(ms.Name())
	dest.SetDescription(ms.Description())
	dest.SetUnit(ms.Unit())
	switch ms.DataType() {
	case MetricDataTypeGauge:
		ms.Gauge().CopyTo(dest.SetEmptyGauge())
	case MetricDataTypeSum:
		ms.Sum().CopyTo(dest.SetEmptySum())
	case MetricDataTypeHistogram:
		ms.Histogram().CopyTo(dest.SetEmptyHistogram())
	case MetricDataTypeExponentialHistogram:
		ms.ExponentialHistogram().CopyTo(dest.SetEmptyExponentialHistogram())
	case MetricDataTypeSummary:
		ms.Summary().CopyTo(dest.SetEmptySummary())
	}

}

// Gauge represents the type of a numeric metric that always exports the "current value" for every data point.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewGauge function to create new instances.
// Important: zero-initialized instance is not valid for use.

type Gauge internal.Gauge

func newGauge(orig *otlpmetrics.Gauge) Gauge {
	return Gauge(internal.NewGauge(orig))
}

func (ms Gauge) getOrig() *otlpmetrics.Gauge {
	return internal.GetOrigGauge(internal.Gauge(ms))
}

// NewGauge creates a new empty Gauge.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewGauge() Gauge {
	return newGauge(&otlpmetrics.Gauge{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms Gauge) MoveTo(dest Gauge) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.Gauge{}
}

// DataPoints returns the DataPoints associated with this Gauge.
func (ms Gauge) DataPoints() NumberDataPointSlice {
	return NumberDataPointSlice(internal.NewNumberDataPointSlice(&ms.getOrig().DataPoints))
}

// CopyTo copies all properties from the current struct to the dest.
func (ms Gauge) CopyTo(dest Gauge) {
	ms.DataPoints().CopyTo(dest.DataPoints())
}

// Sum represents the type of a numeric metric that is calculated as a sum of all reported measurements over a time interval.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewSum function to create new instances.
// Important: zero-initialized instance is not valid for use.

type Sum internal.Sum

func newSum(orig *otlpmetrics.Sum) Sum {
	return Sum(internal.NewSum(orig))
}

func (ms Sum) getOrig() *otlpmetrics.Sum {
	return internal.GetOrigSum(internal.Sum(ms))
}

// NewSum creates a new empty Sum.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewSum() Sum {
	return newSum(&otlpmetrics.Sum{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms Sum) MoveTo(dest Sum) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.Sum{}
}

// AggregationTemporality returns the aggregationtemporality associated with this Sum.
func (ms Sum) AggregationTemporality() MetricAggregationTemporality {
	return MetricAggregationTemporality(ms.getOrig().AggregationTemporality)
}

// SetAggregationTemporality replaces the aggregationtemporality associated with this Sum.
func (ms Sum) SetAggregationTemporality(v MetricAggregationTemporality) {
	ms.getOrig().AggregationTemporality = otlpmetrics.AggregationTemporality(v)
}

// IsMonotonic returns the ismonotonic associated with this Sum.
func (ms Sum) IsMonotonic() bool {
	return ms.getOrig().IsMonotonic
}

// SetIsMonotonic replaces the ismonotonic associated with this Sum.
func (ms Sum) SetIsMonotonic(v bool) {
	ms.getOrig().IsMonotonic = v
}

// DataPoints returns the DataPoints associated with this Sum.
func (ms Sum) DataPoints() NumberDataPointSlice {
	return NumberDataPointSlice(internal.NewNumberDataPointSlice(&ms.getOrig().DataPoints))
}

// CopyTo copies all properties from the current struct to the dest.
func (ms Sum) CopyTo(dest Sum) {
	dest.SetAggregationTemporality(ms.AggregationTemporality())
	dest.SetIsMonotonic(ms.IsMonotonic())
	ms.DataPoints().CopyTo(dest.DataPoints())
}

// Histogram represents the type of a metric that is calculated by aggregating as a Histogram of all reported measurements over a time interval.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewHistogram function to create new instances.
// Important: zero-initialized instance is not valid for use.

type Histogram internal.Histogram

func newHistogram(orig *otlpmetrics.Histogram) Histogram {
	return Histogram(internal.NewHistogram(orig))
}

func (ms Histogram) getOrig() *otlpmetrics.Histogram {
	return internal.GetOrigHistogram(internal.Histogram(ms))
}

// NewHistogram creates a new empty Histogram.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewHistogram() Histogram {
	return newHistogram(&otlpmetrics.Histogram{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms Histogram) MoveTo(dest Histogram) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.Histogram{}
}

// AggregationTemporality returns the aggregationtemporality associated with this Histogram.
func (ms Histogram) AggregationTemporality() MetricAggregationTemporality {
	return MetricAggregationTemporality(ms.getOrig().AggregationTemporality)
}

// SetAggregationTemporality replaces the aggregationtemporality associated with this Histogram.
func (ms Histogram) SetAggregationTemporality(v MetricAggregationTemporality) {
	ms.getOrig().AggregationTemporality = otlpmetrics.AggregationTemporality(v)
}

// DataPoints returns the DataPoints associated with this Histogram.
func (ms Histogram) DataPoints() HistogramDataPointSlice {
	return HistogramDataPointSlice(internal.NewHistogramDataPointSlice(&ms.getOrig().DataPoints))
}

// CopyTo copies all properties from the current struct to the dest.
func (ms Histogram) CopyTo(dest Histogram) {
	dest.SetAggregationTemporality(ms.AggregationTemporality())
	ms.DataPoints().CopyTo(dest.DataPoints())
}

// ExponentialHistogram represents the type of a metric that is calculated by aggregating
// as a ExponentialHistogram of all reported double measurements over a time interval.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewExponentialHistogram function to create new instances.
// Important: zero-initialized instance is not valid for use.

type ExponentialHistogram internal.ExponentialHistogram

func newExponentialHistogram(orig *otlpmetrics.ExponentialHistogram) ExponentialHistogram {
	return ExponentialHistogram(internal.NewExponentialHistogram(orig))
}

func (ms ExponentialHistogram) getOrig() *otlpmetrics.ExponentialHistogram {
	return internal.GetOrigExponentialHistogram(internal.ExponentialHistogram(ms))
}

// NewExponentialHistogram creates a new empty ExponentialHistogram.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewExponentialHistogram() ExponentialHistogram {
	return newExponentialHistogram(&otlpmetrics.ExponentialHistogram{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms ExponentialHistogram) MoveTo(dest ExponentialHistogram) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.ExponentialHistogram{}
}

// AggregationTemporality returns the aggregationtemporality associated with this ExponentialHistogram.
func (ms ExponentialHistogram) AggregationTemporality() MetricAggregationTemporality {
	return MetricAggregationTemporality(ms.getOrig().AggregationTemporality)
}

// SetAggregationTemporality replaces the aggregationtemporality associated with this ExponentialHistogram.
func (ms ExponentialHistogram) SetAggregationTemporality(v MetricAggregationTemporality) {
	ms.getOrig().AggregationTemporality = otlpmetrics.AggregationTemporality(v)
}

// DataPoints returns the DataPoints associated with this ExponentialHistogram.
func (ms ExponentialHistogram) DataPoints() ExponentialHistogramDataPointSlice {
	return ExponentialHistogramDataPointSlice(internal.NewExponentialHistogramDataPointSlice(&ms.getOrig().DataPoints))
}

// CopyTo copies all properties from the current struct to the dest.
func (ms ExponentialHistogram) CopyTo(dest ExponentialHistogram) {
	dest.SetAggregationTemporality(ms.AggregationTemporality())
	ms.DataPoints().CopyTo(dest.DataPoints())
}

// Summary represents the type of a metric that is calculated by aggregating as a Summary of all reported double measurements over a time interval.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewSummary function to create new instances.
// Important: zero-initialized instance is not valid for use.

type Summary internal.Summary

func newSummary(orig *otlpmetrics.Summary) Summary {
	return Summary(internal.NewSummary(orig))
}

func (ms Summary) getOrig() *otlpmetrics.Summary {
	return internal.GetOrigSummary(internal.Summary(ms))
}

// NewSummary creates a new empty Summary.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewSummary() Summary {
	return newSummary(&otlpmetrics.Summary{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms Summary) MoveTo(dest Summary) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.Summary{}
}

// DataPoints returns the DataPoints associated with this Summary.
func (ms Summary) DataPoints() SummaryDataPointSlice {
	return SummaryDataPointSlice(internal.NewSummaryDataPointSlice(&ms.getOrig().DataPoints))
}

// CopyTo copies all properties from the current struct to the dest.
func (ms Summary) CopyTo(dest Summary) {
	ms.DataPoints().CopyTo(dest.DataPoints())
}

// NumberDataPointSlice logically represents a slice of NumberDataPoint.
//
// This is a reference type. If passed by value and callee modifies it, the
// caller will see the modification.
//
// Must use NewNumberDataPointSlice function to create new instances.
// Important: zero-initialized instance is not valid for use.
type NumberDataPointSlice internal.NumberDataPointSlice

func newNumberDataPointSlice(orig *[]*otlpmetrics.NumberDataPoint) NumberDataPointSlice {
	return NumberDataPointSlice(internal.NewNumberDataPointSlice(orig))
}

func (ms NumberDataPointSlice) getOrig() *[]*otlpmetrics.NumberDataPoint {
	return internal.GetOrigNumberDataPointSlice(internal.NumberDataPointSlice(ms))
}

// NewNumberDataPointSlice creates a NumberDataPointSlice with 0 elements.
// Can use "EnsureCapacity" to initialize with a given capacity.
func NewNumberDataPointSlice() NumberDataPointSlice {
	orig := []*otlpmetrics.NumberDataPoint(nil)
	return newNumberDataPointSlice(&orig)
}

// Len returns the number of elements in the slice.
//
// Returns "0" for a newly instance created with "NewNumberDataPointSlice()".
func (es NumberDataPointSlice) Len() int {
	return len(*es.getOrig())
}

// At returns the element at the given index.
//
// This function is used mostly for iterating over all the values in the slice:
//
//	for i := 0; i < es.Len(); i++ {
//	    e := es.At(i)
//	    ... // Do something with the element
//	}
func (es NumberDataPointSlice) At(ix int) NumberDataPoint {
	return newNumberDataPoint((*es.getOrig())[ix])
}

// CopyTo copies all elements from the current slice to the dest.
func (es NumberDataPointSlice) CopyTo(dest NumberDataPointSlice) {
	srcLen := es.Len()
	destCap := cap(*dest.getOrig())
	if srcLen <= destCap {
		(*dest.getOrig()) = (*dest.getOrig())[:srcLen:destCap]
		for i := range *es.getOrig() {
			newNumberDataPoint((*es.getOrig())[i]).CopyTo(newNumberDataPoint((*dest.getOrig())[i]))
		}
		return
	}
	origs := make([]otlpmetrics.NumberDataPoint, srcLen)
	wrappers := make([]*otlpmetrics.NumberDataPoint, srcLen)
	for i := range *es.getOrig() {
		wrappers[i] = &origs[i]
		newNumberDataPoint((*es.getOrig())[i]).CopyTo(newNumberDataPoint(wrappers[i]))
	}
	*dest.getOrig() = wrappers
}

// EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
// 1. If the newCap <= cap then no change in capacity.
// 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
//
// Here is how a new NumberDataPointSlice can be initialized:
//
//	es := NewNumberDataPointSlice()
//	es.EnsureCapacity(4)
//	for i := 0; i < 4; i++ {
//	    e := es.AppendEmpty()
//	    // Here should set all the values for e.
//	}
func (es NumberDataPointSlice) EnsureCapacity(newCap int) {
	oldCap := cap(*es.getOrig())
	if newCap <= oldCap {
		return
	}

	newOrig := make([]*otlpmetrics.NumberDataPoint, len(*es.getOrig()), newCap)
	copy(newOrig, *es.getOrig())
	*es.getOrig() = newOrig
}

// AppendEmpty will append to the end of the slice an empty NumberDataPoint.
// It returns the newly added NumberDataPoint.
func (es NumberDataPointSlice) AppendEmpty() NumberDataPoint {
	*es.getOrig() = append(*es.getOrig(), &otlpmetrics.NumberDataPoint{})
	return es.At(es.Len() - 1)
}

// Sort sorts the NumberDataPoint elements within NumberDataPointSlice given the
// provided less function so that two instances of NumberDataPointSlice
// can be compared.
//
// Returns the same instance to allow nicer code like:
//
//	lessFunc := func(a, b NumberDataPoint) bool {
//	  return a.Name() < b.Name() // choose any comparison here
//	}
//	assert.Equal(t, expected.Sort(lessFunc), actual.Sort(lessFunc))
func (es NumberDataPointSlice) Sort(less func(a, b NumberDataPoint) bool) NumberDataPointSlice {
	sort.SliceStable(*es.getOrig(), func(i, j int) bool { return less(es.At(i), es.At(j)) })
	return es
}

// MoveAndAppendTo moves all elements from the current slice and appends them to the dest.
// The current slice will be cleared.
func (es NumberDataPointSlice) MoveAndAppendTo(dest NumberDataPointSlice) {
	if *dest.getOrig() == nil {
		// We can simply move the entire vector and avoid any allocations.
		*dest.getOrig() = *es.getOrig()
	} else {
		*dest.getOrig() = append(*dest.getOrig(), *es.getOrig()...)
	}
	*es.getOrig() = nil
}

// RemoveIf calls f sequentially for each element present in the slice.
// If f returns true, the element is removed from the slice.
func (es NumberDataPointSlice) RemoveIf(f func(NumberDataPoint) bool) {
	newLen := 0
	for i := 0; i < len(*es.getOrig()); i++ {
		if f(es.At(i)) {
			continue
		}
		if newLen == i {
			// Nothing to move, element is at the right place.
			newLen++
			continue
		}
		(*es.getOrig())[newLen] = (*es.getOrig())[i]
		newLen++
	}
	// TODO: Prevent memory leak by erasing truncated values.
	*es.getOrig() = (*es.getOrig())[:newLen]
}

// NumberDataPoint is a single data point in a timeseries that describes the time-varying value of a number metric.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewNumberDataPoint function to create new instances.
// Important: zero-initialized instance is not valid for use.

type NumberDataPoint internal.NumberDataPoint

func newNumberDataPoint(orig *otlpmetrics.NumberDataPoint) NumberDataPoint {
	return NumberDataPoint(internal.NewNumberDataPoint(orig))
}

func (ms NumberDataPoint) getOrig() *otlpmetrics.NumberDataPoint {
	return internal.GetOrigNumberDataPoint(internal.NumberDataPoint(ms))
}

// NewNumberDataPoint creates a new empty NumberDataPoint.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewNumberDataPoint() NumberDataPoint {
	return newNumberDataPoint(&otlpmetrics.NumberDataPoint{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms NumberDataPoint) MoveTo(dest NumberDataPoint) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.NumberDataPoint{}
}

// Attributes returns the Attributes associated with this NumberDataPoint.
func (ms NumberDataPoint) Attributes() pcommon.Map {
	return pcommon.Map(internal.NewMap(&ms.getOrig().Attributes))
}

// StartTimestamp returns the starttimestamp associated with this NumberDataPoint.
func (ms NumberDataPoint) StartTimestamp() pcommon.Timestamp {
	return pcommon.Timestamp(ms.getOrig().StartTimeUnixNano)
}

// SetStartTimestamp replaces the starttimestamp associated with this NumberDataPoint.
func (ms NumberDataPoint) SetStartTimestamp(v pcommon.Timestamp) {
	ms.getOrig().StartTimeUnixNano = uint64(v)
}

// Timestamp returns the timestamp associated with this NumberDataPoint.
func (ms NumberDataPoint) Timestamp() pcommon.Timestamp {
	return pcommon.Timestamp(ms.getOrig().TimeUnixNano)
}

// SetTimestamp replaces the timestamp associated with this NumberDataPoint.
func (ms NumberDataPoint) SetTimestamp(v pcommon.Timestamp) {
	ms.getOrig().TimeUnixNano = uint64(v)
}

// ValueType returns the type of the value for this NumberDataPoint.
// Calling this function on zero-initialized NumberDataPoint will cause a panic.
func (ms NumberDataPoint) ValueType() NumberDataPointValueType {
	switch ms.getOrig().Value.(type) {
	case *otlpmetrics.NumberDataPoint_AsDouble:
		return NumberDataPointValueTypeDouble
	case *otlpmetrics.NumberDataPoint_AsInt:
		return NumberDataPointValueTypeInt
	}
	return NumberDataPointValueTypeNone
}

// DoubleVal returns the doubleval associated with this NumberDataPoint.
func (ms NumberDataPoint) DoubleVal() float64 {
	return ms.getOrig().GetAsDouble()
}

// SetDoubleVal replaces the doubleval associated with this NumberDataPoint.
func (ms NumberDataPoint) SetDoubleVal(v float64) {
	ms.getOrig().Value = &otlpmetrics.NumberDataPoint_AsDouble{
		AsDouble: v,
	}
}

// IntVal returns the intval associated with this NumberDataPoint.
func (ms NumberDataPoint) IntVal() int64 {
	return ms.getOrig().GetAsInt()
}

// SetIntVal replaces the intval associated with this NumberDataPoint.
func (ms NumberDataPoint) SetIntVal(v int64) {
	ms.getOrig().Value = &otlpmetrics.NumberDataPoint_AsInt{
		AsInt: v,
	}
}

// Exemplars returns the Exemplars associated with this NumberDataPoint.
func (ms NumberDataPoint) Exemplars() ExemplarSlice {
	return ExemplarSlice(internal.NewExemplarSlice(&ms.getOrig().Exemplars))
}

// Flags returns the flags associated with this NumberDataPoint.
func (ms NumberDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.getOrig().Flags)
}

// SetFlags replaces the flags associated with this NumberDataPoint.
func (ms NumberDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.getOrig().Flags = uint32(v)
}

// CopyTo copies all properties from the current struct to the dest.
func (ms NumberDataPoint) CopyTo(dest NumberDataPoint) {
	ms.Attributes().CopyTo(dest.Attributes())
	dest.SetStartTimestamp(ms.StartTimestamp())
	dest.SetTimestamp(ms.Timestamp())
	switch ms.ValueType() {
	case NumberDataPointValueTypeDouble:
		dest.SetDoubleVal(ms.DoubleVal())
	case NumberDataPointValueTypeInt:
		dest.SetIntVal(ms.IntVal())
	}

	ms.Exemplars().CopyTo(dest.Exemplars())
	dest.SetFlags(ms.Flags())
}

// HistogramDataPointSlice logically represents a slice of HistogramDataPoint.
//
// This is a reference type. If passed by value and callee modifies it, the
// caller will see the modification.
//
// Must use NewHistogramDataPointSlice function to create new instances.
// Important: zero-initialized instance is not valid for use.
type HistogramDataPointSlice internal.HistogramDataPointSlice

func newHistogramDataPointSlice(orig *[]*otlpmetrics.HistogramDataPoint) HistogramDataPointSlice {
	return HistogramDataPointSlice(internal.NewHistogramDataPointSlice(orig))
}

func (ms HistogramDataPointSlice) getOrig() *[]*otlpmetrics.HistogramDataPoint {
	return internal.GetOrigHistogramDataPointSlice(internal.HistogramDataPointSlice(ms))
}

// NewHistogramDataPointSlice creates a HistogramDataPointSlice with 0 elements.
// Can use "EnsureCapacity" to initialize with a given capacity.
func NewHistogramDataPointSlice() HistogramDataPointSlice {
	orig := []*otlpmetrics.HistogramDataPoint(nil)
	return newHistogramDataPointSlice(&orig)
}

// Len returns the number of elements in the slice.
//
// Returns "0" for a newly instance created with "NewHistogramDataPointSlice()".
func (es HistogramDataPointSlice) Len() int {
	return len(*es.getOrig())
}

// At returns the element at the given index.
//
// This function is used mostly for iterating over all the values in the slice:
//
//	for i := 0; i < es.Len(); i++ {
//	    e := es.At(i)
//	    ... // Do something with the element
//	}
func (es HistogramDataPointSlice) At(ix int) HistogramDataPoint {
	return newHistogramDataPoint((*es.getOrig())[ix])
}

// CopyTo copies all elements from the current slice to the dest.
func (es HistogramDataPointSlice) CopyTo(dest HistogramDataPointSlice) {
	srcLen := es.Len()
	destCap := cap(*dest.getOrig())
	if srcLen <= destCap {
		(*dest.getOrig()) = (*dest.getOrig())[:srcLen:destCap]
		for i := range *es.getOrig() {
			newHistogramDataPoint((*es.getOrig())[i]).CopyTo(newHistogramDataPoint((*dest.getOrig())[i]))
		}
		return
	}
	origs := make([]otlpmetrics.HistogramDataPoint, srcLen)
	wrappers := make([]*otlpmetrics.HistogramDataPoint, srcLen)
	for i := range *es.getOrig() {
		wrappers[i] = &origs[i]
		newHistogramDataPoint((*es.getOrig())[i]).CopyTo(newHistogramDataPoint(wrappers[i]))
	}
	*dest.getOrig() = wrappers
}

// EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
// 1. If the newCap <= cap then no change in capacity.
// 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
//
// Here is how a new HistogramDataPointSlice can be initialized:
//
//	es := NewHistogramDataPointSlice()
//	es.EnsureCapacity(4)
//	for i := 0; i < 4; i++ {
//	    e := es.AppendEmpty()
//	    // Here should set all the values for e.
//	}
func (es HistogramDataPointSlice) EnsureCapacity(newCap int) {
	oldCap := cap(*es.getOrig())
	if newCap <= oldCap {
		return
	}

	newOrig := make([]*otlpmetrics.HistogramDataPoint, len(*es.getOrig()), newCap)
	copy(newOrig, *es.getOrig())
	*es.getOrig() = newOrig
}

// AppendEmpty will append to the end of the slice an empty HistogramDataPoint.
// It returns the newly added HistogramDataPoint.
func (es HistogramDataPointSlice) AppendEmpty() HistogramDataPoint {
	*es.getOrig() = append(*es.getOrig(), &otlpmetrics.HistogramDataPoint{})
	return es.At(es.Len() - 1)
}

// Sort sorts the HistogramDataPoint elements within HistogramDataPointSlice given the
// provided less function so that two instances of HistogramDataPointSlice
// can be compared.
//
// Returns the same instance to allow nicer code like:
//
//	lessFunc := func(a, b HistogramDataPoint) bool {
//	  return a.Name() < b.Name() // choose any comparison here
//	}
//	assert.Equal(t, expected.Sort(lessFunc), actual.Sort(lessFunc))
func (es HistogramDataPointSlice) Sort(less func(a, b HistogramDataPoint) bool) HistogramDataPointSlice {
	sort.SliceStable(*es.getOrig(), func(i, j int) bool { return less(es.At(i), es.At(j)) })
	return es
}

// MoveAndAppendTo moves all elements from the current slice and appends them to the dest.
// The current slice will be cleared.
func (es HistogramDataPointSlice) MoveAndAppendTo(dest HistogramDataPointSlice) {
	if *dest.getOrig() == nil {
		// We can simply move the entire vector and avoid any allocations.
		*dest.getOrig() = *es.getOrig()
	} else {
		*dest.getOrig() = append(*dest.getOrig(), *es.getOrig()...)
	}
	*es.getOrig() = nil
}

// RemoveIf calls f sequentially for each element present in the slice.
// If f returns true, the element is removed from the slice.
func (es HistogramDataPointSlice) RemoveIf(f func(HistogramDataPoint) bool) {
	newLen := 0
	for i := 0; i < len(*es.getOrig()); i++ {
		if f(es.At(i)) {
			continue
		}
		if newLen == i {
			// Nothing to move, element is at the right place.
			newLen++
			continue
		}
		(*es.getOrig())[newLen] = (*es.getOrig())[i]
		newLen++
	}
	// TODO: Prevent memory leak by erasing truncated values.
	*es.getOrig() = (*es.getOrig())[:newLen]
}

// HistogramDataPoint is a single data point in a timeseries that describes the time-varying values of a Histogram of values.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewHistogramDataPoint function to create new instances.
// Important: zero-initialized instance is not valid for use.

type HistogramDataPoint internal.HistogramDataPoint

func newHistogramDataPoint(orig *otlpmetrics.HistogramDataPoint) HistogramDataPoint {
	return HistogramDataPoint(internal.NewHistogramDataPoint(orig))
}

func (ms HistogramDataPoint) getOrig() *otlpmetrics.HistogramDataPoint {
	return internal.GetOrigHistogramDataPoint(internal.HistogramDataPoint(ms))
}

// NewHistogramDataPoint creates a new empty HistogramDataPoint.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewHistogramDataPoint() HistogramDataPoint {
	return newHistogramDataPoint(&otlpmetrics.HistogramDataPoint{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms HistogramDataPoint) MoveTo(dest HistogramDataPoint) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.HistogramDataPoint{}
}

// Attributes returns the Attributes associated with this HistogramDataPoint.
func (ms HistogramDataPoint) Attributes() pcommon.Map {
	return pcommon.Map(internal.NewMap(&ms.getOrig().Attributes))
}

// StartTimestamp returns the starttimestamp associated with this HistogramDataPoint.
func (ms HistogramDataPoint) StartTimestamp() pcommon.Timestamp {
	return pcommon.Timestamp(ms.getOrig().StartTimeUnixNano)
}

// SetStartTimestamp replaces the starttimestamp associated with this HistogramDataPoint.
func (ms HistogramDataPoint) SetStartTimestamp(v pcommon.Timestamp) {
	ms.getOrig().StartTimeUnixNano = uint64(v)
}

// Timestamp returns the timestamp associated with this HistogramDataPoint.
func (ms HistogramDataPoint) Timestamp() pcommon.Timestamp {
	return pcommon.Timestamp(ms.getOrig().TimeUnixNano)
}

// SetTimestamp replaces the timestamp associated with this HistogramDataPoint.
func (ms HistogramDataPoint) SetTimestamp(v pcommon.Timestamp) {
	ms.getOrig().TimeUnixNano = uint64(v)
}

// Count returns the count associated with this HistogramDataPoint.
func (ms HistogramDataPoint) Count() uint64 {
	return ms.getOrig().Count
}

// SetCount replaces the count associated with this HistogramDataPoint.
func (ms HistogramDataPoint) SetCount(v uint64) {
	ms.getOrig().Count = v
}

// Sum returns the sum associated with this HistogramDataPoint.
func (ms HistogramDataPoint) Sum() float64 {
	return ms.getOrig().GetSum()
}

// HasSum returns true if the HistogramDataPoint contains a
// Sum value, false otherwise.
func (ms HistogramDataPoint) HasSum() bool {
	return ms.getOrig().Sum_ != nil
}

// SetSum replaces the sum associated with this HistogramDataPoint.
func (ms HistogramDataPoint) SetSum(v float64) {
	ms.getOrig().Sum_ = &otlpmetrics.HistogramDataPoint_Sum{Sum: v}
}

// BucketCounts returns the bucketcounts associated with this HistogramDataPoint.
func (ms HistogramDataPoint) BucketCounts() pcommon.UInt64Slice {
	return pcommon.UInt64Slice(internal.NewUInt64Slice(&ms.getOrig().BucketCounts))
}

// SetBucketCounts replaces the bucketcounts associated with this HistogramDataPoint.
// Deprecated: [0.60.0] Use BucketCounts().FromRaw() instead
func (ms HistogramDataPoint) SetBucketCounts(v pcommon.UInt64Slice) {
	ms.getOrig().BucketCounts = *internal.GetOrigUInt64Slice(internal.UInt64Slice(v))
}

// ExplicitBounds returns the explicitbounds associated with this HistogramDataPoint.
func (ms HistogramDataPoint) ExplicitBounds() pcommon.Float64Slice {
	return pcommon.Float64Slice(internal.NewFloat64Slice(&ms.getOrig().ExplicitBounds))
}

// SetExplicitBounds replaces the explicitbounds associated with this HistogramDataPoint.
// Deprecated: [0.60.0] Use ExplicitBounds().FromRaw() instead
func (ms HistogramDataPoint) SetExplicitBounds(v pcommon.Float64Slice) {
	ms.getOrig().ExplicitBounds = *internal.GetOrigFloat64Slice(internal.Float64Slice(v))
}

// Exemplars returns the Exemplars associated with this HistogramDataPoint.
func (ms HistogramDataPoint) Exemplars() ExemplarSlice {
	return ExemplarSlice(internal.NewExemplarSlice(&ms.getOrig().Exemplars))
}

// Flags returns the flags associated with this HistogramDataPoint.
func (ms HistogramDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.getOrig().Flags)
}

// SetFlags replaces the flags associated with this HistogramDataPoint.
func (ms HistogramDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.getOrig().Flags = uint32(v)
}

// Min returns the min associated with this HistogramDataPoint.
func (ms HistogramDataPoint) Min() float64 {
	return ms.getOrig().GetMin()
}

// HasMin returns true if the HistogramDataPoint contains a
// Min value, false otherwise.
func (ms HistogramDataPoint) HasMin() bool {
	return ms.getOrig().Min_ != nil
}

// SetMin replaces the min associated with this HistogramDataPoint.
func (ms HistogramDataPoint) SetMin(v float64) {
	ms.getOrig().Min_ = &otlpmetrics.HistogramDataPoint_Min{Min: v}
}

// Max returns the max associated with this HistogramDataPoint.
func (ms HistogramDataPoint) Max() float64 {
	return ms.getOrig().GetMax()
}

// HasMax returns true if the HistogramDataPoint contains a
// Max value, false otherwise.
func (ms HistogramDataPoint) HasMax() bool {
	return ms.getOrig().Max_ != nil
}

// SetMax replaces the max associated with this HistogramDataPoint.
func (ms HistogramDataPoint) SetMax(v float64) {
	ms.getOrig().Max_ = &otlpmetrics.HistogramDataPoint_Max{Max: v}
}

// CopyTo copies all properties from the current struct to the dest.
func (ms HistogramDataPoint) CopyTo(dest HistogramDataPoint) {
	ms.Attributes().CopyTo(dest.Attributes())
	dest.SetStartTimestamp(ms.StartTimestamp())
	dest.SetTimestamp(ms.Timestamp())
	dest.SetCount(ms.Count())
	if ms.HasSum() {
		dest.SetSum(ms.Sum())
	}

	ms.BucketCounts().CopyTo(dest.BucketCounts())
	ms.ExplicitBounds().CopyTo(dest.ExplicitBounds())
	ms.Exemplars().CopyTo(dest.Exemplars())
	dest.SetFlags(ms.Flags())
	if ms.HasMin() {
		dest.SetMin(ms.Min())
	}

	if ms.HasMax() {
		dest.SetMax(ms.Max())
	}

}

// ExponentialHistogramDataPointSlice logically represents a slice of ExponentialHistogramDataPoint.
//
// This is a reference type. If passed by value and callee modifies it, the
// caller will see the modification.
//
// Must use NewExponentialHistogramDataPointSlice function to create new instances.
// Important: zero-initialized instance is not valid for use.
type ExponentialHistogramDataPointSlice internal.ExponentialHistogramDataPointSlice

func newExponentialHistogramDataPointSlice(orig *[]*otlpmetrics.ExponentialHistogramDataPoint) ExponentialHistogramDataPointSlice {
	return ExponentialHistogramDataPointSlice(internal.NewExponentialHistogramDataPointSlice(orig))
}

func (ms ExponentialHistogramDataPointSlice) getOrig() *[]*otlpmetrics.ExponentialHistogramDataPoint {
	return internal.GetOrigExponentialHistogramDataPointSlice(internal.ExponentialHistogramDataPointSlice(ms))
}

// NewExponentialHistogramDataPointSlice creates a ExponentialHistogramDataPointSlice with 0 elements.
// Can use "EnsureCapacity" to initialize with a given capacity.
func NewExponentialHistogramDataPointSlice() ExponentialHistogramDataPointSlice {
	orig := []*otlpmetrics.ExponentialHistogramDataPoint(nil)
	return newExponentialHistogramDataPointSlice(&orig)
}

// Len returns the number of elements in the slice.
//
// Returns "0" for a newly instance created with "NewExponentialHistogramDataPointSlice()".
func (es ExponentialHistogramDataPointSlice) Len() int {
	return len(*es.getOrig())
}

// At returns the element at the given index.
//
// This function is used mostly for iterating over all the values in the slice:
//
//	for i := 0; i < es.Len(); i++ {
//	    e := es.At(i)
//	    ... // Do something with the element
//	}
func (es ExponentialHistogramDataPointSlice) At(ix int) ExponentialHistogramDataPoint {
	return newExponentialHistogramDataPoint((*es.getOrig())[ix])
}

// CopyTo copies all elements from the current slice to the dest.
func (es ExponentialHistogramDataPointSlice) CopyTo(dest ExponentialHistogramDataPointSlice) {
	srcLen := es.Len()
	destCap := cap(*dest.getOrig())
	if srcLen <= destCap {
		(*dest.getOrig()) = (*dest.getOrig())[:srcLen:destCap]
		for i := range *es.getOrig() {
			newExponentialHistogramDataPoint((*es.getOrig())[i]).CopyTo(newExponentialHistogramDataPoint((*dest.getOrig())[i]))
		}
		return
	}
	origs := make([]otlpmetrics.ExponentialHistogramDataPoint, srcLen)
	wrappers := make([]*otlpmetrics.ExponentialHistogramDataPoint, srcLen)
	for i := range *es.getOrig() {
		wrappers[i] = &origs[i]
		newExponentialHistogramDataPoint((*es.getOrig())[i]).CopyTo(newExponentialHistogramDataPoint(wrappers[i]))
	}
	*dest.getOrig() = wrappers
}

// EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
// 1. If the newCap <= cap then no change in capacity.
// 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
//
// Here is how a new ExponentialHistogramDataPointSlice can be initialized:
//
//	es := NewExponentialHistogramDataPointSlice()
//	es.EnsureCapacity(4)
//	for i := 0; i < 4; i++ {
//	    e := es.AppendEmpty()
//	    // Here should set all the values for e.
//	}
func (es ExponentialHistogramDataPointSlice) EnsureCapacity(newCap int) {
	oldCap := cap(*es.getOrig())
	if newCap <= oldCap {
		return
	}

	newOrig := make([]*otlpmetrics.ExponentialHistogramDataPoint, len(*es.getOrig()), newCap)
	copy(newOrig, *es.getOrig())
	*es.getOrig() = newOrig
}

// AppendEmpty will append to the end of the slice an empty ExponentialHistogramDataPoint.
// It returns the newly added ExponentialHistogramDataPoint.
func (es ExponentialHistogramDataPointSlice) AppendEmpty() ExponentialHistogramDataPoint {
	*es.getOrig() = append(*es.getOrig(), &otlpmetrics.ExponentialHistogramDataPoint{})
	return es.At(es.Len() - 1)
}

// Sort sorts the ExponentialHistogramDataPoint elements within ExponentialHistogramDataPointSlice given the
// provided less function so that two instances of ExponentialHistogramDataPointSlice
// can be compared.
//
// Returns the same instance to allow nicer code like:
//
//	lessFunc := func(a, b ExponentialHistogramDataPoint) bool {
//	  return a.Name() < b.Name() // choose any comparison here
//	}
//	assert.Equal(t, expected.Sort(lessFunc), actual.Sort(lessFunc))
func (es ExponentialHistogramDataPointSlice) Sort(less func(a, b ExponentialHistogramDataPoint) bool) ExponentialHistogramDataPointSlice {
	sort.SliceStable(*es.getOrig(), func(i, j int) bool { return less(es.At(i), es.At(j)) })
	return es
}

// MoveAndAppendTo moves all elements from the current slice and appends them to the dest.
// The current slice will be cleared.
func (es ExponentialHistogramDataPointSlice) MoveAndAppendTo(dest ExponentialHistogramDataPointSlice) {
	if *dest.getOrig() == nil {
		// We can simply move the entire vector and avoid any allocations.
		*dest.getOrig() = *es.getOrig()
	} else {
		*dest.getOrig() = append(*dest.getOrig(), *es.getOrig()...)
	}
	*es.getOrig() = nil
}

// RemoveIf calls f sequentially for each element present in the slice.
// If f returns true, the element is removed from the slice.
func (es ExponentialHistogramDataPointSlice) RemoveIf(f func(ExponentialHistogramDataPoint) bool) {
	newLen := 0
	for i := 0; i < len(*es.getOrig()); i++ {
		if f(es.At(i)) {
			continue
		}
		if newLen == i {
			// Nothing to move, element is at the right place.
			newLen++
			continue
		}
		(*es.getOrig())[newLen] = (*es.getOrig())[i]
		newLen++
	}
	// TODO: Prevent memory leak by erasing truncated values.
	*es.getOrig() = (*es.getOrig())[:newLen]
}

// ExponentialHistogramDataPoint is a single data point in a timeseries that describes the
// time-varying values of a ExponentialHistogram of double values. A ExponentialHistogram contains
// summary statistics for a population of values, it may optionally contain the
// distribution of those values across a set of buckets.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewExponentialHistogramDataPoint function to create new instances.
// Important: zero-initialized instance is not valid for use.

type ExponentialHistogramDataPoint internal.ExponentialHistogramDataPoint

func newExponentialHistogramDataPoint(orig *otlpmetrics.ExponentialHistogramDataPoint) ExponentialHistogramDataPoint {
	return ExponentialHistogramDataPoint(internal.NewExponentialHistogramDataPoint(orig))
}

func (ms ExponentialHistogramDataPoint) getOrig() *otlpmetrics.ExponentialHistogramDataPoint {
	return internal.GetOrigExponentialHistogramDataPoint(internal.ExponentialHistogramDataPoint(ms))
}

// NewExponentialHistogramDataPoint creates a new empty ExponentialHistogramDataPoint.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewExponentialHistogramDataPoint() ExponentialHistogramDataPoint {
	return newExponentialHistogramDataPoint(&otlpmetrics.ExponentialHistogramDataPoint{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms ExponentialHistogramDataPoint) MoveTo(dest ExponentialHistogramDataPoint) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.ExponentialHistogramDataPoint{}
}

// Attributes returns the Attributes associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Attributes() pcommon.Map {
	return pcommon.Map(internal.NewMap(&ms.getOrig().Attributes))
}

// StartTimestamp returns the starttimestamp associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) StartTimestamp() pcommon.Timestamp {
	return pcommon.Timestamp(ms.getOrig().StartTimeUnixNano)
}

// SetStartTimestamp replaces the starttimestamp associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) SetStartTimestamp(v pcommon.Timestamp) {
	ms.getOrig().StartTimeUnixNano = uint64(v)
}

// Timestamp returns the timestamp associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Timestamp() pcommon.Timestamp {
	return pcommon.Timestamp(ms.getOrig().TimeUnixNano)
}

// SetTimestamp replaces the timestamp associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) SetTimestamp(v pcommon.Timestamp) {
	ms.getOrig().TimeUnixNano = uint64(v)
}

// Count returns the count associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Count() uint64 {
	return ms.getOrig().Count
}

// SetCount replaces the count associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) SetCount(v uint64) {
	ms.getOrig().Count = v
}

// Sum returns the sum associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Sum() float64 {
	return ms.getOrig().GetSum()
}

// HasSum returns true if the ExponentialHistogramDataPoint contains a
// Sum value, false otherwise.
func (ms ExponentialHistogramDataPoint) HasSum() bool {
	return ms.getOrig().Sum_ != nil
}

// SetSum replaces the sum associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) SetSum(v float64) {
	ms.getOrig().Sum_ = &otlpmetrics.ExponentialHistogramDataPoint_Sum{Sum: v}
}

// Scale returns the scale associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Scale() int32 {
	return ms.getOrig().Scale
}

// SetScale replaces the scale associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) SetScale(v int32) {
	ms.getOrig().Scale = v
}

// ZeroCount returns the zerocount associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) ZeroCount() uint64 {
	return ms.getOrig().ZeroCount
}

// SetZeroCount replaces the zerocount associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) SetZeroCount(v uint64) {
	ms.getOrig().ZeroCount = v
}

// Positive returns the positive associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Positive() Buckets {
	return Buckets(internal.NewBuckets(&ms.getOrig().Positive))
}

// Negative returns the negative associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Negative() Buckets {
	return Buckets(internal.NewBuckets(&ms.getOrig().Negative))
}

// Exemplars returns the Exemplars associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Exemplars() ExemplarSlice {
	return ExemplarSlice(internal.NewExemplarSlice(&ms.getOrig().Exemplars))
}

// Flags returns the flags associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.getOrig().Flags)
}

// SetFlags replaces the flags associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.getOrig().Flags = uint32(v)
}

// Min returns the min associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Min() float64 {
	return ms.getOrig().GetMin()
}

// HasMin returns true if the ExponentialHistogramDataPoint contains a
// Min value, false otherwise.
func (ms ExponentialHistogramDataPoint) HasMin() bool {
	return ms.getOrig().Min_ != nil
}

// SetMin replaces the min associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) SetMin(v float64) {
	ms.getOrig().Min_ = &otlpmetrics.ExponentialHistogramDataPoint_Min{Min: v}
}

// Max returns the max associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) Max() float64 {
	return ms.getOrig().GetMax()
}

// HasMax returns true if the ExponentialHistogramDataPoint contains a
// Max value, false otherwise.
func (ms ExponentialHistogramDataPoint) HasMax() bool {
	return ms.getOrig().Max_ != nil
}

// SetMax replaces the max associated with this ExponentialHistogramDataPoint.
func (ms ExponentialHistogramDataPoint) SetMax(v float64) {
	ms.getOrig().Max_ = &otlpmetrics.ExponentialHistogramDataPoint_Max{Max: v}
}

// CopyTo copies all properties from the current struct to the dest.
func (ms ExponentialHistogramDataPoint) CopyTo(dest ExponentialHistogramDataPoint) {
	ms.Attributes().CopyTo(dest.Attributes())
	dest.SetStartTimestamp(ms.StartTimestamp())
	dest.SetTimestamp(ms.Timestamp())
	dest.SetCount(ms.Count())
	if ms.HasSum() {
		dest.SetSum(ms.Sum())
	}

	dest.SetScale(ms.Scale())
	dest.SetZeroCount(ms.ZeroCount())
	ms.Positive().CopyTo(dest.Positive())
	ms.Negative().CopyTo(dest.Negative())
	ms.Exemplars().CopyTo(dest.Exemplars())
	dest.SetFlags(ms.Flags())
	if ms.HasMin() {
		dest.SetMin(ms.Min())
	}

	if ms.HasMax() {
		dest.SetMax(ms.Max())
	}

}

// Buckets are a set of bucket counts, encoded in a contiguous array of counts.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewBuckets function to create new instances.
// Important: zero-initialized instance is not valid for use.

type Buckets internal.Buckets

func newBuckets(orig *otlpmetrics.ExponentialHistogramDataPoint_Buckets) Buckets {
	return Buckets(internal.NewBuckets(orig))
}

func (ms Buckets) getOrig() *otlpmetrics.ExponentialHistogramDataPoint_Buckets {
	return internal.GetOrigBuckets(internal.Buckets(ms))
}

// NewBuckets creates a new empty Buckets.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewBuckets() Buckets {
	return newBuckets(&otlpmetrics.ExponentialHistogramDataPoint_Buckets{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms Buckets) MoveTo(dest Buckets) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.ExponentialHistogramDataPoint_Buckets{}
}

// Offset returns the offset associated with this Buckets.
func (ms Buckets) Offset() int32 {
	return ms.getOrig().Offset
}

// SetOffset replaces the offset associated with this Buckets.
func (ms Buckets) SetOffset(v int32) {
	ms.getOrig().Offset = v
}

// BucketCounts returns the bucketcounts associated with this Buckets.
func (ms Buckets) BucketCounts() pcommon.UInt64Slice {
	return pcommon.UInt64Slice(internal.NewUInt64Slice(&ms.getOrig().BucketCounts))
}

// SetBucketCounts replaces the bucketcounts associated with this Buckets.
// Deprecated: [0.60.0] Use BucketCounts().FromRaw() instead
func (ms Buckets) SetBucketCounts(v pcommon.UInt64Slice) {
	ms.getOrig().BucketCounts = *internal.GetOrigUInt64Slice(internal.UInt64Slice(v))
}

// CopyTo copies all properties from the current struct to the dest.
func (ms Buckets) CopyTo(dest Buckets) {
	dest.SetOffset(ms.Offset())
	ms.BucketCounts().CopyTo(dest.BucketCounts())
}

// SummaryDataPointSlice logically represents a slice of SummaryDataPoint.
//
// This is a reference type. If passed by value and callee modifies it, the
// caller will see the modification.
//
// Must use NewSummaryDataPointSlice function to create new instances.
// Important: zero-initialized instance is not valid for use.
type SummaryDataPointSlice internal.SummaryDataPointSlice

func newSummaryDataPointSlice(orig *[]*otlpmetrics.SummaryDataPoint) SummaryDataPointSlice {
	return SummaryDataPointSlice(internal.NewSummaryDataPointSlice(orig))
}

func (ms SummaryDataPointSlice) getOrig() *[]*otlpmetrics.SummaryDataPoint {
	return internal.GetOrigSummaryDataPointSlice(internal.SummaryDataPointSlice(ms))
}

// NewSummaryDataPointSlice creates a SummaryDataPointSlice with 0 elements.
// Can use "EnsureCapacity" to initialize with a given capacity.
func NewSummaryDataPointSlice() SummaryDataPointSlice {
	orig := []*otlpmetrics.SummaryDataPoint(nil)
	return newSummaryDataPointSlice(&orig)
}

// Len returns the number of elements in the slice.
//
// Returns "0" for a newly instance created with "NewSummaryDataPointSlice()".
func (es SummaryDataPointSlice) Len() int {
	return len(*es.getOrig())
}

// At returns the element at the given index.
//
// This function is used mostly for iterating over all the values in the slice:
//
//	for i := 0; i < es.Len(); i++ {
//	    e := es.At(i)
//	    ... // Do something with the element
//	}
func (es SummaryDataPointSlice) At(ix int) SummaryDataPoint {
	return newSummaryDataPoint((*es.getOrig())[ix])
}

// CopyTo copies all elements from the current slice to the dest.
func (es SummaryDataPointSlice) CopyTo(dest SummaryDataPointSlice) {
	srcLen := es.Len()
	destCap := cap(*dest.getOrig())
	if srcLen <= destCap {
		(*dest.getOrig()) = (*dest.getOrig())[:srcLen:destCap]
		for i := range *es.getOrig() {
			newSummaryDataPoint((*es.getOrig())[i]).CopyTo(newSummaryDataPoint((*dest.getOrig())[i]))
		}
		return
	}
	origs := make([]otlpmetrics.SummaryDataPoint, srcLen)
	wrappers := make([]*otlpmetrics.SummaryDataPoint, srcLen)
	for i := range *es.getOrig() {
		wrappers[i] = &origs[i]
		newSummaryDataPoint((*es.getOrig())[i]).CopyTo(newSummaryDataPoint(wrappers[i]))
	}
	*dest.getOrig() = wrappers
}

// EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
// 1. If the newCap <= cap then no change in capacity.
// 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
//
// Here is how a new SummaryDataPointSlice can be initialized:
//
//	es := NewSummaryDataPointSlice()
//	es.EnsureCapacity(4)
//	for i := 0; i < 4; i++ {
//	    e := es.AppendEmpty()
//	    // Here should set all the values for e.
//	}
func (es SummaryDataPointSlice) EnsureCapacity(newCap int) {
	oldCap := cap(*es.getOrig())
	if newCap <= oldCap {
		return
	}

	newOrig := make([]*otlpmetrics.SummaryDataPoint, len(*es.getOrig()), newCap)
	copy(newOrig, *es.getOrig())
	*es.getOrig() = newOrig
}

// AppendEmpty will append to the end of the slice an empty SummaryDataPoint.
// It returns the newly added SummaryDataPoint.
func (es SummaryDataPointSlice) AppendEmpty() SummaryDataPoint {
	*es.getOrig() = append(*es.getOrig(), &otlpmetrics.SummaryDataPoint{})
	return es.At(es.Len() - 1)
}

// Sort sorts the SummaryDataPoint elements within SummaryDataPointSlice given the
// provided less function so that two instances of SummaryDataPointSlice
// can be compared.
//
// Returns the same instance to allow nicer code like:
//
//	lessFunc := func(a, b SummaryDataPoint) bool {
//	  return a.Name() < b.Name() // choose any comparison here
//	}
//	assert.Equal(t, expected.Sort(lessFunc), actual.Sort(lessFunc))
func (es SummaryDataPointSlice) Sort(less func(a, b SummaryDataPoint) bool) SummaryDataPointSlice {
	sort.SliceStable(*es.getOrig(), func(i, j int) bool { return less(es.At(i), es.At(j)) })
	return es
}

// MoveAndAppendTo moves all elements from the current slice and appends them to the dest.
// The current slice will be cleared.
func (es SummaryDataPointSlice) MoveAndAppendTo(dest SummaryDataPointSlice) {
	if *dest.getOrig() == nil {
		// We can simply move the entire vector and avoid any allocations.
		*dest.getOrig() = *es.getOrig()
	} else {
		*dest.getOrig() = append(*dest.getOrig(), *es.getOrig()...)
	}
	*es.getOrig() = nil
}

// RemoveIf calls f sequentially for each element present in the slice.
// If f returns true, the element is removed from the slice.
func (es SummaryDataPointSlice) RemoveIf(f func(SummaryDataPoint) bool) {
	newLen := 0
	for i := 0; i < len(*es.getOrig()); i++ {
		if f(es.At(i)) {
			continue
		}
		if newLen == i {
			// Nothing to move, element is at the right place.
			newLen++
			continue
		}
		(*es.getOrig())[newLen] = (*es.getOrig())[i]
		newLen++
	}
	// TODO: Prevent memory leak by erasing truncated values.
	*es.getOrig() = (*es.getOrig())[:newLen]
}

// SummaryDataPoint is a single data point in a timeseries that describes the time-varying values of a Summary of double values.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewSummaryDataPoint function to create new instances.
// Important: zero-initialized instance is not valid for use.

type SummaryDataPoint internal.SummaryDataPoint

func newSummaryDataPoint(orig *otlpmetrics.SummaryDataPoint) SummaryDataPoint {
	return SummaryDataPoint(internal.NewSummaryDataPoint(orig))
}

func (ms SummaryDataPoint) getOrig() *otlpmetrics.SummaryDataPoint {
	return internal.GetOrigSummaryDataPoint(internal.SummaryDataPoint(ms))
}

// NewSummaryDataPoint creates a new empty SummaryDataPoint.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewSummaryDataPoint() SummaryDataPoint {
	return newSummaryDataPoint(&otlpmetrics.SummaryDataPoint{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms SummaryDataPoint) MoveTo(dest SummaryDataPoint) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.SummaryDataPoint{}
}

// Attributes returns the Attributes associated with this SummaryDataPoint.
func (ms SummaryDataPoint) Attributes() pcommon.Map {
	return pcommon.Map(internal.NewMap(&ms.getOrig().Attributes))
}

// StartTimestamp returns the starttimestamp associated with this SummaryDataPoint.
func (ms SummaryDataPoint) StartTimestamp() pcommon.Timestamp {
	return pcommon.Timestamp(ms.getOrig().StartTimeUnixNano)
}

// SetStartTimestamp replaces the starttimestamp associated with this SummaryDataPoint.
func (ms SummaryDataPoint) SetStartTimestamp(v pcommon.Timestamp) {
	ms.getOrig().StartTimeUnixNano = uint64(v)
}

// Timestamp returns the timestamp associated with this SummaryDataPoint.
func (ms SummaryDataPoint) Timestamp() pcommon.Timestamp {
	return pcommon.Timestamp(ms.getOrig().TimeUnixNano)
}

// SetTimestamp replaces the timestamp associated with this SummaryDataPoint.
func (ms SummaryDataPoint) SetTimestamp(v pcommon.Timestamp) {
	ms.getOrig().TimeUnixNano = uint64(v)
}

// Count returns the count associated with this SummaryDataPoint.
func (ms SummaryDataPoint) Count() uint64 {
	return ms.getOrig().Count
}

// SetCount replaces the count associated with this SummaryDataPoint.
func (ms SummaryDataPoint) SetCount(v uint64) {
	ms.getOrig().Count = v
}

// Sum returns the sum associated with this SummaryDataPoint.
func (ms SummaryDataPoint) Sum() float64 {
	return ms.getOrig().Sum
}

// SetSum replaces the sum associated with this SummaryDataPoint.
func (ms SummaryDataPoint) SetSum(v float64) {
	ms.getOrig().Sum = v
}

// QuantileValues returns the QuantileValues associated with this SummaryDataPoint.
func (ms SummaryDataPoint) QuantileValues() ValueAtQuantileSlice {
	return ValueAtQuantileSlice(internal.NewValueAtQuantileSlice(&ms.getOrig().QuantileValues))
}

// Flags returns the flags associated with this SummaryDataPoint.
func (ms SummaryDataPoint) Flags() MetricDataPointFlags {
	return MetricDataPointFlags(ms.getOrig().Flags)
}

// SetFlags replaces the flags associated with this SummaryDataPoint.
func (ms SummaryDataPoint) SetFlags(v MetricDataPointFlags) {
	ms.getOrig().Flags = uint32(v)
}

// CopyTo copies all properties from the current struct to the dest.
func (ms SummaryDataPoint) CopyTo(dest SummaryDataPoint) {
	ms.Attributes().CopyTo(dest.Attributes())
	dest.SetStartTimestamp(ms.StartTimestamp())
	dest.SetTimestamp(ms.Timestamp())
	dest.SetCount(ms.Count())
	dest.SetSum(ms.Sum())
	ms.QuantileValues().CopyTo(dest.QuantileValues())
	dest.SetFlags(ms.Flags())
}

// ValueAtQuantileSlice logically represents a slice of ValueAtQuantile.
//
// This is a reference type. If passed by value and callee modifies it, the
// caller will see the modification.
//
// Must use NewValueAtQuantileSlice function to create new instances.
// Important: zero-initialized instance is not valid for use.
type ValueAtQuantileSlice internal.ValueAtQuantileSlice

func newValueAtQuantileSlice(orig *[]*otlpmetrics.SummaryDataPoint_ValueAtQuantile) ValueAtQuantileSlice {
	return ValueAtQuantileSlice(internal.NewValueAtQuantileSlice(orig))
}

func (ms ValueAtQuantileSlice) getOrig() *[]*otlpmetrics.SummaryDataPoint_ValueAtQuantile {
	return internal.GetOrigValueAtQuantileSlice(internal.ValueAtQuantileSlice(ms))
}

// NewValueAtQuantileSlice creates a ValueAtQuantileSlice with 0 elements.
// Can use "EnsureCapacity" to initialize with a given capacity.
func NewValueAtQuantileSlice() ValueAtQuantileSlice {
	orig := []*otlpmetrics.SummaryDataPoint_ValueAtQuantile(nil)
	return newValueAtQuantileSlice(&orig)
}

// Len returns the number of elements in the slice.
//
// Returns "0" for a newly instance created with "NewValueAtQuantileSlice()".
func (es ValueAtQuantileSlice) Len() int {
	return len(*es.getOrig())
}

// At returns the element at the given index.
//
// This function is used mostly for iterating over all the values in the slice:
//
//	for i := 0; i < es.Len(); i++ {
//	    e := es.At(i)
//	    ... // Do something with the element
//	}
func (es ValueAtQuantileSlice) At(ix int) ValueAtQuantile {
	return newValueAtQuantile((*es.getOrig())[ix])
}

// CopyTo copies all elements from the current slice to the dest.
func (es ValueAtQuantileSlice) CopyTo(dest ValueAtQuantileSlice) {
	srcLen := es.Len()
	destCap := cap(*dest.getOrig())
	if srcLen <= destCap {
		(*dest.getOrig()) = (*dest.getOrig())[:srcLen:destCap]
		for i := range *es.getOrig() {
			newValueAtQuantile((*es.getOrig())[i]).CopyTo(newValueAtQuantile((*dest.getOrig())[i]))
		}
		return
	}
	origs := make([]otlpmetrics.SummaryDataPoint_ValueAtQuantile, srcLen)
	wrappers := make([]*otlpmetrics.SummaryDataPoint_ValueAtQuantile, srcLen)
	for i := range *es.getOrig() {
		wrappers[i] = &origs[i]
		newValueAtQuantile((*es.getOrig())[i]).CopyTo(newValueAtQuantile(wrappers[i]))
	}
	*dest.getOrig() = wrappers
}

// EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
// 1. If the newCap <= cap then no change in capacity.
// 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
//
// Here is how a new ValueAtQuantileSlice can be initialized:
//
//	es := NewValueAtQuantileSlice()
//	es.EnsureCapacity(4)
//	for i := 0; i < 4; i++ {
//	    e := es.AppendEmpty()
//	    // Here should set all the values for e.
//	}
func (es ValueAtQuantileSlice) EnsureCapacity(newCap int) {
	oldCap := cap(*es.getOrig())
	if newCap <= oldCap {
		return
	}

	newOrig := make([]*otlpmetrics.SummaryDataPoint_ValueAtQuantile, len(*es.getOrig()), newCap)
	copy(newOrig, *es.getOrig())
	*es.getOrig() = newOrig
}

// AppendEmpty will append to the end of the slice an empty ValueAtQuantile.
// It returns the newly added ValueAtQuantile.
func (es ValueAtQuantileSlice) AppendEmpty() ValueAtQuantile {
	*es.getOrig() = append(*es.getOrig(), &otlpmetrics.SummaryDataPoint_ValueAtQuantile{})
	return es.At(es.Len() - 1)
}

// Sort sorts the ValueAtQuantile elements within ValueAtQuantileSlice given the
// provided less function so that two instances of ValueAtQuantileSlice
// can be compared.
//
// Returns the same instance to allow nicer code like:
//
//	lessFunc := func(a, b ValueAtQuantile) bool {
//	  return a.Name() < b.Name() // choose any comparison here
//	}
//	assert.Equal(t, expected.Sort(lessFunc), actual.Sort(lessFunc))
func (es ValueAtQuantileSlice) Sort(less func(a, b ValueAtQuantile) bool) ValueAtQuantileSlice {
	sort.SliceStable(*es.getOrig(), func(i, j int) bool { return less(es.At(i), es.At(j)) })
	return es
}

// MoveAndAppendTo moves all elements from the current slice and appends them to the dest.
// The current slice will be cleared.
func (es ValueAtQuantileSlice) MoveAndAppendTo(dest ValueAtQuantileSlice) {
	if *dest.getOrig() == nil {
		// We can simply move the entire vector and avoid any allocations.
		*dest.getOrig() = *es.getOrig()
	} else {
		*dest.getOrig() = append(*dest.getOrig(), *es.getOrig()...)
	}
	*es.getOrig() = nil
}

// RemoveIf calls f sequentially for each element present in the slice.
// If f returns true, the element is removed from the slice.
func (es ValueAtQuantileSlice) RemoveIf(f func(ValueAtQuantile) bool) {
	newLen := 0
	for i := 0; i < len(*es.getOrig()); i++ {
		if f(es.At(i)) {
			continue
		}
		if newLen == i {
			// Nothing to move, element is at the right place.
			newLen++
			continue
		}
		(*es.getOrig())[newLen] = (*es.getOrig())[i]
		newLen++
	}
	// TODO: Prevent memory leak by erasing truncated values.
	*es.getOrig() = (*es.getOrig())[:newLen]
}

// ValueAtQuantile is a quantile value within a Summary data point.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewValueAtQuantile function to create new instances.
// Important: zero-initialized instance is not valid for use.

type ValueAtQuantile internal.ValueAtQuantile

func newValueAtQuantile(orig *otlpmetrics.SummaryDataPoint_ValueAtQuantile) ValueAtQuantile {
	return ValueAtQuantile(internal.NewValueAtQuantile(orig))
}

func (ms ValueAtQuantile) getOrig() *otlpmetrics.SummaryDataPoint_ValueAtQuantile {
	return internal.GetOrigValueAtQuantile(internal.ValueAtQuantile(ms))
}

// NewValueAtQuantile creates a new empty ValueAtQuantile.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewValueAtQuantile() ValueAtQuantile {
	return newValueAtQuantile(&otlpmetrics.SummaryDataPoint_ValueAtQuantile{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms ValueAtQuantile) MoveTo(dest ValueAtQuantile) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.SummaryDataPoint_ValueAtQuantile{}
}

// Quantile returns the quantile associated with this ValueAtQuantile.
func (ms ValueAtQuantile) Quantile() float64 {
	return ms.getOrig().Quantile
}

// SetQuantile replaces the quantile associated with this ValueAtQuantile.
func (ms ValueAtQuantile) SetQuantile(v float64) {
	ms.getOrig().Quantile = v
}

// Value returns the value associated with this ValueAtQuantile.
func (ms ValueAtQuantile) Value() float64 {
	return ms.getOrig().Value
}

// SetValue replaces the value associated with this ValueAtQuantile.
func (ms ValueAtQuantile) SetValue(v float64) {
	ms.getOrig().Value = v
}

// CopyTo copies all properties from the current struct to the dest.
func (ms ValueAtQuantile) CopyTo(dest ValueAtQuantile) {
	dest.SetQuantile(ms.Quantile())
	dest.SetValue(ms.Value())
}

// ExemplarSlice logically represents a slice of Exemplar.
//
// This is a reference type. If passed by value and callee modifies it, the
// caller will see the modification.
//
// Must use NewExemplarSlice function to create new instances.
// Important: zero-initialized instance is not valid for use.
type ExemplarSlice internal.ExemplarSlice

func newExemplarSlice(orig *[]otlpmetrics.Exemplar) ExemplarSlice {
	return ExemplarSlice(internal.NewExemplarSlice(orig))
}

func (ms ExemplarSlice) getOrig() *[]otlpmetrics.Exemplar {
	return internal.GetOrigExemplarSlice(internal.ExemplarSlice(ms))
}

// NewExemplarSlice creates a ExemplarSlice with 0 elements.
// Can use "EnsureCapacity" to initialize with a given capacity.
func NewExemplarSlice() ExemplarSlice {
	orig := []otlpmetrics.Exemplar(nil)
	return ExemplarSlice(internal.NewExemplarSlice(&orig))
}

// Len returns the number of elements in the slice.
//
// Returns "0" for a newly instance created with "NewExemplarSlice()".
func (es ExemplarSlice) Len() int {
	return len(*es.getOrig())
}

// At returns the element at the given index.
//
// This function is used mostly for iterating over all the values in the slice:
//
//	for i := 0; i < es.Len(); i++ {
//	    e := es.At(i)
//	    ... // Do something with the element
//	}
func (es ExemplarSlice) At(ix int) Exemplar {
	return newExemplar(&(*es.getOrig())[ix])
}

// CopyTo copies all elements from the current slice to the dest.
func (es ExemplarSlice) CopyTo(dest ExemplarSlice) {
	srcLen := es.Len()
	destCap := cap(*dest.getOrig())
	if srcLen <= destCap {
		(*dest.getOrig()) = (*dest.getOrig())[:srcLen:destCap]
	} else {
		(*dest.getOrig()) = make([]otlpmetrics.Exemplar, srcLen)
	}

	for i := range *es.getOrig() {
		newExemplar(&(*es.getOrig())[i]).CopyTo(newExemplar(&(*dest.getOrig())[i]))
	}
}

// EnsureCapacity is an operation that ensures the slice has at least the specified capacity.
// 1. If the newCap <= cap then no change in capacity.
// 2. If the newCap > cap then the slice capacity will be expanded to equal newCap.
//
// Here is how a new ExemplarSlice can be initialized:
//
//	es := NewExemplarSlice()
//	es.EnsureCapacity(4)
//	for i := 0; i < 4; i++ {
//	    e := es.AppendEmpty()
//	    // Here should set all the values for e.
//	}
func (es ExemplarSlice) EnsureCapacity(newCap int) {
	oldCap := cap(*es.getOrig())
	if newCap <= oldCap {
		return
	}

	newOrig := make([]otlpmetrics.Exemplar, len(*es.getOrig()), newCap)
	copy(newOrig, *es.getOrig())
	*es.getOrig() = newOrig
}

// AppendEmpty will append to the end of the slice an empty Exemplar.
// It returns the newly added Exemplar.
func (es ExemplarSlice) AppendEmpty() Exemplar {
	*es.getOrig() = append(*es.getOrig(), otlpmetrics.Exemplar{})
	return es.At(es.Len() - 1)
}

// MoveAndAppendTo moves all elements from the current slice and appends them to the dest.
// The current slice will be cleared.
func (es ExemplarSlice) MoveAndAppendTo(dest ExemplarSlice) {
	if *dest.getOrig() == nil {
		// We can simply move the entire vector and avoid any allocations.
		*dest.getOrig() = *es.getOrig()
	} else {
		*dest.getOrig() = append(*dest.getOrig(), *es.getOrig()...)
	}
	*es.getOrig() = nil
}

// RemoveIf calls f sequentially for each element present in the slice.
// If f returns true, the element is removed from the slice.
func (es ExemplarSlice) RemoveIf(f func(Exemplar) bool) {
	newLen := 0
	for i := 0; i < len(*es.getOrig()); i++ {
		if f(es.At(i)) {
			continue
		}
		if newLen == i {
			// Nothing to move, element is at the right place.
			newLen++
			continue
		}
		(*es.getOrig())[newLen] = (*es.getOrig())[i]
		newLen++
	}
	// TODO: Prevent memory leak by erasing truncated values.
	*es.getOrig() = (*es.getOrig())[:newLen]
}

// Exemplar is a sample input double measurement.
//
// Exemplars also hold information about the environment when the measurement was recorded,
// for example the span and trace ID of the active span when the exemplar was recorded.
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use NewExemplar function to create new instances.
// Important: zero-initialized instance is not valid for use.

type Exemplar internal.Exemplar

func newExemplar(orig *otlpmetrics.Exemplar) Exemplar {
	return Exemplar(internal.NewExemplar(orig))
}

func (ms Exemplar) getOrig() *otlpmetrics.Exemplar {
	return internal.GetOrigExemplar(internal.Exemplar(ms))
}

// NewExemplar creates a new empty Exemplar.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func NewExemplar() Exemplar {
	return newExemplar(&otlpmetrics.Exemplar{})
}

// MoveTo moves all properties from the current struct to dest
// resetting the current instance to its zero value
func (ms Exemplar) MoveTo(dest Exemplar) {
	*dest.getOrig() = *ms.getOrig()
	*ms.getOrig() = otlpmetrics.Exemplar{}
}

// Timestamp returns the timestamp associated with this Exemplar.
func (ms Exemplar) Timestamp() pcommon.Timestamp {
	return pcommon.Timestamp(ms.getOrig().TimeUnixNano)
}

// SetTimestamp replaces the timestamp associated with this Exemplar.
func (ms Exemplar) SetTimestamp(v pcommon.Timestamp) {
	ms.getOrig().TimeUnixNano = uint64(v)
}

// ValueType returns the type of the value for this Exemplar.
// Calling this function on zero-initialized Exemplar will cause a panic.
func (ms Exemplar) ValueType() ExemplarValueType {
	switch ms.getOrig().Value.(type) {
	case *otlpmetrics.Exemplar_AsDouble:
		return ExemplarValueTypeDouble
	case *otlpmetrics.Exemplar_AsInt:
		return ExemplarValueTypeInt
	}
	return ExemplarValueTypeNone
}

// DoubleVal returns the doubleval associated with this Exemplar.
func (ms Exemplar) DoubleVal() float64 {
	return ms.getOrig().GetAsDouble()
}

// SetDoubleVal replaces the doubleval associated with this Exemplar.
func (ms Exemplar) SetDoubleVal(v float64) {
	ms.getOrig().Value = &otlpmetrics.Exemplar_AsDouble{
		AsDouble: v,
	}
}

// IntVal returns the intval associated with this Exemplar.
func (ms Exemplar) IntVal() int64 {
	return ms.getOrig().GetAsInt()
}

// SetIntVal replaces the intval associated with this Exemplar.
func (ms Exemplar) SetIntVal(v int64) {
	ms.getOrig().Value = &otlpmetrics.Exemplar_AsInt{
		AsInt: v,
	}
}

// FilteredAttributes returns the FilteredAttributes associated with this Exemplar.
func (ms Exemplar) FilteredAttributes() pcommon.Map {
	return pcommon.Map(internal.NewMap(&ms.getOrig().FilteredAttributes))
}

// TraceID returns the traceid associated with this Exemplar.
func (ms Exemplar) TraceID() pcommon.TraceID {
	return pcommon.TraceID(ms.getOrig().TraceId)
}

// SetTraceID replaces the traceid associated with this Exemplar.
func (ms Exemplar) SetTraceID(v pcommon.TraceID) {
	ms.getOrig().TraceId = data.TraceID(v)
}

// SpanID returns the spanid associated with this Exemplar.
func (ms Exemplar) SpanID() pcommon.SpanID {
	return pcommon.SpanID(ms.getOrig().SpanId)
}

// SetSpanID replaces the spanid associated with this Exemplar.
func (ms Exemplar) SetSpanID(v pcommon.SpanID) {
	ms.getOrig().SpanId = data.SpanID(v)
}

// CopyTo copies all properties from the current struct to the dest.
func (ms Exemplar) CopyTo(dest Exemplar) {
	dest.SetTimestamp(ms.Timestamp())
	switch ms.ValueType() {
	case ExemplarValueTypeDouble:
		dest.SetDoubleVal(ms.DoubleVal())
	case ExemplarValueTypeInt:
		dest.SetIntVal(ms.IntVal())
	}

	ms.FilteredAttributes().CopyTo(dest.FilteredAttributes())
	dest.SetTraceID(ms.TraceID())
	dest.SetSpanID(ms.SpanID())
}
