package com.xqbase.baiji.io.parsing;

import com.xqbase.baiji.exceptions.BaijiTypeException;
import com.xqbase.baiji.schema.Schema;
import com.xqbase.baiji.schema.SchemaType;
import java.util.Map;

/**
 * The class that generates a grammar suitable to parse Baiji data
 * in Binary format.
 *
 * @author Tony He
 */
public class BinaryGrammarGenerator extends ValidatingGrammarGenerator {

    public BinaryGrammarGenerator(Schema schema) {

    }

    /**
     * Resolves the reader schema and returns the start symbol for the grammar generated.
     * If there is already a symbol in the map <tt>seen</tt> for resolving the
     * two schemas, then that symbol is returned. Otherwise a new symbol is
     * generated and returned.
     * @param schema    The schema used by the reader
     * @param seen      The &lt;reader-schema, writer-schema&gt; to symbol
     * map of start symbols of resolving grammars so far.
     * @return          The start symbol for the resolving grammar
     */
    public Symbol generate(Schema schema, Map<LitS, Symbol> seen) {
        final SchemaType type = schema.getType();
        switch (type) {
            case NULL:
                return Symbol.NULL;
            case BOOLEAN:
                return Symbol.BOOLEAN;
            case INT:
                return Symbol.INT;
            case LONG:
                return Symbol.LONG;
            case FLOAT:
                return Symbol.FLOAT;
            case DOUBLE:
                return Symbol.DOUBLE;
            case STRING:
                return Symbol.STRING;
            case BYTES:
                return Symbol.BYTES;
            case DATETIME:
                return Symbol.DATETIME;
            default:
                throw new BaijiTypeException("unknown type: " + type);
        }
    }
}

@@ -86,16 +86,99 @@
 eption;%0A
+import com.xqbase.baiji.schema.Field;%0Aimport com.xqbase.baiji.schema.RecordSchema;%0A
 import c
@@ -250,16 +250,40 @@
 emaType;
+%0A%0Aimport java.util.List;
 %0Aimport 
@@ -1808,97 +1808,1028 @@
     
-default:%0A                throw new BaijiTypeException(%22unknown type: %22 + type);%0A        %7D
+case RECORD:%0A                return resolveRecord((RecordSchema) schema, seen);%0A            default:%0A                throw new BaijiTypeException(%22unknown type: %22 + type);%0A        %7D%0A    %7D%0A%0A    private Symbol resolveRecord(RecordSchema recordSchema, Map%3CLitS, Symbol%3E seen) %7B%0A        LitS wsc = new LitS(recordSchema);%0A        Symbol result = seen.get(wsc);%0A        if (null == result) %7B%0A            List%3CField%3E fields = recordSchema.getFields();%0A            int count = fields.size() + 1;%0A%0A            Symbol%5B%5D production = new Symbol%5Bcount%5D;%0A            production%5B--count%5D = Symbol.fieldOrderAction(fields.toArray(new Field%5Bfields.size()%5D));%0A%0A            /**%0A             * We construct a symbol without filling the array. Please see%0A             * %7B@link Symbol#production%7D for the reason.%0A             */%0A            result = Symbol.seq(production);%0A            seen.put(wsc, result);%0A%0A            for (Field f : fields) %7B%0A                generate(f.getSchema(), seen);%0A            %7D%0A        %7D%0A        return result;
 %0A   

resolve record when construct binary grammar...