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: go_collector_latest.go
    path of file: ./repos/devspace/vendor/github.com/prometheus/client_golang/prometheus
    
    the code of the file until where you have to start completion: // Copyright 2021 The Prometheus Authors
// Licens
    
func (c *goCollector) Collect(ch chan<- Metric) {
	// Collect base non-memory metrics.
	c.base.Collect(ch)

	if len(c.sampleBuf) == 0 {
		return
	}

	// Collect must be thread-safe, so prevent concurrent use of
	// sampleBuf elements. Just read into sampleBuf but write all the data
	// we get into our Metrics or MemStats.
	//
	// This lock also ensures that the Metrics we send out are all from
	// the same updates, ensuring their mutual consistency insofar as
	// is guaranteed by the runtime/metrics package.
	//
	// N.B. This locking is heavy-handed, but Collect is expected to be called
	// relatively infrequently. Also the core operation here, metrics.Read,
	// is fast (O(tens of microseconds)) so contention should certainly be
	// low, though channel operations and any allocations may add to that.
	c.mu.Lock()
	defer c.mu.Unlock()

	// Populate runtime/metrics sample buffer.
	metrics.Read(c.sampleBuf)

	// Collect all our runtime/metrics user chose to expose from sampleBuf (if any).
	for i, metric := range c.rmExposedMetrics {
		// We created samples for exposed metrics first in order, so indexes match.
		sample := c.sampleBuf[i]

		// N.B. switch on concrete type because it's significantly more efficient
		// than checking for the Counter and Gauge interface implementations. In
		// this case, we control all the types here.
		switch m := metric.(type) {
		case *counter:
			// Guard against decreases. This should never happen, but a failure
			// to do so will result in a panic, which is a harsh consequence for
			// a metrics collection bug.
			v0, v1 := m.get(), unwrapScalarRMValue(sample.Value)
			if v1 > v0 {
				m.Add(unwrapScalarRMValue(sample.Value) - m.get())
			}
			m.Collect(ch)
		case *gauge:
			m.Set(unwrapScalarRMValue(sample.Value))
			m.Collect(ch)
		case *batchHistogram:
			m.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name))
			m.Collect(ch)
		default:
			panic("unexpected metric type")
		}
	}

	if c.msMetricsEnabled {
		// ms is a dummy MemStats that we populate ourselves so that we can
		// populate the old metrics from it if goMemStatsCollection is enabled.
		var ms runtime.MemStats
		memStatsFromRM(&ms, c.sampleMap)
		for _, i := range c.msMetrics {
			ch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms))
		}
	}
}