// Code generated by gotmpl. DO NOT MODIFY.
// source: internal/shared/otlp/observ/target.go.tmpl

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

package observ // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/observ"

import (
	
	
	
	
	
	
)

const (
	schemeUnix         = "unix"
	schemeUnixAbstract = "unix-abstract"
)

// ParseCanonicalTarget parses a target string and returns the extracted host
// (domain address or IP), the target port, or an error.
//
// If no port is specified, -1 is returned.
//
// If no host is specified, an empty string is returned.
//
// The target string is expected to always have the form
// "<scheme>://[authority]/<endpoint>". For example:
//   - "dns:///example.com:42"
//   - "dns://8.8.8.8/example.com:42"
//   - "unix:///path/to/socket"
//   - "unix-abstract:///socket-name"
//   - "passthrough:///192.34.2.1:42"
//
// The target is expected to come from the CanonicalTarget method of a gRPC
// Client.
func ( string) (string, int, error) {
	const  = "://"

	// Find scheme. Do not allocate the string by using url.Parse.
	 := strings.Index(, )
	if  == -1 {
		return "", -1, fmt.Errorf("invalid target %q: missing scheme", )
	}
	,  := [:], [+len():]

	// Check for unix schemes.
	if  == schemeUnix ||  == schemeUnixAbstract {
		return parseUnix()
	}

	// Strip leading slash and any authority.
	if  := strings.Index(, "/");  != -1 {
		 = [+1:]
	}

	// DNS, passthrough, and custom resolvers.
	return parseEndpoint()
}

// parseUnix parses unix socket targets.
func parseUnix( string) (string, int, error) {
	// Format: unix[-abstract]://path
	//
	// We should have "/path" (empty authority) if valid.
	if len() >= 1 && [0] == '/' {
		// Return the full path including leading slash.
		return , -1, nil
	}

	// If there's no leading slash, it means there might be an authority
	// Check for authority case (should error): "authority/path"
	if  := strings.Index(, "/");  > 0 {
		return "", -1, fmt.Errorf("invalid (non-empty) authority: %s", [:])
	}

	return "", -1, errors.New("invalid unix target format")
}

// parseEndpoint parses an endpoint from a gRPC target.
//
// It supports the following formats:
//   - "host"
//   - "host%zone"
//   - "host:port"
//   - "host%zone:port"
//   - "ipv4"
//   - "ipv4%zone"
//   - "ipv4:port"
//   - "ipv4%zone:port"
//   - "ipv6"
//   - "ipv6%zone"
//   - "[ipv6]"
//   - "[ipv6%zone]"
//   - "[ipv6]:port"
//   - "[ipv6%zone]:port"
//
// It returns the host or host%zone (domain address or IP), the port (or -1 if
// not specified), or an error if the input is not a valid.
func parseEndpoint( string) (string, int, error) {
	// First check if the endpoint is just an IP address.
	if  := parseIP();  != "" {
		return , -1, nil
	}

	// If there's no colon, there is no port (IPv6 with no port checked above).
	if !strings.Contains(, ":") {
		return , -1, nil
	}

	, ,  := net.SplitHostPort()
	if  != nil {
		return "", -1, fmt.Errorf("invalid host:port %q: %w", , )
	}

	const ,  = 10, 16
	,  := strconv.ParseUint(, , )
	if  != nil {
		return "", -1, fmt.Errorf("invalid port %q: %w", , )
	}
	 := int() // port is guaranteed to be in the range [0, 65535].

	return , , nil
}

// parseIP attempts to parse the entire endpoint as an IP address.
// It returns the normalized string form of the IP if successful,
// or an empty string if parsing fails.
func parseIP( string) string {
	// Strip leading and trailing brackets for IPv6 addresses.
	if len() >= 2 && [0] == '[' && [len()-1] == ']' {
		 = [1 : len()-1]
	}
	,  := netip.ParseAddr()
	if  != nil {
		return ""
	}
	// Return the normalized string form of the IP.
	return .String()
}