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: etcd.go
    path of file: ./repos/goldfish/vendor/github.com/hashicorp/vault/physical/etcd
    
    the code of the file until where you have to start completion: package etcd

import (
	"context"
	"errors"
	"fmt"
	"net/url"
	"os"
	"strings"

	"github.com/coreos/etcd/client"
	"github.com/coreos/go-semver/semver"
	"github.com/hashicorp/vault/physical"
	log "github
    
func NewEtcdBackend(conf map[string]string, logger log.Logger) (physical.Backend, error) {
	var (
		apiVersion string
		ok         bool
	)

	// v2 client can talk to both etcd2 and etcd3 thought API v2
	c, err := newEtcdV2Client(conf)
	if err != nil {
		return nil, errors.New("failed to create etcd client: " + err.Error())
	}

	remoteAPIVersion, err := getEtcdAPIVersion(c)
	if err != nil {
		return nil, errors.New("failed to get etcd API version: " + err.Error())
	}

	if apiVersion, ok = conf["etcd_api"]; !ok {
		apiVersion = os.Getenv("ETCD_API")
	}

	if apiVersion == "" {
		path, ok := conf["path"]
		if !ok {
			path = "/vault"
		}
		kAPI := client.NewKeysAPI(c)

		// keep using v2 if vault data exists in v2 and user does not explicitly
		// ask for v3.
		_, err := kAPI.Get(context.Background(), path, &client.GetOptions{})
		if errorIsMissingKey(err) {
			apiVersion = remoteAPIVersion
		} else if err == nil {
			apiVersion = "2"
		} else {
			return nil, errors.New("failed to check etcd status: " + err.Error())
		}
	}

	switch apiVersion {
	case "2", "etcd2", "v2":
		return newEtcd2Backend(conf, logger)
	case "3", "etcd3", "v3":
		if remoteAPIVersion == "2" {
			return nil, errors.New("etcd3 is required: etcd2 is running")
		}
		return newEtcd3Backend(conf, logger)
	default:
		return nil, EtcdVersionUnknown
	}
}