package engine import "gitea.maximumdirect.net/eric/ConfigKit/internal/document" type inheritanceTemplateResult struct { value *document.Node origins map[string]Origin collectionPolicies collectionPolicyScope policyTemplates []collectionPolicyScope controls []inheritanceControl transfers []inheritanceTransfer replacements []inheritanceReplacement operations []inheritanceOperation } func combineInheritanceTemplate( template inheritanceExecutionTemplate, child preparedInheritanceChild, parent *preparedInheritanceParent, parentOrigins map[string]Origin, applicationPolicy sequencePolicy, ) (inheritanceTemplateResult, []Diagnostic) { result := inheritanceTemplateResult{} if child.control != nil { result.controls = append(result.controls, *child.control) result.operations = append(result.operations, inheritanceOperation{ control: child.control, controlOrigin: child.controlOrigin, }) } if parent == nil { result.value = document.Clone(child.payload) result.origins = child.origins result.collectionPolicies = cloneCollectionPolicyScopeForInheritance(child.policyTemplates) result.policyTemplates = []collectionPolicyScope{child.policyTemplates} return result, nil } mergedPolicyScope, diagnostics := mergeInheritanceCollectionPolicies( parent.parentPolicyScope, parent.childPolicyScope, template.path, parent.payload, child.payload, applicationPolicy, parent.replaced, ) if len(diagnostics) != 0 { return inheritanceTemplateResult{}, diagnostics } mergedOrigins := transferredInheritanceOrigins(parentOrigins, parent.transfer.from, template.path, parent.transfer) mergeInheritanceOrigin(mergedOrigins, template.path, child.origins[template.path.String()]) var sequenceContributions []sequenceHistoryContribution var combinationDiagnostics []Diagnostic mergeRecursiveMappings(parent.payload, child.payload, template.path, new(mappingIndex), recursiveMergeHooks{ added: func(childPath Path, incoming *document.Node) { copyInheritanceSubtree(mergedOrigins, child.origins, incoming, childPath) }, combined: func(childPath Path, _ *document.Node) { mergeInheritanceOrigin(mergedOrigins, childPath, child.origins[childPath.String()]) }, replaced: func(childPath Path, existing, incoming *document.Node) { result.replacements = append(result.replacements, inheritanceReplacement{ before: existing, after: incoming, }) deleteOriginSubtree(mergedOrigins, childPath, existing) copyInheritanceSubtree(mergedOrigins, child.origins, incoming, childPath) }, merge: func(childPath Path, existing, incoming *document.Node) (*document.Node, bool) { resolution, _, _, active, issues := inheritanceCollectionResolution( childPath, parent.parentPolicyScope, parent.childPolicyScope, applicationPolicy, incoming, ) if len(issues) != 0 { combinationDiagnostics = append(combinationDiagnostics, issues...) return existing, false } if !active { return nil, false } lowerValue := existing combined, problems := combineSequence(lowerValue, incoming, resolution, sequenceCombinationContext{destination: childPath}) if len(problems) != 0 { combinationDiagnostics = append(combinationDiagnostics, problems...) return existing, false } policy := applyInheritanceSequencePolicy( childPath, combined, resolution, parent.parentPolicyScope, parent.childPolicyScope, ) mergedPolicyScope.set(childPath, policy) result.replacements = append(result.replacements, applyInheritanceSequenceOrigins( mergedOrigins, child.origins, childPath, lowerValue, incoming, combined, resolution.operation, )...) sequenceContributions = append(sequenceContributions, sequenceHistoryContributionForCombination( childPath, resolution.operation, incoming, combined, )) return combined.value, true }, }) preserveInheritanceIdentityFields(parent.payload, child.payload, template.identityFields) if len(combinationDiagnostics) != 0 { return inheritanceTemplateResult{}, canonicalDiagnostics(combinationDiagnostics) } if problems := validateRegisteredInheritanceSequences(parent.payload, template.path, applicationPolicy); len(problems) != 0 { return inheritanceTemplateResult{}, problems } parent.payload.Location = template.entry.Value.Location result.value = parent.payload result.origins = mergedOrigins result.collectionPolicies = inheritancePolicyScopeAtPath(mergedPolicyScope, template.path) result.policyTemplates = parent.effectivePolicyTemplates result.transfers = append(result.transfers, parent.transfer) result.operations = append(result.operations, inheritanceOperation{ transfer: &parent.transfer, parent: parent.historyParent, effective: parent.payload, parentOrigins: parentOrigins, effectiveOrigins: mergedOrigins, parentPolicies: cloneInheritancePolicyTemplates(parent.policyTemplates), templatePolicies: cloneCollectionPolicyScopeForInheritance(child.policyTemplates), effectivePolicies: cloneInheritancePolicyTemplates(parent.effectivePolicyTemplates), sequences: cloneSequenceHistoryContributions(sequenceContributions), identityFields: cloneStrings(template.identityFields), }) return result, nil }