diff options
author | Arne H Juul <arnej@yahooinc.com> | 2022-03-16 07:03:54 +0000 |
---|---|---|
committer | Arne H Juul <arnej@yahooinc.com> | 2022-03-16 09:29:51 +0000 |
commit | a043188e341fa5a8874288fe0ffcb75b39708a57 (patch) | |
tree | 8c36043b733323203330e34f756ba2fbee5e752a /config-model/src/main/java/com/yahoo/searchdefinition/parser | |
parent | cd7f364094c441c7e2656d0d5efde3bf09914c42 (diff) |
pre-resolve struct and annotation inheritance
Diffstat (limited to 'config-model/src/main/java/com/yahoo/searchdefinition/parser')
-rw-r--r-- | config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertSchemaCollection.java | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertSchemaCollection.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertSchemaCollection.java index 8ee4a237258..79ad811bd2b 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertSchemaCollection.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertSchemaCollection.java @@ -125,6 +125,9 @@ public class ConvertSchemaCollection { } public List<Schema> convertToSchemas() { + resolveStructInheritance(); + resolveAnnotationInheritance(); + addMissingAnnotationStructs(); var converter = new ConvertParsedSchemas(orderedInput, docMan, applicationPackage, @@ -136,4 +139,96 @@ public class ConvertSchemaCollection { return converter.convertToSchemas(); } + private void resolveStructInheritance() { + List<ParsedStruct> all = new ArrayList(); + for (var schema : orderedInput) { + var doc = schema.getDocument(); + for (var struct : doc.getStructs()) { + for (String inherit : struct.getInherited()) { + var parent = doc.findParsedStruct(inherit); + if (parent == null) { + throw new IllegalArgumentException("Can not find parent for "+struct+" in "+doc); + } + struct.resolveInherit(inherit, parent); + } + all.add(struct); + } + } + List<String> seen = new ArrayList<>(); + for (ParsedStruct struct : all) { + inheritanceCycleCheck(struct, seen); + } + } + + private void resolveAnnotationInheritance() { + List<ParsedAnnotation> all = new ArrayList(); + for (var schema : orderedInput) { + var doc = schema.getDocument(); + for (var annotation : doc.getAnnotations()) { + for (String inherit : annotation.getInherited()) { + var parent = doc.findParsedAnnotation(inherit); + if (parent == null) { + throw new IllegalArgumentException("Can not find parent for "+annotation+" in "+doc); + } + annotation.resolveInherit(inherit, parent); + } + all.add(annotation); + } + } + List<String> seen = new ArrayList<>(); + for (ParsedAnnotation annotation : all) { + inheritanceCycleCheck(annotation, seen); + } + } + + private void fixupAnnotationStruct(ParsedAnnotation parsed) { + for (var parent : parsed.getResolvedInherits()) { + fixupAnnotationStruct(parent); + parent.getStruct().ifPresent(ps -> { + var myStruct = parsed.ensureStruct(); + if (! myStruct.getInherited().contains(ps.name())) { + myStruct.inherit(ps.name()); + myStruct.resolveInherit(ps.name(), ps); + } + }); + } + } + + private void addMissingAnnotationStructs() { + for (var schema : orderedInput) { + var doc = schema.getDocument(); + for (var annotation : doc.getAnnotations()) { + fixupAnnotationStruct(annotation); + } + } + } + + private void inheritanceCycleCheck(ParsedStruct struct, List<String> seen) { + String name = struct.name(); + if (seen.contains(name)) { + seen.add(name); + throw new IllegalArgumentException("Inheritance/reference cycle for structs: " + + String.join(" -> ", seen)); + } + seen.add(name); + for (ParsedStruct parent : struct.getResolvedInherits()) { + inheritanceCycleCheck(parent, seen); + } + seen.remove(name); + } + + private void inheritanceCycleCheck(ParsedAnnotation annotation, List<String> seen) { + String name = annotation.name(); + if (seen.contains(name)) { + seen.add(name); + throw new IllegalArgumentException("Inheritance/reference cycle for annotations: " + + String.join(" -> ", seen)); + } + seen.add(name); + for (ParsedAnnotation parent : annotation.getResolvedInherits()) { + inheritanceCycleCheck(parent, seen); + } + seen.remove(name); + } + } |