public static List<Diagnostic> resolveDocumentReferences(ParseContext context) {

        List<Diagnostic> diagnostics = new ArrayList<>();

        SchemaDocument document = context.scheduler().getSchemaDocument(context.fileURI());
        if (document == null) return diagnostics;
        Optional<Symbol> myDocumentDefinition = context.schemaIndex().findSymbol(null, SymbolType.DOCUMENT, document.getSchemaIdentifier());

        if (myDocumentDefinition.isEmpty()) return diagnostics;

        for (SchemaNode documentReferenceNode : context.unresolvedDocumentReferenceNodes()) {
            // If it has not been resolved as a reference, we don't bother
            if (!documentReferenceNode.hasSymbol() || documentReferenceNode.getSymbol().getStatus() != SymbolStatus.REFERENCE) continue;

            Optional<Symbol> referencedDocument = context.schemaIndex().getSymbolDefinition(documentReferenceNode.getSymbol());

            if (referencedDocument.isEmpty()) continue;

            if (!context.schemaIndex().tryRegisterDocumentReference(myDocumentDefinition.get(), referencedDocument.get())) {
                String message = " because cyclic references are not allowed";
                if (myDocumentDefinition.get().equals(referencedDocument.get())) message = " because self-references are not allowed";
                diagnostics.add(new SchemaDiagnostic.Builder()
                        .setRange( documentReferenceNode.getRange())
                        .setMessage( "Cannot reference document " + documentReferenceNode.getText() + message)
                        .setSeverity( DiagnosticSeverity.Error)
                        .build() );
            }
        }

        context.clearUnresolvedDocumentReferenceNodes();
        return diagnostics;
    }
DocumentReferenceResolver
Run after symbol references has been resolved
integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/schemadocument/resolvers/DocumentReferenceResolver.java