//:: # Copyright 2013, Big Switch Networks, Inc.
//:: #
//:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
//:: # the following special exception:
//:: #
//:: # LOXI Exception
//:: #
//:: # As a special exception to the terms of the EPL, you may distribute libraries
//:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
//:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
//:: # from the LoxiGen Libraries and the notice provided below is (i) included in
//:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
//:: # documentation for the LoxiGen Libraries, if distributed in binary form.
//:: #
//:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
//:: #
//:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
//:: # a copy of the EPL at:
//:: #
//:: # http::: #www.eclipse.org/legal/epl-v10.html
//:: #
//:: # Unless required by applicable law or agreed to in writing, software
//:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
//:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
//:: # EPL for the specific language governing permissions and limitations
//:: # under the EPL.
//::
//:: from loxi_ir import *
//:: import os
//:: import itertools
//:: import of_g
//:: include('_copyright.java')

//:: include('_autogen.java')

package ${msg.package};

//:: include("_imports.java", msg=msg)

abstract class ${msg.name} {
    // version: ${version}
    final static byte WIRE_VERSION = ${version.int_version};
//:: if msg.is_fixed_length:
    final static int LENGTH = ${msg.length};
//:: else:
    final static int MINIMUM_LENGTH = ${msg.min_length};
//:: #endif


    public final static ${msg.name}.Reader READER = new Reader();

    static class Reader implements OFMessageReader<${msg.interface.inherited_declaration()}> {
        @Override
        public ${msg.interface.inherited_declaration()} readFrom(ChannelBuffer bb) throws OFParseError {
//:: if msg.is_fixed_length:
            if(bb.readableBytes() < LENGTH)
//:: else:
            if(bb.readableBytes() < MINIMUM_LENGTH)
//:: #endif
                return null;
            int start = bb.readerIndex();
//:: fields_with_length_member = {}
//::    for prop in msg.members:
//::       if prop.is_data:
            ${prop.java_type.skip_op(version,
                    length=fields_with_length_member[prop.c_name] if prop.c_name in fields_with_length_member else None)};
//:: elif prop.is_pad:
            // pad: ${prop.length} bytes
            bb.skipBytes(${prop.length});
//:: elif prop.is_fixed_value:
            // fixed value property ${prop.name} == ${prop.value}
            ${prop.java_type.priv_type} ${prop.name} = ${prop.java_type.read_op(version, pub_type=False)};
            if(${prop.name} != ${prop.value})
                throw new OFParseError("Wrong ${prop.name}: Expected=${prop.enum_value}(${prop.value}), got="+${prop.name});
//:: elif prop.is_length_value:
            ${prop.java_type.public_type} ${prop.name} = ${prop.java_type.read_op(version, pub_type=True)};
            if(${prop.name} < MINIMUM_LENGTH)
                throw new OFParseError("Wrong ${prop.name}: Expected to be >= " + MINIMUM_LENGTH + ", was: " + ${prop.name});
//:: elif prop.is_field_length_value:
//::        fields_with_length_member[prop.member.field_name] = prop.name
            int ${prop.name} = ${prop.java_type.read_op(version)};
//:: elif prop.is_discriminator:
            ${prop.java_type.priv_type} ${prop.name} = ${prop.java_type.read_op(version, pub_type=False)};
            bb.readerIndex(start);
            switch(${prop.name}) {
//::     for sub in msg.subclasses:
//::           if not model.generate_class(sub):
               // skip ${sub.name} - excluded from generation
//::           else:
//::           m = sub.get_member(prop.name)
//::           if not m.is_fixed_value:
//::                  raise Exception("subtype %s of %s does not have fixed value for discriminator %s" %
//::                           (sub.name, msg.name, prop.name))
//::           #endif
               case ${m.priv_value}:
                   // discriminator value ${m.enum_value}=${m.value} for class ${sub.name}
                   return ${sub.name}.READER.readFrom(bb);
//:: #endif    # generate_class
//:: #endfor
               default:
                   throw new OFParseError("Unknown value for discriminator ${prop.name} of class ${msg.name}: " + ${prop.name});
            }
//::        break
//:: #endif
//:: #endfor
        }
    }
}
