Add dynamic sequence identity selectors
This commit is contained in:
@@ -228,7 +228,7 @@ func validateRegisteredSequences(claims []compositionClaim, policy sequencePolic
|
||||
if claim.kind != document.Sequence {
|
||||
continue
|
||||
}
|
||||
identityField, registered := policy.identityFields[claim.path.String()]
|
||||
identityFields, registered := policy.identityFieldsAt(claim.path)
|
||||
if !registered {
|
||||
continue
|
||||
}
|
||||
@@ -254,36 +254,71 @@ func validateRegisteredSequences(claims []compositionClaim, policy sequencePolic
|
||||
Path: itemPath, Message: "registered sequence items must be mappings", Primary: location,
|
||||
}}
|
||||
}
|
||||
fieldIndex := documentEntryIndex(item.Mapping, identityField)
|
||||
if fieldIndex < 0 {
|
||||
location := publicLocation(item.Location)
|
||||
return nil, nil, []Diagnostic{{
|
||||
Code: CodeComposeInvalid, Severity: SeverityError,
|
||||
Path: itemPath, Message: "registered sequence item is missing its identity field",
|
||||
Primary: &location,
|
||||
}}
|
||||
}
|
||||
field := item.Mapping[fieldIndex].Value
|
||||
if field == nil || field.Kind != document.String {
|
||||
location := publicLocation(item.Mapping[fieldIndex].ValueLocation)
|
||||
if field != nil {
|
||||
location = publicLocation(field.Location)
|
||||
var identity string
|
||||
var identityLocation document.Location
|
||||
if legacyField, legacy := policy.identityFields[claim.path.String()]; legacy {
|
||||
fieldIndex := documentEntryIndex(item.Mapping, legacyField)
|
||||
if fieldIndex < 0 {
|
||||
location := publicLocation(item.Location)
|
||||
return nil, nil, []Diagnostic{{
|
||||
Code: CodeComposeInvalid, Severity: SeverityError,
|
||||
Path: itemPath, Message: "registered sequence item is missing its identity field",
|
||||
Primary: &location,
|
||||
}}
|
||||
}
|
||||
return nil, nil, []Diagnostic{{
|
||||
Code: CodeComposeInvalid, Severity: SeverityError,
|
||||
Path: itemPath.Key(identityField), Message: "registered sequence identity must be a string",
|
||||
Primary: &location,
|
||||
}}
|
||||
field := item.Mapping[fieldIndex].Value
|
||||
if field == nil || field.Kind != document.String {
|
||||
location := publicLocation(item.Mapping[fieldIndex].ValueLocation)
|
||||
if field != nil {
|
||||
location = publicLocation(field.Location)
|
||||
}
|
||||
return nil, nil, []Diagnostic{{
|
||||
Code: CodeComposeInvalid, Severity: SeverityError,
|
||||
Path: itemPath.Key(legacyField), Message: "registered sequence identity must be a string",
|
||||
Primary: &location,
|
||||
}}
|
||||
}
|
||||
identity, identityLocation = field.Text, field.Location
|
||||
} else {
|
||||
mapping := newSequenceMappingIndex(item)
|
||||
var locations []document.Location
|
||||
var fieldName string
|
||||
var fieldIndex int
|
||||
identity, locations, fieldName, fieldIndex = mapping.identity(identityFields)
|
||||
if fieldIndex == -1 {
|
||||
location := publicLocation(item.Location)
|
||||
return nil, nil, []Diagnostic{{
|
||||
Code: CodeComposeInvalid, Severity: SeverityError,
|
||||
Path: itemPath.Key(fieldName), Message: "registered sequence item is missing an identity field",
|
||||
Primary: &location,
|
||||
}}
|
||||
}
|
||||
if fieldIndex == -2 || fieldIndex >= 0 {
|
||||
location := publicLocation(item.Location)
|
||||
fieldPath := itemPath.Key(fieldName)
|
||||
if fieldIndex >= 0 {
|
||||
location = publicLocation(item.Mapping[fieldIndex].ValueLocation)
|
||||
if field := item.Mapping[fieldIndex].Value; field != nil {
|
||||
location = publicLocation(field.Location)
|
||||
}
|
||||
}
|
||||
return nil, nil, []Diagnostic{{
|
||||
Code: CodeComposeInvalid, Severity: SeverityError,
|
||||
Path: fieldPath, Message: "registered sequence identity fields must be scalar values",
|
||||
Primary: &location,
|
||||
}}
|
||||
}
|
||||
identityLocation = locations[0]
|
||||
}
|
||||
if first, duplicate := identities[field.Text]; duplicate {
|
||||
current := publicLocation(field.Location)
|
||||
if first, duplicate := identities[identity]; duplicate {
|
||||
current := publicLocation(identityLocation)
|
||||
return nil, nil, []Diagnostic{{
|
||||
Code: CodeComposeConflict, Severity: SeverityError,
|
||||
Path: claim.path.clone(), Message: "registered sequence contains duplicate identities",
|
||||
Primary: &first, Related: []Location{current},
|
||||
}}
|
||||
}
|
||||
identities[field.Text] = publicLocation(field.Location)
|
||||
identities[identity] = publicLocation(identityLocation)
|
||||
}
|
||||
if itemsByPath[pathKey] == nil {
|
||||
itemsByPath[pathKey] = make(map[int]validatedSequence)
|
||||
@@ -328,11 +363,6 @@ func mergeDisjointMappingsAtPath(target, incoming *document.Node, path Path, ind
|
||||
mergeComposedMappings(target, incoming, path, index, sourceIndex, policy, validated)
|
||||
}
|
||||
|
||||
func (p sequencePolicy) registered(path Path) bool {
|
||||
_, ok := p.identityFields[path.String()]
|
||||
return ok
|
||||
}
|
||||
|
||||
func cloneSequenceRanges(ranges []sequenceRange) []sequenceRange {
|
||||
cloned := make([]sequenceRange, len(ranges))
|
||||
for i, assigned := range ranges {
|
||||
|
||||
Reference in New Issue
Block a user