private ArrayList<Diagnostic> handleImportField(SchemaNode identifierNode) {
        ArrayList<Diagnostic> ret = new ArrayList<>();

        if (!identifierNode.getPreviousSibling().isASTInstance(FIELD.class)) return ret;

        Node parent = identifierNode.getParent();

        String fieldIdentifier = identifierNode.getText();

        if (!fieldIdentifier.contains(".")) {
            // TODO: parser throws an error here. But we could handle it so it looks better
            return ret;
        }

        if (fieldIdentifier.endsWith(".") || fieldIdentifier.startsWith(".")) {
            ret.add(new SchemaDiagnostic.Builder()
                    .setRange( identifierNode.getRange())
                    .setMessage( "Expected an identifier")
                    .setSeverity( DiagnosticSeverity.Error)
                    .build() );
            return ret;
        }

        String[] subfields = fieldIdentifier.split("[.]");

        int newStart = identifierNode.getRange().getStart().getCharacter();
        int newEnd = newStart + subfields[0].length();
        identifierNode.setNewEndCharacter(newEnd);

        // Set new end for the token inside this node
        if (identifierNode.size() != 0) {
            identifierNode.get(0).getSchemaNode().setNewEndCharacter(newEnd);
        }

        Optional<Symbol> scope = CSTUtils.findScope(identifierNode);

        if (scope.isPresent()) {
            identifierNode.setSymbol(SymbolType.FIELD, context.fileURI(), scope.get());
        } else {
            identifierNode.setSymbol(SymbolType.FIELD, context.fileURI());
        }
        identifierNode.setSymbolStatus(SymbolStatus.UNRESOLVED);


        // Construct a new node which will be a reference to the subfield
        int myIndex = parent.indexOf(identifierNode);

        newStart += subfields[0].length() + 1; // +1 for the dot
        newEnd += subfields[1].length() + 1;

        identifierStr newASTNode = new identifierStr();
        newASTNode.setTokenSource(identifierNode.getTokenSource());
        newASTNode.setBeginOffset(identifierNode.getOriginalSchemaNode().getBeginOffset());
        newASTNode.setEndOffset(identifierNode.getOriginalSchemaNode().getEndOffset());

        SchemaNode newNode = new SchemaNode(newASTNode);
        newNode.setNewStartCharacter(newStart);
        newNode.setNewEndCharacter(newEnd);

        parent.insertChildAfter(myIndex, newNode);

        scope = CSTUtils.findScope(newNode);

        if (scope.isPresent()) {
            newNode.setSymbol(SymbolType.SUBFIELD, context.fileURI(), scope.get());
        } else {
            newNode.setSymbol(SymbolType.SUBFIELD, context.fileURI());
        }

        return ret;
    }
If the parent of an identifier belongs to one of these classes
it will be handled by the {@link IdentifySymbolReferences#handleFieldReference} method.

This involves splitting the identifierStr node into several nodes based on the dot-syntax for fields.
integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/schemadocument/parser/schema/IdentifySymbolReferences.java