private static ArrayList<SemanticTokenMarker> traverseCST(SchemaNode node, ClientLogger logger) {
        ArrayList<SemanticTokenMarker> ret = new ArrayList<SemanticTokenMarker>();

        TokenType schemaType = node.getSchemaType();
        var rankExpressionType = node.getRankExpressionType();
        var indexinglanguageType = node.getIndexingLanguageType();

        // TODO: this became a bit ugly with the map stuff
        if (node.isASTInstance(dataType.class) && (!node.hasSymbol() || node.getSymbol().getType() == SymbolType.MAP_KEY || node.getSymbol().getType() == SymbolType.MAP_VALUE)) {

            Integer tokenType = CommonSemanticTokens.getType("type");
            if (tokenType != -1) {
                // this will leave <> uncolored, as we are only interested in marking the actual token
                Range markerRange = node.findFirstLeaf().getRange();
                ret.add(new SemanticTokenMarker(tokenType, markerRange));
            }
            for (Node child : node) {
                ArrayList<SemanticTokenMarker> markers = traverseCST(child.getSchemaNode(), logger);
                ret.addAll(markers);
            }

        } else if (node.isASTInstance(valueType.class)) {

            Integer tokenType = CommonSemanticTokens.getType("type");
            if (tokenType != -1) {
                ret.add(new SemanticTokenMarker(tokenType, node));
            }
        } else if (node.hasSymbol()) {
            ret.addAll(findSemanticMarkersForSymbol(node));
        } else if (schemaType != null) {
            Integer tokenType = null;
            String modifier = null;
            if (isEnumLike(node)) {
                tokenType = CommonSemanticTokens.getType(SemanticTokenTypes.Property); 
                modifier = SemanticTokenModifiers.Readonly;
            }
            if (tokenType == null) {
                tokenType = schemaTokenTypeMap.get(schemaType);
            }

            if (tokenType != null) {
                var marker =new SemanticTokenMarker(tokenType, node);
                if (modifier != null)marker.addModifier(modifier);
                ret.add(marker);
            }

        } else if (rankExpressionType != null) {
            Integer tokenType = rankExpressionTokenTypeMap.get(rankExpressionType);
            if (tokenType != null) {
                ret.add(new SemanticTokenMarker(tokenType, node));
            }

        } else if (indexinglanguageType != null) {
            if (SchemaSemanticTokenConfig.indexingLanguageOutputs.contains(indexinglanguageType)) {
                Integer tokenType = CommonSemanticTokens.getType("type");
                Range markerRange = node.findFirstLeaf().getRange();
                ret.add(new SemanticTokenMarker(tokenType, markerRange));
            } else if (SchemaSemanticTokenConfig.indexingLanguageKeywords.contains(indexinglanguageType)) {
                Integer tokenType = CommonSemanticTokens.getType("keyword");
                Range markerRange = node.findFirstLeaf().getRange();
                ret.add(new SemanticTokenMarker(tokenType, markerRange));
            } else if (SchemaSemanticTokenConfig.indexingLanguageOperators.contains(indexinglanguageType)) {
                Integer tokenType = CommonSemanticTokens.getType("function");
                Range markerRange = node.findFirstLeaf().getRange();
                ret.add(new SemanticTokenMarker(tokenType, markerRange));
            } else if (indexinglanguageType == ai.vespa.schemals.parser.indexinglanguage.Token.TokenType.STRING) {
                Integer tokenType = CommonSemanticTokens.getType("string");
                Range markerRange = node.findFirstLeaf().getRange();
                ret.add(new SemanticTokenMarker(tokenType, markerRange));
            }
        }  else {
            
            for (Node child : node) {
                ArrayList<SemanticTokenMarker> markers = traverseCST(child.getSchemaNode(), logger);
                ret.addAll(markers);
            }
        }


        return ret;
    }
Responsible for LSP textDocument/semanticTokens/full requests.
integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/lsp/schema/semantictokens/SchemaSemanticTokens.java