You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: producer.go
    path of file: ./repos/opencensus-go/plugin/runmetrics
    
    the code of the file until where you have to start completion: package runmetrics

import (
	"errors"
	"runtime"
	"sync"
	"time"

	"go.opencensus.io/metric"
	"go.opencensus.io/metric/metricdata"
	"go.opencensus.io/metric/metricproducer"
)

type (
	// producer produces runtime metrics.
	//
	// Enable collection of runtime metrics with Enable().
	producer struct {
		options RunMetricOptions
		reg     *metric.Registry

		deprecatedMemStats *deprecatedMemStats
		memStats           *memStats
		cpuStats           *cpuStats
	}

	// RunMetricOptions allows to configure runtime metrics.
	RunMetricOptions struct {
		EnableCPU            bool   // EnableCPU whether CPU metrics shall be recorded
		EnableMemory         bool   // EnableMemory whether memory metrics shall be recorded
		Prefix               string // Prefix is a custom prefix for metric names
		UseDerivedCumulative bool   // UseDerivedCumulative whether DerivedCumulative metrics should be used
	}

	deprecatedMemStats struct {
		memStats runtime.MemStats

		memAlloc   *metric.Int64GaugeEntry
		memTotal   *metric.Int64GaugeEntry
		memSys     *metric.Int64GaugeEntry
		memLookups *metric.Int64GaugeEntry
		memMalloc  *metric.Int64GaugeEntry
		memFrees   *metric.Int64GaugeEntry

		heapAlloc    *metric.Int64GaugeEntry
		heapSys      *metric.Int64GaugeEntry
		heapIdle     *metric.Int64GaugeEntry
		heapInuse    *metric.Int64GaugeEntry
		heapObjects  *metric.Int64GaugeEntry
		heapReleased *metric.Int64GaugeEntry

		stackInuse       *metric.Int64GaugeEntry
		stackSys         *metric.Int64GaugeEntry
		stackMSpanInuse  *metric.Int64GaugeEntry
		stackMSpanSys    *metric.Int64GaugeEntry
		stackMCacheInuse *metric.Int64GaugeEntry
		stackMCacheSys   *metric.Int64GaugeEntry

		otherSys      *metric.Int64GaugeEntry
		gcSys         *metric.Int64GaugeEntry
		numGC         *metric.Int64GaugeEntry
		numForcedGC   *metric.Int64GaugeEntry
		nextGC        *metric.Int64GaugeEntry
		lastGC        *metric.Int64GaugeEntry
		pauseTotalNs  *metric.Int64GaugeEntry
		gcCPUFraction *metric.Float64Entry
	}

	memStats struct {
		memStats runtime.MemStats

		memAlloc   *metric.Int64GaugeEntry
		memTotal   *metric.Int64DerivedCumulative
		memSys     *metric.Int64GaugeEntry
		memLookups *metric.Int64DerivedCumulative
		memMalloc  *metric.Int64DerivedCumulative
		memFrees   *metric.Int64DerivedCumulative

		heapAlloc    *metric.Int64GaugeEntry
		heapSys      *metric.Int64GaugeEntry
		heapIdle     *metric.Int64GaugeEntry
		heapInuse    *metric.Int64GaugeEntry
		heapObjects  *metric.Int64GaugeEntry
		heapReleased *metric.Int64DerivedCumulative

		stackInuse       *metric.Int64GaugeEntry
		stackSys         *metric.Int64GaugeEntry
		stackMSpanInuse  *metric.Int64GaugeEntry
		stackMSpanSys    *metric.Int64GaugeEntry
		stackMCacheInuse *metric.Int64GaugeEntry
		stackMCacheSys   *metric.Int64GaugeEntr
    
func newMemStats(producer *producer) (*memStats, error) {
	var err error
	memStats := &memStats{}

	// General
	memStats.memAlloc, err = producer.createInt64GaugeEntry("process/memory_alloc", "Number of bytes currently allocated in use", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.memTotal, err = producer.createInt64DerivedCumulative("process/total_memory_alloc", "Number of allocations in total", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.memSys, err = producer.createInt64GaugeEntry("process/sys_memory_alloc", "Number of bytes given to the process to use in total", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.memLookups, err = producer.createInt64DerivedCumulative("process/memory_lookups", "Cumulative number of pointer lookups performed by the runtime", metricdata.UnitDimensionless)
	if err != nil {
		return nil, err
	}

	memStats.memMalloc, err = producer.createInt64DerivedCumulative("process/memory_malloc", "Cumulative count of heap objects allocated", metricdata.UnitDimensionless)
	if err != nil {
		return nil, err
	}

	memStats.memFrees, err = producer.createInt64DerivedCumulative("process/memory_frees", "Cumulative count of heap objects freed", metricdata.UnitDimensionless)
	if err != nil {
		return nil, err
	}

	// Heap
	memStats.heapAlloc, err = producer.createInt64GaugeEntry("process/heap_alloc", "Process heap allocation", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.heapSys, err = producer.createInt64GaugeEntry("process/sys_heap", "Bytes of heap memory obtained from the OS", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.heapIdle, err = producer.createInt64GaugeEntry("process/heap_idle", "Bytes in idle (unused) spans", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.heapInuse, err = producer.createInt64GaugeEntry("process/heap_inuse", "Bytes in in-use spans", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.heapObjects, err = producer.createInt64GaugeEntry("process/heap_objects", "The number of objects allocated on the heap", metricdata.UnitDimensionless)
	if err != nil {
		return nil, err
	}

	memStats.heapReleased, err = producer.createInt64DerivedCumulative("process/heap_release", "The cumulative number of objects released from the heap", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	// Stack
	memStats.stackInuse, err = producer.createInt64GaugeEntry("process/stack_inuse", "Bytes in stack spans", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.stackSys, err = producer.createInt64GaugeEntry("process/sys_stack", "The memory used by stack spans and OS thread stacks", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.stackMSpanInuse, err = producer.createInt64GaugeEntry("process/stack_mspan_inuse", "Bytes of allocated mspan structures", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.stackMSpanSys, err = producer.createInt64GaugeEntry("process/sys_stack_mspan", "Bytes of memory obtained from the OS for mspan structures", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.stackMCacheInuse, err = producer.createInt64GaugeEntry("process/stack_mcache_inuse", "Bytes of allocated mcache structures", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.stackMCacheSys, err = producer.createInt64GaugeEntry("process/sys_stack_mcache", "Bytes of memory obtained from the OS for mcache structures", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	// GC
	memStats.gcSys, err = producer.createInt64GaugeEntry("process/gc_sys", "Bytes of memory in garbage collection metadatas", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.otherSys, err = producer.createInt64GaugeEntry("process/other_sys", "Bytes of memory in miscellaneous off-heap runtime allocations", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.numGC, err = producer.createInt64DerivedCumulative("process/num_gc", "Cumulative count of completed GC cycles", metricdata.UnitDimensionless)
	if err != nil {
		return nil, err
	}

	memStats.numForcedGC, err = producer.createInt64DerivedCumulative("process/num_forced_gc", "Cumulative count of GC cycles forced by the application", metricdata.UnitDimensionless)
	if err != nil {
		return nil, err
	}

	memStats.nextGC, err = producer.createInt64GaugeEntry("process/next_gc_heap_size", "Target heap size of the next GC cycle in bytes", metricdata.UnitBytes)
	if err != nil {
		return nil, err
	}

	memStats.lastGC, err = producer.createInt64GaugeEntry("process/last_gc_finished_timestamp", "Time the last garbage collection finished, as milliseconds since 1970 (the UNIX epoch)", metricdata.UnitMilliseconds)
	if err != nil {
		return nil, err
	}

	memStats.pauseTotalNs, err = producer.createInt64DerivedCumulative("process/pause_total", "Cumulative milliseconds spent in GC stop-the-world pauses", metricdata.UnitMilliseconds)
	if err != nil {
		return nil, err
	}

	memStats.gcCPUFraction, err = producer.createFloat64GaugeEntry("process/gc_cpu_fraction", "Fraction of this program's available CPU time used by the GC since the program started", metricdata.UnitDimensionless)
	if err != nil {
		return nil, err
	}

	return memStats, nil
}