in tooling/src/validate.ts [103:232]
private validateEdge(edge: Edge): void {
this.edges.set(edge.id, edge.label);
const descriptor = Edge.getDescriptor(edge);
const valid = descriptor.validate(edge);
const vertices = this.vertices;
let hasInVs: boolean = true;
let sameInVs: boolean = true;
let verticesEmitted: boolean = true;
let inOutCorrect: boolean = true;
let cardinalityCorrect: boolean = true;
let isOpen: boolean = true;
let isClosed: boolean = false;
let freeRanges: Id[] = [];
if (valid) {
const referencedVertices: [VertexLabels | undefined, VertexLabels | undefined][] = [];
if (Edge.is11(edge)) {
referencedVertices.push([vertices.get(edge.outV), vertices.get(edge.inV)]);
} else if (Edge.is1N(edge)) {
const outVertexLabel = vertices.get(edge.outV);
if (edge.inVs.length === 0) {
hasInVs = false;
} else {
const inVertexLabel = vertices.get(edge.inVs[0]);
referencedVertices.push([outVertexLabel, inVertexLabel]);
for (let i = 1; i < edge.inVs.length; i++) {
const label = vertices.get(edge.inVs[i]);
if (inVertexLabel !== label) {
sameInVs = false;
referencedVertices.push([outVertexLabel, label]);
}
}
}
}
for (const item of referencedVertices) {
if (item[0] === undefined || item[1] === undefined) {
verticesEmitted = false;
} else {
const edgeDescriptions = this.getEdgeDescriptions(edge);
const validIns = edgeDescriptions.get(Vertex.getDescriptor(item[0]));
if (validIns === undefined) {
inOutCorrect = false;
} else {
if (!validIns.has(Vertex.getDescriptor(item[1]))) {
inOutCorrect = false;
}
}
}
}
const cardinalityKey: string = JSON.stringify({ k: edge.outV, el: edge.label }, undefined, 0);
let cardinality = this.cardinality.get(cardinalityKey);
if (cardinality === undefined) {
cardinality = 1;
} else {
cardinality++;
}
this.cardinality.set(cardinalityKey, cardinality);
if (descriptor.cardinality === Cardinality.one2one && cardinality !== 1) {
cardinalityCorrect = false;
}
if (edge.label === EdgeLabels.contains) {
const vertexLabel = this.vertices.get(edge.outV);
if (vertexLabel === VertexLabels.document) {
const ranges = this.rangesPreDocument.get(edge.outV);
if (ranges === undefined) {
this.reporter.error(edge, `edge points to a range vertex for which no document ranges can be found`);
}
for (const range of edge.inVs) {
this.associatedRanges.add(range);
const rangeVertex = this.ranges.get(range);
this.ranges.delete(range);
if (rangeVertex === undefined) {
this.reporter.error(edge, `edge points to a range vertex that can't be found.`);
continue;
}
if (ranges !== undefined) {
const key = Range.key(rangeVertex);
if (ranges.has(key)) {
this.reporter.error(edge, `a range with [${JSON.stringify(rangeVertex.start)},${JSON.stringify(rangeVertex.end)}] is emitted twice for the document with Id: ${edge.outV}`);
} else {
ranges.add(key);
}
}
}
}
}
if (edge.label === EdgeLabels.item) {
isOpen = this.openElements.has(edge.shard)!!;
isClosed = this.closedElements.has(edge.shard)!!;
for (const inV of edge.inVs) {
const vertexLabel = this.vertices.get(inV);
if (vertexLabel === VertexLabels.range && !this.associatedRanges.has(inV)) {
freeRanges.push(inV);
}
}
}
}
if (!valid || !sameInVs || !verticesEmitted || !inOutCorrect || !isOpen || !cardinalityCorrect || freeRanges.length > 0) {
this.reporter.error(edge);
if (!valid) {
this.reporter.error(edge, 'edge has invalid property values.');
}
if (!verticesEmitted) {
this.reporter.error(edge, 'references vertices are not emitted yet.');
}
if (!hasInVs) {
this.reporter.error(edge, `inVs property is empty.`);
}
if (!sameInVs) {
this.reporter.error(edge, `vertices referenced via the inVs property are of different types.`);
}
if (!inOutCorrect) {
this.reporter.error(edge, `vertices referenced via the edge are of unsupported type for this edge.`);
}
if (!cardinalityCorrect) {
this.reporter.error(edge, `The cardinality of the edge is 1:1 but the out vertex already has an edge of type ${edge.label}`);
}
if (!isOpen) {
if (isClosed) {
this.reporter.error(edge, `the vertex referenced via the shard property is already closed.`);
} else {
this.reporter.error(edge, `the vertex referenced via the shard property is not open yet.`);
}
}
if (freeRanges.length > 0) {
this.reporter.error(edge, `the ranges [${freeRanges.join(',')}] referenced via the edge are not associated with a document.`);
}
}
}