func inferEndpoints(epSpec0, epSpec1 endpoint, get func(svc string) (*Meta, error)) (endpoint, endpoint, error) {
	if epSpec0.relation != "" && epSpec1.relation != "" {
		// The endpoints are already specified explicitly so
		// there is no need to fetch any charm data to infer
		// them.
		return epSpec0, epSpec1, nil
	}
	eps0, err := possibleEndpoints(epSpec0, get)
	if err != nil {
		return endpoint{}, endpoint{}, err
	}
	eps1, err := possibleEndpoints(epSpec1, get)
	if err != nil {
		return endpoint{}, endpoint{}, err
	}
	var candidates [][]endpointInfo
	for _, ep0 := range eps0 {
		for _, ep1 := range eps1 {
			if ep0.canRelateTo(ep1) {
				candidates = append(candidates, []endpointInfo{ep0, ep1})
			}
		}
	}
	switch len(candidates) {
	case 0:
		return endpoint{}, endpoint{}, fmt.Errorf("no relations found")
	case 1:
		return candidates[0][0].endpoint(), candidates[0][1].endpoint(), nil
	}

	// There's ambiguity; try discarding implicit relations.
	filtered := discardImplicitRelations(candidates)
	if len(filtered) == 1 {
		return filtered[0][0].endpoint(), filtered[0][1].endpoint(), nil
	}
	// The ambiguity cannot be resolved, so return an error.
	var keys []string
	for _, cand := range candidates {
		keys = append(keys, fmt.Sprintf("%q", relationKey(cand)))
	}
	sort.Strings(keys)
	return endpoint{}, endpoint{}, fmt.Errorf("ambiguous relation: %s %s could refer to %s",
		epSpec0, epSpec1, strings.Join(keys, "; "))
}
// inferEndpoints infers missing relation names from the given endpoint
// specifications, using the given get function to retrieve charm
// data if necessary. It returns the fully specified endpoints.
inferEndpoints infers missing relation names from the given endpoint
specifications, using the given get function to retrieve charm
data if necessary. It returns the fully specified endpoints.
// inferEndpoints infers missing relation names from the given endpoint // specifications using the given get function to retrieve charm // data if necessary . It returns the fully specified endpoints .
func inferEndpoints(epSpec0, epSpec1 endpoint, get func(svc string) (*Meta, error)) (endpoint, endpoint, error) {
	if epSpec0.relation != "" && epSpec1.relation != "" {
		return epSpec0, epSpec1, nil
	}
	eps0, err := possibleEndpoints(epSpec0, get)
	if err != nil {
		return endpoint{}, endpoint{}, err
	}
	eps1, err := possibleEndpoints(epSpec1, get)
	if err != nil {
		return endpoint{}, endpoint{}, err
	}
	var candidates [][]endpointInfo
	for _, ep0 := range eps0 {
		for _, ep1 := range eps1 {
			if ep0.canRelateTo(ep1) {
				candidates = append(candidates, []endpointInfo{ep0, ep1})
			}
		}
	}
	switch len(candidates) {
	case 0:
		return endpoint{}, endpoint{}, fmt.Errorf("no relations found")
	case 1:
		return candidates[0][0].endpoint(), candidates[0][1].endpoint(), nil
	}
	filtered := discardImplicitRelations(candidates)
	if len(filtered) == 1 {
		return filtered[0][0].endpoint(), filtered[0][1].endpoint(), nil
	}
	var keys []string
	for _, cand := range candidates {
		keys = append(keys, fmt.Sprintf("%q", relationKey(cand)))
	}
	sort.Strings(keys)
	return endpoint{}, endpoint{}, fmt.Errorf("ambiguous relation: %s %s could refer to %s",
		epSpec0, epSpec1, strings.Join(keys, "; "))
}
func inferEndpoints ( epSpec0 , epSpec1 endpoint , get func ( svc string ) ( * Meta , error ) ) ( endpoint , endpoint , error ) { if epSpec0 . relation != " " && epSpec1 . relation != " " { return epSpec0 , epSpec1 , nil } eps0 , err := possibleEndpoints ( epSpec0 , get ) if err != nil { return endpoint { } , endpoint { } , err } eps1 , err := possibleEndpoints ( epSpec1 , get ) if err != nil { return endpoint { } , endpoint { } , err } var candidates [ ] [ ] endpointInfo for _ , ep0 := range eps0 { for _ , ep1 := range eps1 { if ep0 . canRelateTo ( ep1 ) { candidates = append ( candidates , [ ] endpointInfo { ep0 , ep1 } ) } } } switch len ( candidates ) { case 0 : return endpoint { } , endpoint { } , fmt . Errorf ( " " ) case 1 : return candidates [ 0 ] [ 0 ] . endpoint ( ) , candidates [ 0 ] [ 1 ] . endpoint ( ) , nil } filtered := discardImplicitRelations ( candidates ) if len ( filtered ) == 1 { return filtered [ 0 ] [ 0 ] . endpoint ( ) , filtered [ 0 ] [ 1 ] . endpoint ( ) , nil } var keys [ ] string for _ , cand := range candidates { keys = append ( keys , fmt . Sprintf ( " " , relationKey ( cand ) ) ) } sort . Strings ( keys ) return endpoint { } , endpoint { } , fmt . Errorf ( " " , epSpec0 , epSpec1 , strings . Join ( keys , " " ) ) }
inferEndpoints infers missing relation names from the given endpoint
specifications, using the given get function to retrieve charm
data if necessary.
inferEndpoints infers missing relation names from the given endpoint specifications using the given get function to retrieve charm data if necessary .
// The endpoints are already specified explicitly so // there is no need to fetch any charm data to infer // them. // There's ambiguity; try discarding implicit relations. // The ambiguity cannot be resolved, so return an error.