diff options
author | Jon Bratseth <bratseth@gmail.com> | 2021-11-10 12:53:31 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2021-11-10 12:53:31 +0100 |
commit | 77a0e3bdc57cb1ea0a9e4c17da55197c95e18947 (patch) | |
tree | a1c8814aa56871d986f1ebdf2ed9a82d7228fd0b /config-model/src/main | |
parent | 4e36629576deded814f9aa59faa05808a37fd2f2 (diff) |
Support struct inheritance
Diffstat (limited to 'config-model/src/main')
5 files changed, 60 insertions, 43 deletions
diff --git a/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java b/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java index 08a0f8b9882..d98869e9dd3 100644 --- a/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java +++ b/config-model/src/main/java/com/yahoo/documentmodel/NewDocumentType.java @@ -368,9 +368,9 @@ public final class NewDocumentType extends StructuredDataType implements DataTyp @Override public String toString() { return name; } - public final String getName() { return name; } + public String getName() { return name; } - public final int getId() { return id; } + public int getId() { return id; } @Override public int hashCode() { return name.hashCode(); } diff --git a/config-model/src/main/java/com/yahoo/documentmodel/VespaDocumentType.java b/config-model/src/main/java/com/yahoo/documentmodel/VespaDocumentType.java index 4899029c4b0..b29e4704f62 100644 --- a/config-model/src/main/java/com/yahoo/documentmodel/VespaDocumentType.java +++ b/config-model/src/main/java/com/yahoo/documentmodel/VespaDocumentType.java @@ -16,7 +16,7 @@ public class VespaDocumentType { public static NewDocumentType INSTANCE = newInstance(); - public static DataTypeName NAME = new DataTypeName("document"); + public static final DataTypeName NAME = new DataTypeName("document"); private static NewDocumentType newInstance() { NewDocumentType vespa = new NewDocumentType(new NewDocumentType.Name(8, "document")); diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/SDDocumentTypeOrderer.java b/config-model/src/main/java/com/yahoo/searchdefinition/SDDocumentTypeOrderer.java index 8a6f16586d2..aa43c00f461 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/SDDocumentTypeOrderer.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/SDDocumentTypeOrderer.java @@ -4,6 +4,7 @@ package com.yahoo.searchdefinition; import com.yahoo.config.application.api.DeployLogger; import com.yahoo.document.*; import com.yahoo.document.annotation.AnnotationReferenceDataType; +import com.yahoo.documentmodel.NewDocumentType; import com.yahoo.searchdefinition.document.SDDocumentType; import com.yahoo.searchdefinition.document.TemporarySDDocumentType; @@ -15,10 +16,10 @@ import java.util.logging.Level; */ public class SDDocumentTypeOrderer { - private Map<DataTypeName, SDDocumentType> createdSDTypes = new LinkedHashMap<>(); - private Set<Integer> seenTypes = new LinkedHashSet<>(); + private final Map<DataTypeName, SDDocumentType> createdSDTypes = new LinkedHashMap<>(); + private final Set<Integer> seenTypes = new LinkedHashSet<>(); List<SDDocumentType> processingOrder = new LinkedList<>(); - private DeployLogger deployLogger; + private final DeployLogger deployLogger; public SDDocumentTypeOrderer(List<SDDocumentType> sdTypes, DeployLogger deployLogger) { this.deployLogger = deployLogger; @@ -36,28 +37,12 @@ public class SDDocumentTypeOrderer { public void process() { for (SDDocumentType type : createdSDTypes.values()) { - process(type); + process(type, type); } } - private void process(SDDocumentType type) { - List<DataTypeName> toReplace = new ArrayList<>(); - for (SDDocumentType sdoc : type.getInheritedTypes()) { - if (sdoc instanceof TemporarySDDocumentType) { - toReplace.add(sdoc.getDocumentName()); - } - } - for (DataTypeName name : toReplace) { - SDDocumentType inherited = createdSDTypes.get(name); - if (inherited == null) { - throw new IllegalStateException("Document type '" + name + "' not found."); - } - process(inherited); - type.inherit(inherited); - } - visit(type); - } - private void visit(SDDocumentType docOrStruct) { + private void process(SDDocumentType docOrStruct, SDDocumentType owningDocument) { + resolveAndProcessInheritedTemporaryTypes(docOrStruct, owningDocument); int id; if (docOrStruct.isStruct()) { id = new StructDataType(docOrStruct.getName()).getId(); @@ -71,16 +56,38 @@ public class SDDocumentTypeOrderer { seenTypes.add((new StructDataType(docOrStruct.getName()).getId())); } - for (Field field : docOrStruct.fieldSet()) { if (!seenTypes.contains(field.getDataType().getId())) { //we haven't seen this before, do it - visit(field.getDataType()); + visit(field.getDataType(), owningDocument); } } processingOrder.add(docOrStruct); } + private void resolveAndProcessInheritedTemporaryTypes(SDDocumentType type, SDDocumentType owningDocument) { + List<DataTypeName> toReplace = new ArrayList<>(); + for (SDDocumentType sdoc : type.getInheritedTypes()) { + if (sdoc instanceof TemporarySDDocumentType) { + toReplace.add(sdoc.getDocumentName()); + } + } + for (DataTypeName name : toReplace) { + SDDocumentType inherited; + if (type.isStruct()) { + inherited = owningDocument.allTypes().get(new NewDocumentType.Name(name.getName())); + if (inherited == null) throw new IllegalStateException("Struct '" + name + "' not found in " + owningDocument); + process(inherited, owningDocument); + } + else { + inherited = createdSDTypes.get(name); + if (inherited == null) throw new IllegalStateException("Document type '" + name + "' not found"); + process(inherited, inherited); + } + type.inherit(inherited); + } + } + private SDDocumentType find(String name) { SDDocumentType sdDocType = createdSDTypes.get(new DataTypeName(name)); if (sdDocType != null) { @@ -95,27 +102,28 @@ public class SDDocumentTypeOrderer { } return null; } - private void visit(DataType type) { + + private void visit(DataType type, SDDocumentType owningDocument) { if (type instanceof StructuredDataType) { StructuredDataType structType = (StructuredDataType) type; SDDocumentType sdDocType = find(structType.getName()); if (sdDocType == null) { - throw new IllegalArgumentException("Could not find struct '" + type.getName() + "'."); + throw new IllegalArgumentException("Could not find struct '" + type.getName() + "'"); } - visit(sdDocType); + process(sdDocType, owningDocument); return; } if (type instanceof MapDataType) { MapDataType mType = (MapDataType) type; - visit(mType.getValueType()); - visit(mType.getKeyType()); + visit(mType.getValueType(), owningDocument); + visit(mType.getKeyType(), owningDocument); } else if (type instanceof WeightedSetDataType) { WeightedSetDataType wType = (WeightedSetDataType) type; - visit(wType.getNestedType()); + visit(wType.getNestedType(), owningDocument); } else if (type instanceof CollectionDataType) { CollectionDataType cType = (CollectionDataType) type; - visit(cType.getNestedType()); + visit(cType.getNestedType(), owningDocument); } else if (type instanceof AnnotationReferenceDataType) { //do nothing } else if (type instanceof PrimitiveDataType) { @@ -128,4 +136,5 @@ public class SDDocumentTypeOrderer { deployLogger.logApplicationPackage(Level.WARNING, "Unknown type : " + type); } } + } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/SDDocumentType.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/SDDocumentType.java index 6424db1c2dd..de9a39ea75d 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/document/SDDocumentType.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/SDDocumentType.java @@ -127,6 +127,14 @@ public class SDDocumentType implements Cloneable, Serializable { return list; } + public Map<NewDocumentType.Name, SDDocumentType> allTypes() { + Map<NewDocumentType.Name, SDDocumentType> map = new LinkedHashMap<>(); + for (SDDocumentType inherited : inheritedTypes.values()) + map.putAll(inherited.allTypes()); + map.putAll(ownedTypes); + return map; + } + /** * Creates a new document type. * The document type id will be generated as a hash from the document type name. @@ -145,10 +153,9 @@ public class SDDocumentType implements Cloneable, Serializable { * Creates a new document type. * The document type id will be generated as a hash from the document type name. * - * @param name The name of the new document type + * @param name the name of the new document type * @param schema check for type ID collisions in this search definition */ - @SuppressWarnings("deprecation") public SDDocumentType(String name, Schema schema) { docType = new DocumentType(name); docType.contentStruct().setCompressionConfig(new CompressionConfig()); @@ -161,7 +168,7 @@ public class SDDocumentType implements Cloneable, Serializable { public SDDocumentType setStruct(DataType structType) { if (structType != null) { this.structType = structType; - inheritedTypes.clear(); + inheritedTypes.remove(VESPA_DOCUMENT.getDocumentName()); } else { if (docType.contentStruct() != null) { this.structType = docType.contentStruct(); @@ -200,7 +207,7 @@ public class SDDocumentType implements Cloneable, Serializable { if (schema.getDocument(getName()) == null) return; SDDocumentType doc = schema.getDocument(); throw new IllegalArgumentException("Failed creating document type '" + getName() + "', " + - "document type '" + doc.getName() + "' already uses ID '" + doc.getName() + "'"); + "document type '" + doc.getName() + "' already uses ID '" + doc.getName() + "'"); } public void setFieldId(SDField field, int id) { @@ -293,6 +300,8 @@ public class SDDocumentType implements Cloneable, Serializable { return fieldSet().iterator(); } + /** Returns the number of fields in this only, not including inherited fields */ + // TODO: Remove public int getFieldCount() { return docType.getFieldCount(); } diff --git a/config-model/src/main/javacc/SDParser.jj b/config-model/src/main/javacc/SDParser.jj index 07171dea803..d2894442ab9 100644 --- a/config-model/src/main/javacc/SDParser.jj +++ b/config-model/src/main/javacc/SDParser.jj @@ -840,14 +840,13 @@ void structOutside(Schema schema) : SDDocumentType structDefinition(Schema schema, SDDocumentType repo) : { String name; + String inherited = null; SDDocumentType struct; } { - <STRUCT> name = identifier() - { - struct = new SDDocumentType(name, schema); - } - lbrace() (structFieldDefinition(struct) (<NL>)*)* <RBRACE> + ( <STRUCT> name = identifier() (<NL>)* { struct = new SDDocumentType(name, schema); } + [ inheritsDocument(struct) (<NL>)* ] + lbrace() (structFieldDefinition(struct) (<NL>)*)* <RBRACE> ) { try { docMan.getDataType(name); |