public Optional<Symbol> findFieldStructDefinition(Symbol fieldDefinition) {
        Optional<Node> dataTypeNode = getFieldDataTypeNode(fieldDefinition);
        if (dataTypeNode.isEmpty()) return Optional.empty();

        if (dataTypeNode.get().hasSymbol()) {
            // TODO: handle non struct?
            if (dataTypeNode.get().getSymbol().getType() != SymbolType.STRUCT) return Optional.empty();

            return schemaIndex.getSymbolDefinition(dataTypeNode.get().getSymbol());
        }

        if (!dataTypeNode.get().isSchemaNode()) return Optional.empty();
        dataType originalNode = (dataType)dataTypeNode.get().getSchemaNode().getOriginalSchemaNode();
        
        if (originalNode.getParsedType().getVariant() == Variant.MAP) {
            return Optional.of(fieldDefinition);
        } else if (originalNode.getParsedType().getVariant() == Variant.ARRAY) {
            if (dataTypeNode.get().size() < 3 || !dataTypeNode.get().get(2).isASTInstance(dataType.class)) return Optional.empty();

            Node innerType = dataTypeNode.get().get(2);

            if (!innerType.hasSymbol() || innerType.getSymbol().getType() != SymbolType.STRUCT) return Optional.empty();

            Symbol structReference = innerType.getSymbol();
            return schemaIndex.getSymbolDefinition(structReference);
        }

        return Optional.empty();
    }
FieldIndex
For storing metadata about fields.
It is owned by a SchemaIndex, so there is a one-to-one correspondence
integration/schema-language-server/language-server/src/main/java/ai/vespa/schemals/index/FieldIndex.java