# 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.

"""
@file code_gen.py
Code generation functions for LOCI
"""

import sys
import of_g
import c_match
from generic_utils import *
import c_gen.c_type_maps as c_type_maps
import loxi_front_end.type_maps as type_maps
import loxi_front_end.flags as flags
import loxi_utils.loxi_utils as loxi_utils
import loxi_front_end.identifiers as identifiers

# 'property' is for queues. Could be trouble


################################################################
#
# Misc helper functions
#
################################################################

def h_file_to_define(name):
    """
    Convert a .h file name to the define used for the header
    """
    h_name = name[:-2].upper()
    h_name = "_" + h_name + "_H_"
    return h_name

def enum_name(cls):
    """
    Return the name used for an enum identifier for the given class
    @param cls The class name
    """
    return loxi_utils.enum_name(cls)

def member_returns_val(cls, m_name):
    """
    Should get accessor return a value rather than void
    @param cls The class name
    @param m_name The member name
    @return True if of_g config and the specific member allow a 
    return value.  Otherwise False
    """
    m_type = of_g.unified[cls]["union"][m_name]["m_type"]
    return (config_check("get_returns") =="value" and 
            m_type in of_g.of_scalar_types)

# TODO serialize match outside accessor?
def accessor_return_type(a_type, m_type):
    if loxi_utils.accessor_returns_error(a_type, m_type):
        return "int WARN_UNUSED_RESULT"
    else:
        return "void"

def accessor_return_success(a_type, m_type):
    if loxi_utils.accessor_returns_error(a_type, m_type):
        return "OF_ERROR_NONE"
    else:
        return ""

################################################################
#
# Per-file generators, mapped to jump table below
#
################################################################

def base_h_gen(out, name):
    """
    Generate code for base header file
    @param out The file handle to write to
    @param name The name of the file
    """
    common_top_matter(out, name)
    base_h_content(out)
    gen_object_enum(out)
    out.write("""
/****************************************************************
 *
 * Experimenter IDs
 *
 ****************************************************************/

""")
    for name, val in of_g.experimenter_name_to_id.items():
        out.write("#define OF_EXPERIMENTER_ID_%s 0x%08x\n" %
                  (name.upper(), val))

    out.write("""
/****************************************************************
 *
 * OpenFlow Match version specific and generic defines
 *
 ****************************************************************/
""")
    c_match.gen_v4_match_compat(out)
    c_match.gen_match_macros(out)
    c_match.gen_oxm_defines(out)
    out.write("\n#endif /* Base header file */\n")

def identifiers_gen(out, filename):
    """
    Generate the macros for LOCI identifiers
    @param out The file handle to write to
    @param filename The name of the file
    """
    common_top_matter(out, filename)
    out.write("""
/**
 * For each identifier from an OpenFlow header file, a Loxi version
 * of the identifier is generated.  For example, ofp_port_flood becomes
 * OF_PORT_DEST_FLOOD.  Loxi provides the following macros related to 
 * OpenFlow identifiers (using OF_IDENT_ as an example below):
 *     OF_IDENT_BY_VERSION(version) Get the value for the specific version
 *     OF_IDENT_SUPPORTED(version) Boolean: Is OF_IDENT defined for version
 *     OF_IDENT The common value across all versions if defined
 *     OF_IDENT_GENERIC A unique value across all OF identifiers
 *
 * For identifiers marked as flags, the following are also defined
 *     OF_IDENT_SET(flags, version)
 *     OF_IDENT_CLEAR(flags, version)
 *     OF_IDENT_TEST(flags, version)
 *
 * Notes:
 *
 *     OF_IDENT_BY_VERSION(version) returns an undefined value
 * if the passed version does not define OF_IDENT.  It does not generate an
 * error, nor record anything to the log file.  If the value is the same
 * across all defined versions, the version is ignored.
 *
 *     OF_IDENT is only defined if the value is the same across all
 * target LOXI versions FOR WHICH IT IS DEFINED.  No error checking is
 * done.  This allows code to be written without requiring the version
 * to be known or referenced when it doesn't matter.  It does mean
 * that when porting to a new version of OpenFlow, compile errors may
 * occur.  However, this is an indication that the existing code must
 * be updated to account for a change in the semantics with the newly
 * supported OpenFlow version.
 *
 * @fixme Currently we do not handle multi-bit flags or field values; for
 * example, OF_TABLE_CONFIG_TABLE_MISS_CONTROLLER is the meaning for
 * a zero value in the bits indicated by OF_TABLE_CONFIG_TABLE_MISS_MASK.
 *
 * @fixme Need to decide (or make a code gen option) on the requirement
 * for defining OF_IDENT:  Is it that all target versions define it and
 * the agree?  Or only that the versions which define it agree?
 */
""")

    # Build value-by-version parameters and c_code
    if len(of_g.target_version_list) > 1: # Supporting more than one version
        vbv_params = []
        vbv_code = ""
        first = True
        for version in of_g.target_version_list:
            vbv_params.append("value_%s" % of_g.short_version_names[version])
            if not first:
                vbv_code += "\\\n     "
            else:
                first = False
            last_value = "value_%s" % of_g.short_version_names[version]
            vbv_code += "((version) == %s) ? (%s) : " % \
                (of_g.of_version_wire2name[version], last_value)
        # @todo Using last value, can optimize out last ?
        vbv_code += "(%s)" % last_value

    out.write("""
/**
 * @brief True for the special case of all versions supported
 */
#define OF_IDENT_IN_ALL_VERSIONS 1 /* Indicates identifier in all versions */

/**
 * @brief General macro to map version to value where values given as params
 *
 * If unknown version is passed, use the latest version's value
 */
#define OF_VALUE_BY_VERSION(version, %s) \\
    (%s)

/**
 * @brief Generic set a flag
 */
#define OF_FLAG_SET(flags, mask) (flags) = (flags) | (mask)

/**
 * @brief Generic test if a flag is set
 */
#define OF_FLAG_CLEAR(flags, mask) (flags) = (flags) & ~(mask)

/**
 * @brief Generic test if a flag is set
 */
#define OF_FLAG_TEST(flags, mask) ((flags) & (mask) ? 1 : 0)

/**
 * @brief Set a flag where the value is an enum indication of bit shift
 */
#define OF_FLAG_ENUM_SET(flags, e_val) OF_FLAG_SET(flags, 1 << (e_val))

/**
 * @brief Clear a flag where the value is an enum indication of bit shift
 */
#define OF_FLAG_ENUM_CLEAR(flags, e_val) OF_FLAG_CLEAR(flags, 1 << (e_val))

/**
 * @brief Test a flag where the value is an enum indication of bit shift
 */
#define OF_FLAG_ENUM_TEST(flags, e_val) OF_FLAG_TEST(flags, 1 << (e_val))
""" % (", ".join(vbv_params), vbv_code))

    # For each group of identifiers, bunch ident defns
    count = 1
    keys = of_g.identifiers_by_group.keys()
    keys.sort()
    for group in keys:
        idents = of_g.identifiers_by_group[group]
        idents.sort()
        out.write("""
/****************************************************************
 * Identifiers from %s 
 *****************************************************************/
""" % group)
        for ident in idents:
            info = of_g.identifiers[ident]

            keys = info["values_by_version"].keys()
            keys.sort()

            out.write("""
/*
 * Defines for %(ident)s
 * Original name %(ofp_name)s
 */
""" % dict(ident=ident, ofp_name=info["ofp_name"]))

            # Generate supported versions macro
            if len(keys) == len(of_g.target_version_list): # Defined for all
                out.write("""\
#define %(ident)s_SUPPORTED(version) OF_IDENT_IN_ALL_VERSIONS
""" % dict(ident=ident))
            else: # Undefined for some version
                sup_list = []
                for version in keys:
                    sup_list.append("((version) == %s)" %
                                    of_g.of_version_wire2name[version])
                out.write("""\
#define %(ident)s_SUPPORTED(version)      \\
    (%(sup_str)s)
""" % dict(ident=ident, sup_str=" || \\\n     ".join(sup_list)))

            # Generate value macro
            if identifiers.defined_versions_agree(of_g.identifiers,
                                                  of_g.target_version_list,
                                                  ident):
                out.write("""\
#define %(ident)s (%(value)s)
#define %(ident)s_BY_VERSION(version) (%(value)s)
""" % dict(ident=ident,value=info["common_value"]))
            else: # Values differ between versions
                # Generate version check and value by version
                val_list = []
                # Order of params matters
                for version in of_g.target_version_list:
                    if version in info["values_by_version"]:
                        value = info["values_by_version"][version]
                    else:
                        value = identifiers.UNDEFINED_IDENT_VALUE
                    val_list.append("%s" % value)
                out.write("""\
#define %(ident)s_BY_VERSION(version)     \\
    OF_VALUE_BY_VERSION(version, %(val_str)s)
""" % dict(ident=ident, val_str=", ".join(val_list)))
            if flags.ident_is_flag(ident):
                log("Treating %s as a flag" % ident)
                out.write("""
#define %(ident)s_SET(flags, version)     \\
    OF_FLAG_SET(flags, %(ident)s_BY_VERSION(version))
#define %(ident)s_TEST(flags, version)    \\
    OF_FLAG_TEST(flags, %(ident)s_BY_VERSION(version))
#define %(ident)s_CLEAR(flags, version)   \\
    OF_FLAG_CLEAR(flags, %(ident)s_BY_VERSION(version))
""" % dict(ident=ident))

            out.write("#define %(ident)s_GENERIC %(count)d\n"
                      % dict(ident=ident, count=count))
            count += 1 # This count should probably be promoted higher

    log("Generated %d identifiers" % (count - 1))
    out.write("\n#endif /* Loci identifiers header file */\n")

def base_h_external(out, filename):
    """
    Copy contents of external file to base header

    The contents of the filename are copied literally into the
    out file handler.  This allows openflow common defines to
    be entered into the LoxiGen code base.  The content of this
    code must depend only on standard C headers.
    """
    infile = open(filename, "r")
    contents = infile.read()
    out.write(contents)
    infile.close()

def match_h_gen(out, name):
    """
    Generate code for
    @param out The file handle to write to
    @param name The name of the file
    """
    c_match.match_h_top_matter(out, name)
    c_match.gen_incompat_members(out)
    c_match.gen_match_struct(out)
    c_match.gen_match_comp(out)
#    c_match.gen_match_accessors(out)
    out.write("\n#endif /* Match header file */\n")

def top_h_gen(out, name):
    """
    Generate code for
    @param out The file handle to write to
    @param name The name of the file
    """
    external_h_top_matter(out, name)
    out.write("""

typedef enum loci_log_level {
    LOCI_LOG_LEVEL_TRACE,
    LOCI_LOG_LEVEL_VERBOSE,
    LOCI_LOG_LEVEL_INFO,
    LOCI_LOG_LEVEL_WARN,
    LOCI_LOG_LEVEL_ERROR,
    LOCI_LOG_LEVEL_MSG
} loci_log_level_t;

/**
 * @brief Output a log message.
 * @param level The log level.
 * @param fname The function name.
 * @param file The file name.
 * @param line The line number.
 * @param format The message format string.
 */
typedef int (*loci_logger_f)(loci_log_level_t level,
                             const char *fname, const char *file, int line,
                             const char *format, ...);

/*
 * This variable should be set by the user of the library to redirect logs to
 * their log infrastructure. The default drops all logs.
 */
extern loci_logger_f loci_logger;

/**
 * Map a generic object to the underlying wire buffer
 *
 * Treat as private
 */
#define OF_OBJECT_TO_MESSAGE(obj) \\
    ((of_message_t)(WBUF_BUF((obj)->wire_object.wbuf)))

/**
 * Macro for the fixed length part of an object
 *
 * @param obj The object whose extended length is being calculated
 * @returns length in bytes of non-variable part of the object
 */
#define OF_OBJECT_FIXED_LENGTH(obj) \\
    (of_object_fixed_len[(obj)->version][(obj)->object_id])

/**
 * Return the length of the object beyond its fixed length
 *
 * @param obj The object whose extended length is being calculated
 * @returns length in bytes of non-variable part of the object
 *
 * Most variable length fields are alone at the end of a structure.
 * Their length is a simple calculation, just the total length of
 * the parent minus the length of the non-variable part of the
 * parent's class type.
 */

#define OF_OBJECT_VARIABLE_LENGTH(obj) \\
    ((obj)->length - OF_OBJECT_FIXED_LENGTH(obj))

/* FIXME: Where do these go? */
/* Low level maps btwn wire version + type and object ids */
extern int of_message_is_stats_request(int type, int w_ver);
extern int of_message_is_stats_reply(int type, int w_ver);
extern int of_message_stats_reply_to_object_id(int stats_type, int w_ver);
extern int of_message_stats_request_to_object_id(int stats_type, int w_ver);
extern int of_message_type_to_object_id(int type, int w_ver);

extern int of_wire_buffer_of_match_get(of_object_t *obj, int offset,
                                    of_match_t *match);
extern int of_wire_buffer_of_match_set(of_object_t *obj, int offset,
                                    of_match_t *match, int cur_len);
extern void of_extension_object_id_set(of_object_t *obj, of_object_id_t id);
""")

    # gen_base_types(out)

    gen_struct_typedefs(out)
    gen_acc_pointer_typedefs(out)
    gen_new_function_declarations(out)
    if config_check("gen_unified_fns"):
        gen_accessor_declarations(out)

    gen_common_struct_definitions(out)
    gen_flow_add_setup_function_declarations(out)
    if config_check("gen_fn_ptrs"): # Otherwise, all classes are from generic cls
        gen_struct_definitions(out)
    gen_generic_union(out)
    gen_generics(out)
    gen_top_static_functions(out)
    out.write("""
/****************************************************************
 *
 * Declarations of maps between on-the-wire type values and LOCI identifiers
 *
 ****************************************************************/
""")
    c_type_maps.gen_type_maps_header(out)
    c_type_maps.gen_type_data_header(out)
    c_match.gen_declarations(out)
    # @fixme Move debug stuff to own fn
    out.write("""
/**
 * Macro to check consistency of length for top level objects
 *
 * If the object has no parent then its length should match the
 * underlying wire buffer's current bytes.
 */
#define OF_LENGTH_CHECK_ASSERT(obj) \\
    ASSERT(((obj)->parent != NULL) || \\
     ((obj)->wire_object.wbuf == NULL) || \\
     (WBUF_CURRENT_BYTES((obj)->wire_object.wbuf) == (obj)->length))

#define OF_DEBUG_DUMP
#if defined(OF_DEBUG_DUMP)
extern void dump_match(of_match_t *match);
#endif /* OF_DEBUG_DUMP */
""")

    out.write("\n#endif /* Top header file */\n")

def match_c_gen(out, name):
    """
    Generate code for
    @param out The file handle to write to
    @param name The name of the file
    """
    c_match.match_c_top_matter(out, name)
    c_match.gen_match_conversions(out)
    c_match.gen_serialize(out)
    c_match.gen_deserialize(out)

def gen_len_offset_macros(out):
    """
    Special case length and offset calculations put directly into
    loci.c as they are private.
    """

    out.write("""
/****************************************************************
 * Special case macros for calculating variable lengths and offsets
 ****************************************************************/

/**
 * Get a u16 directly from an offset in an object's wire buffer
 * @param obj An of_object_t object
 * @param offset Base offset of the uint16 relative to the object
 *
 */

static inline int
of_object_u16_get(of_object_t *obj, int offset) {
    uint16_t val16;

    of_wire_buffer_u16_get(obj->wire_object.wbuf,
        obj->wire_object.obj_offset + offset, &val16);

    return (int)val16;
}

/**
 * Set a u16 directly at an offset in an object's wire buffer
 * @param obj An of_object_t object
 * @param offset Base offset of the uint16 relative to the object
 * @param val The value to store
 *
 */

static inline void
of_object_u16_set(of_object_t *obj, int offset, int value) {
    uint16_t val16;

    val16 = (uint16_t)value;
    of_wire_buffer_u16_set(obj->wire_object.wbuf,
        obj->wire_object.obj_offset + offset, val16);
}

/**
 * Get length of an object with a TLV header with uint16_t
 * @param obj An object with a match member
 * @param offset The wire offset of the start of the object
 *
 * The length field follows the type field.
 */

#define _TLV16_LEN(obj, offset) \\
    (of_object_u16_get((of_object_t *)(obj), (offset) + 2))

/**
 * Get length of an object that is the "rest" of the object
 * @param obj An object with a match member
 * @param offset The wire offset of the start of the object
 *
 */

#define _END_LEN(obj, offset) ((obj)->length - (offset))

/**
 * Get length of the action list object in a packet_out object
 * @param obj An object of type of_packet_out
 *
 * The length field is just before the end of the fixed length
 * part of the object in all versions.
 */

#define _PACKET_OUT_ACTION_LEN(obj) \\
    (of_object_u16_get((of_object_t *)(obj), \\
     of_object_fixed_len[(obj)->version][OF_PACKET_OUT] - 2))

/**
 * Set length of the action list object in a packet_out object
 * @param obj An object of type of_packet_out
 *
 * The length field is just before the end of the fixed length
 * part of the object in all versions.
 */

#define _PACKET_OUT_ACTION_LEN_SET(obj, len) \\
    (of_object_u16_set((of_object_t *)(obj), \\
     of_object_fixed_len[(obj)->version][OF_PACKET_OUT] - 2, len))

/*
 * Match structs in 1.2 come at the end of the fixed length part
 * of structures.  They add 8 bytes to the minimal length of the
 * message, but are also variable length.  This means that the 
 * type/length offsets are 8 bytes back from the end of the fixed 
 * length part of the object.  The right way to handle this is to 
 * expose the offset of the match member more explicitly.  For now, 
 * we make the calculation as described here.
 */

/* 1.2 min length of match is 8 bytes */
#define _MATCH_MIN_LENGTH_V3 8

/**
 * The offset of a 1.2 match object relative to fixed length of obj
 */
#define _MATCH_OFFSET_V3(fixed_obj_len) \\
    ((fixed_obj_len) - _MATCH_MIN_LENGTH_V3)

/**
 * The "extra" length beyond the minimal 8 bytes of a match struct
 * in an object
 */
#define _MATCH_EXTRA_LENGTH_V3(obj, fixed_obj_len) \\
    (OF_MATCH_BYTES(_TLV16_LEN(obj, _MATCH_OFFSET_V3(fixed_obj_len))) - \\
     _MATCH_MIN_LENGTH_V3)

/**
 * The offset of an object following a match object for 1.2
 */
#define _OFFSET_FOLLOWING_MATCH_V3(obj, fixed_obj_len) \\
    ((fixed_obj_len) + _MATCH_EXTRA_LENGTH_V3(obj, fixed_obj_len))

/**
 * Get length of a match object from its wire representation
 * @param obj An object with a match member
 * @param match_offset The wire offset of the match object.
 *
 * See above; for 1.2, 
 * The match length is raw bytes but the actual space it takes
 * up is padded for alignment to 64-bits
 */
#define _WIRE_MATCH_LEN(obj, match_offset) \\
    (((obj)->version == OF_VERSION_1_0) ? %(match1)d : \\
     (((obj)->version == OF_VERSION_1_1) ? %(match2)d : \\
      _TLV16_LEN(obj, match_offset)))

#define _WIRE_LEN_MIN 4

/*
 * Wrapper function for match len.  There are cases where the wire buffer
 * has not been set with the proper minimum length.  In this case, the
 * wire match len is interpretted as its minimum length, 4 bytes.
 */

static inline int
wire_match_len(of_object_t *obj, int match_offset) {
    int len;

    len = _WIRE_MATCH_LEN(obj, match_offset);

    return (len == 0) ? _WIRE_LEN_MIN : len;
}

#define _WIRE_MATCH_PADDED_LEN(obj, match_offset) \\
    OF_MATCH_BYTES(wire_match_len((of_object_t *)(obj), (match_offset)))

/**
 * Macro to calculate variable offset of instructions member in flow mod
 * @param obj An object of some type of flow modify/add/delete
 *
 * Get length of preceding match object and add to fixed length
 * Applies only to version 1.2
 */

#define _FLOW_MOD_INSTRUCTIONS_OFFSET(obj) \\
    _OFFSET_FOLLOWING_MATCH_V3(obj, %(flow_mod)d)

/* The different flavors of flow mod all use the above */
#define _FLOW_ADD_INSTRUCTIONS_OFFSET(obj) \\
    _FLOW_MOD_INSTRUCTIONS_OFFSET(obj)
#define _FLOW_MODIFY_INSTRUCTIONS_OFFSET(obj) \\
    _FLOW_MOD_INSTRUCTIONS_OFFSET(obj)
#define _FLOW_MODIFY_STRICT_INSTRUCTIONS_OFFSET(obj) \\
    _FLOW_MOD_INSTRUCTIONS_OFFSET(obj)
#define _FLOW_DELETE_INSTRUCTIONS_OFFSET(obj) \\
    _FLOW_MOD_INSTRUCTIONS_OFFSET(obj)
#define _FLOW_DELETE_STRICT_INSTRUCTIONS_OFFSET(obj) \\
    _FLOW_MOD_INSTRUCTIONS_OFFSET(obj)

/**
 * Macro to calculate variable offset of instructions member in flow stats
 * @param obj An object of type of_flow_mod_t
 *
 * Get length of preceding match object and add to fixed length
 * Applies only to version 1.2 and 1.3
 */

#define _FLOW_STATS_ENTRY_INSTRUCTIONS_OFFSET(obj) \\
    _OFFSET_FOLLOWING_MATCH_V3(obj, %(flow_stats)d)

/**
 * Macro to calculate variable offset of data (packet) member in packet_in
 * @param obj An object of type of_packet_in_t
 *
 * Get length of preceding match object and add to fixed length
 * Applies only to version 1.2 and 1.3
 */

#define _PACKET_IN_DATA_OFFSET(obj) \\
    _OFFSET_FOLLOWING_MATCH_V3((obj), (obj)->version == OF_VERSION_1_2 ? \
%(packet_in)d : %(packet_in_1_3)d)

/**
 * Macro to calculate variable offset of data (packet) member in packet_out
 * @param obj An object of type of_packet_out_t
 *
 * Find the length in the actions_len variable and add to the fixed len
 * Applies only to version 1.2 and 1.3
 */

#define _PACKET_OUT_DATA_OFFSET(obj) (_PACKET_OUT_ACTION_LEN(obj) + \\
     of_object_fixed_len[(obj)->version][OF_PACKET_OUT])

/**
 * Macro to map port numbers that changed across versions
 * @param port The port_no_t variable holding the value
 * @param ver The OpenFlow version from which the value was extracted
 */
#define OF_PORT_NO_VALUE_CHECK(port, ver) \\
    if (((ver) == OF_VERSION_1_0) && ((port) > 0xff00)) (port) += 0xffff0000

""" % dict(flow_mod=of_g.base_length[("of_flow_modify",of_g.VERSION_1_2)],
           packet_in=of_g.base_length[("of_packet_in",of_g.VERSION_1_2)],
           packet_in_1_3=of_g.base_length[("of_packet_in",of_g.VERSION_1_3)],
           flow_stats=of_g.base_length[("of_flow_stats_entry",
                                        of_g.VERSION_1_2)],
           match1=of_g.base_length[("of_match_v1",of_g.VERSION_1_0)],
           match2=of_g.base_length[("of_match_v2",of_g.VERSION_1_1)]))

def gen_obj_id_macros(out):
    """
    Flow modify (add, delete) messages (and maybe others) use ID checks allowing
    inheritance to use common accessor functions.
    """
    out.write("""
/**
 * Macro to detect if an object ID falls in the "flow mod" family of objects
 * This includes add, modify, modify_strict, delete and delete_strict
 */
#define IS_FLOW_MOD_SUBTYPE(object_id)                 \\
    (((object_id) == OF_FLOW_MODIFY) ||                \\
     ((object_id) == OF_FLOW_MODIFY_STRICT) ||         \\
     ((object_id) == OF_FLOW_DELETE) ||                \\
     ((object_id) == OF_FLOW_DELETE_STRICT) ||         \\
     ((object_id) == OF_FLOW_ADD))
""")


def top_c_gen(out, name):
    """
    Generate code for
    @param out The file handle to write to
    @param name The name of the file
    """
    common_top_matter(out, name)
    # Generic C code that needs to go into loci.c can go here.
    out.write("""
/****************************************************************
 *
 * This file is divided into the following sections.
 *
 * Instantiate strings such as object names
 * Special case macros for low level object access
 * Per-class, per-member accessor definitions
 * Per-class new/init function definitions
 * Per-class new/init pointer instantiations
 * Instantiate "set map" for pointer set fns
 *
 ****************************************************************/

#if __GNUC__ >= 3
#pragma GCC optimize ("s")
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif

#include <loci/loci.h>
#include <loci/of_object.h>
#include "loci_log.h"

""")
    gen_object_enum_str(out)
    gen_len_offset_macros(out)
    gen_obj_id_macros(out)
    if config_check("gen_unified_fns"):
        gen_accessor_definitions(out)
    gen_new_function_definitions(out)
    gen_init_map(out)
    out.write("\n/* This code should be broken out to a different file */\n")
    gen_setup_from_add_fns(out)

def type_data_c_gen(out, name):
    common_top_matter(out, name)
    c_type_maps.gen_type_maps(out)
    c_type_maps.gen_length_array(out)

################################################################
# Top Matter
################################################################

def common_top_matter(out, name):
    loxi_utils.gen_c_copy_license(out)
    out.write("""\
/****************************************************************
 * File: %s
 *
 * DO NOT EDIT
 *
 * This file is automatically generated
 *
 ****************************************************************/

""" % name)

    if name[-2:] == ".h":
        out.write("""
#if !defined(%(h)s)
#define %(h)s

""" % dict(h=h_file_to_define(name)))

def base_h_content(out):
    """
    Generate base header file content

    @param out The output file object
    """

    # @fixme Supported version should be generated based on input to LoxiGen

    out.write("""
/*
 * Base OpenFlow definitions.  These depend only on standard C headers
 */
#include <string.h>
#include <stdint.h>

/* g++ requires this to pick up PRI, etc.
 * See  http://gcc.gnu.org/ml/gcc-help/2006-10/msg00223.html
 */
#if !defined(__STDC_FORMAT_MACROS)
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>

#include <stdlib.h>
#include <assert.h>
#include <loci/loci_idents.h>

/**
 * Macro to enable debugging for LOCI.
 *
 * This enables debug output to stdout.
 */
#define OF_DEBUG_ENABLE

#if defined(OF_DEBUG_ENABLE)
#include <stdio.h> /* Currently for debugging */
#define FIXME(str) do {                 \\
        fprintf(stderr, "%s\\n", str);  \\
        exit(1);                        \\
    } while (0)
#define debug printf
#else
#define FIXME(str)
#define debug(str, ...)
#endif /* OF_DEBUG_ENABLE */

/**
 * The type of a function used by the LOCI dump/show functions to
 * output text. Essentially the same signature as fprintf. May
 * be called many times per invocation of e.g. of_object_show().
 */
typedef int (*loci_writer_f)(void *cookie, const char *fmt, ...);

/**
 * Check if a version is supported
 */
#define OF_VERSION_OKAY(v) ((v) >= OF_VERSION_1_0 && (v) <= OF_VERSION_1_3)

""")
    gen_version_enum(out)
    out.write("\n")

    # for c_name in of_g.ofp_constants:
    #     val = str(of_g.ofp_constants[c_name])
    #     out.write("#define %s %s\n" % (c_name, val))
    # out.write("\n")

    out.write("""
typedef enum of_error_codes_e {
    OF_ERROR_NONE        = 0,
    OF_ERROR_RESOURCE    = -1,    /* Could not allocate space */
    OF_ERROR_PARAM       = -2,    /* Bad parameter */
    OF_ERROR_VERSION     = -3,    /* Version not supported */
    OF_ERROR_RANGE       = -4,    /* End of list indication */
    OF_ERROR_COMPAT      = -5,    /* Incompatible assignment */
    OF_ERROR_PARSE       = -6,    /* Error in parsing data */
    OF_ERROR_INIT        = -7,    /* Uninitialized data */
    OF_ERROR_UNKNOWN     = -8     /* Unknown error */
} of_error_codes_t;

#define OF_ERROR_STRINGS "none", \\
    "resource", \\
    "parameter", \\
    "version", \\
    "range", \\
    "incompatible", \\
    "parse", \\
    "init", \\
    "unknown"

extern const char *of_error_strings[];

#ifndef NDEBUG
/* #define ASSERT(val) assert(val) */
#define FORCE_FAULT *(volatile int *)0 = 1
#define ASSERT(val) if (!(val)) \\
    fprintf(stderr, "\\nASSERT %s. %s:%d\\n", #val, __FILE__, __LINE__), \\
    FORCE_FAULT
#else
#define ASSERT(val)
#endif

/*
 * Some LOCI object accessors can fail, and it's easy to forget to check.
 * On certain compilers we can trigger a warning if the error code
 * is ignored.
 */
#ifndef DISABLE_WARN_UNUSED_RESULT
#ifdef __GNUC__
#define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
#else
#define WARN_UNUSED_RESULT
#endif
#else
#define WARN_UNUSED_RESULT
#endif

typedef union of_generic_u of_generic_t;
typedef struct of_object_s of_object_t;

/* Define ipv4 address as uint32 */
typedef uint32_t of_ipv4_t;

/* Table ID is the OF standard uint8 */
typedef uint8_t of_table_id_t;

#define OF_MAC_ADDR_BYTES 6
typedef struct of_mac_addr_s {
   uint8_t addr[OF_MAC_ADDR_BYTES];
} of_mac_addr_t;

#define OF_IPV6_BYTES 16
typedef struct of_ipv6_s {
   uint8_t addr[OF_IPV6_BYTES];
} of_ipv6_t;

extern const of_mac_addr_t of_mac_addr_all_ones;
extern const of_mac_addr_t of_mac_addr_all_zeros;

extern const of_ipv6_t of_ipv6_all_ones;
extern const of_ipv6_t of_ipv6_all_zeros;

/**
 * Generic zero and all-ones values of size 16 bytes.
 *
 * IPv6 is longest data type we worry about for comparisons
 */
#define of_all_zero_value of_ipv6_all_zeros
#define of_all_ones_value of_ipv6_all_ones

/**
 * Non-zero/all ones check for arbitrary type of size <= 16 bytes
 */
#define OF_VARIABLE_IS_NON_ZERO(_ptr) \\
    (MEMCMP(&of_all_zero_value, (_ptr), sizeof(*(_ptr))))
#define OF_VARIABLE_IS_ALL_ONES(_ptr) \\
    (!MEMCMP(&of_all_ones_value, (_ptr), sizeof(*(_ptr))))

/* The octets object is a struct holding pointer and length */
typedef struct of_octets_s {
    uint8_t *data;
    int bytes;
} of_octets_t;

/* Macro to convert an octet object to a pointer; currently trivial */
#define OF_OCTETS_POINTER_GET(octet_ptr) ((octet_ptr)->data)
#define OF_OCTETS_POINTER_SET(octet_ptr, ptr) (octet_ptr)->data = (ptr)
#define OF_OCTETS_BYTES_GET(octet_ptr) ((octet_ptr)->bytes)
#define OF_OCTETS_BYTES_SET(octet_ptr, bytes) (octet_ptr)->bytes = (bytes)

/* Currently these are categorized as scalars */
typedef char of_port_name_t[OF_MAX_PORT_NAME_LEN];
typedef char of_table_name_t[OF_MAX_TABLE_NAME_LEN];
typedef char of_desc_str_t[OF_DESC_STR_LEN];
typedef char of_serial_num_t[OF_SERIAL_NUM_LEN];

/* These are types which change across versions.  */
typedef uint32_t of_port_no_t;
typedef uint16_t of_fm_cmd_t;
typedef uint64_t of_wc_bmap_t;
typedef uint64_t of_match_bmap_t;

#define MEMMOVE(dest, src, bytes) memmove(dest, src, bytes)
#define MEMSET(dest, val, bytes) memset(dest, val, bytes)
#define MEMCPY(dest, src, bytes) memcpy(dest, src, bytes)
#define MEMCMP(a, b, bytes) memcmp(a, b, bytes)
#define MALLOC(bytes) malloc(bytes)
#define FREE(ptr) free(ptr)

/** Try an operation and return on failure. */
#define OF_TRY(op) do {                                                      \\
        int _rv;                                                             \\
        if ((_rv = (op)) < 0) {                                              \\
            LOCI_LOG_ERROR("ERROR %d at %s:%d\\n", _rv, __FILE__, __LINE__); \\
            return _rv;                                                      \\
        }                                                                    \\
    } while (0)

/* The extent of an OF match object is determined by its length field, but
 * aligned to 8 bytes
 */

#define OF_MATCH_BYTES(length) (((length) + 7) & 0xfff8)

#if __BYTE_ORDER == __BIG_ENDIAN
#define U16_NTOH(val) (val)
#define U32_NTOH(val) (val)
#define U64_NTOH(val) (val)
#define IPV6_NTOH(dst, src) /* NOTE different syntax; currently no-op */
#define U16_HTON(val) (val)
#define U32_HTON(val) (val)
#define U64_HTON(val) (val)
#define IPV6_HTON(dst, src) /* NOTE different syntax; currently no-op */
#else /* Little Endian */
#define U16_NTOH(val) (((val) >> 8) | ((val) << 8))
#define U32_NTOH(val) ((((val) & 0xff000000) >> 24) |                   \\
                       (((val) & 0x00ff0000) >>  8) |                   \\
                       (((val) & 0x0000ff00) <<  8) |                   \\
                       (((val) & 0x000000ff) << 24))
#define U64_NTOH(val) ((((val) & 0xff00000000000000LL) >> 56) |         \\
                       (((val) & 0x00ff000000000000LL) >> 40) |         \\
                       (((val) & 0x0000ff0000000000LL) >> 24) |         \\
                       (((val) & 0x000000ff00000000LL) >>  8) |         \\
                       (((val) & 0x00000000ff000000LL) <<  8) |         \\
                       (((val) & 0x0000000000ff0000LL) << 24) |         \\
                       (((val) & 0x000000000000ff00LL) << 40) |         \\
                       (((val) & 0x00000000000000ffLL) << 56))
#define IPV6_NTOH(dst, src) /* NOTE different syntax; currently no-op */
#define U16_HTON(val) U16_NTOH(val)
#define U32_HTON(val) U32_NTOH(val)
#define U64_HTON(val) U64_NTOH(val)
#define IPV6_HTON(dst, src) /* NOTE different syntax; currently no-op */
#endif

/****************************************************************
 *
 * The following are internal definitions used by the automatically
 * generated code.  Users should not reference these definitions
 * as they may change between versions of this code
 *
 ****************************************************************/

#define OF_MESSAGE_IN_MATCH_POINTER(obj)                            \\
    (WIRE_BUF_POINTER(&((obj)->wire_buffer), OF_MESSAGE_IN_MATCH_OFFSET))
#define OF_MESSAGE_IN_MATCH_LEN(ptr) BUF_U16_GET(&ptr[2])
#define OF_MESSAGE_IN_DATA_OFFSET(obj) \\
    (FIXED_LEN + OF_MESSAGE_IN_MATCH_LEN(OF_MESSAGE_IN_MATCH_POINTER(obj)) + 2)

#define OF_MESSAGE_OUT_DATA_OFFSET(obj) \\
    (FIXED_LEN + of_message_out_actions_len_get(obj))

""")

def external_h_top_matter(out, name):
    """
    Generate top matter for external header file

    @param name The name of the output file
    @param out The output file object
    """
    common_top_matter(out, name)
    out.write("""
#include <loci/loci_base.h>
#include <loci/of_message.h>
#include <loci/of_match.h>
#include <loci/of_object.h>
#include <loci/of_wire_buf.h>

/****************************************************************
 *
 * This file is divided into the following sections.
 *
 * A few object specific macros
 * Class typedefs (no struct definitions)
 * Per-data type accessor function typedefs
 * Per-class new/delete function typedefs
 * Per-class static delete functions
 * Per-class, per-member accessor declarations
 * Per-class structure definitions
 * Generic union (inheritance) definitions
 * Pointer set function declarations
 * Some special case macros
 *
 ****************************************************************/
""")

def gen_top_static_functions(out):
    out.write("""

#define _MAX_PARENT_ITERATIONS 4
/**
 * Iteratively update parent lengths thru hierarchy
 * @param obj The object whose length is being updated
 * @param delta The difference between the current and new lengths
 *
 * Note that this includes updating the object itself.  It will
 * iterate thru parents.
 *
 * Assumes delta > 0.
 */
static inline void
of_object_parent_length_update(of_object_t *obj, int delta)
{
#ifndef NDEBUG
    int count = 0;
    of_wire_buffer_t *wbuf;  /* For debug asserts only */
#endif

    while (obj != NULL) {
        ASSERT(count++ < _MAX_PARENT_ITERATIONS);
        obj->length += delta;
        if (obj->wire_length_set != NULL) {
            obj->wire_length_set(obj, obj->length);
        }
#ifndef NDEBUG
        wbuf = obj->wire_object.wbuf;
#endif

        /* Asserts for wire length checking */
        ASSERT(obj->length + obj->wire_object.obj_offset <=
               WBUF_CURRENT_BYTES(wbuf));
        if (obj->parent == NULL) {
            ASSERT(obj->length + obj->wire_object.obj_offset ==
                   WBUF_CURRENT_BYTES(wbuf));
        }

        obj = obj->parent;
    }
}
""")

################################################################
#
################################################################

def gen_version_enum(out):
    """
    Generate the enumerated type for versions in LoxiGen
    @param out The file object to which to write the decs

    This just uses the wire versions for now
    """
    out.write("""
/**
 * Enumeration of OpenFlow versions
 *
 * The wire protocol numbers are currently used for values of the corresponding
 * version identifiers.
 */
typedef enum of_version_e {
    OF_VERSION_UNKNOWN = 0,
""")

    is_first = True
    max = 0
    for v in of_g.wire_ver_map:
        if is_first:
            is_first = False
        else:
            out.write(",\n")
        if v > max:
            max = v
        out.write("    %s = %d" % (of_g.wire_ver_map[v], v))

    out.write("""
} of_version_t;

/**
 * @brief Use this when declaring arrays indexed by wire version
 */
#define OF_VERSION_ARRAY_MAX %d
""" % (max + 1))
    
def gen_object_enum(out):
    """
    Generate the enumerated type for object identification in LoxiGen
    @param out The file object to which to write the decs
    """
    out.write("""

/**
 * Enumeration of OpenFlow objects
 *
 * We enumerate the OpenFlow objects used internally.  Note that some
 * message types are determined both by an outer type (message type like
 * stats_request) and an inner type (port stats).  These are different
 * messages in ofC.
 *
 * These values are for internal use only.  They will change with
 * different versions of ofC.
 */

typedef enum of_object_id_e {
    /* Root object type */
    OF_OBJECT_INVALID = -1, /* "invalid" return value for mappings */
    OF_OBJECT = 0, /* Generic, untyped object */

    /* OpenFlow message objects */
""")
    last = 0
    msg_count = 0
    for cls in of_g.ordered_messages:
        out.write("    %s = %d,\n" % (enum_name(cls),
                                   of_g.unified[cls]["object_id"]))
        msg_count = of_g.unified[cls]["object_id"] + 1

    out.write("\n    /* Non-message objects */\n")
    for cls in of_g.ordered_non_messages:
        out.write("    %s = %d,\n" % (enum_name(cls),
                                   of_g.unified[cls]["object_id"]))
        last = of_g.unified[cls]["object_id"]
    out.write("\n    /* List objects */\n")
    for cls in of_g.ordered_list_objects:
        out.write("    %s = %d,\n" % (enum_name(cls),
                                   of_g.unified[cls]["object_id"]))
        last = of_g.unified[cls]["object_id"]

    out.write("\n    /* Generic stats request/reply types; pseudo objects */\n")
    for cls in of_g.ordered_pseudo_objects:
        out.write("    %s = %d,\n" % (enum_name(cls),
                                   of_g.unified[cls]["object_id"]))
        last = of_g.unified[cls]["object_id"]

    out.write("""
    OF_OBJECT_COUNT = %d
} of_object_id_t;

extern const char *of_object_id_str[];

#define OF_MESSAGE_OBJECT_COUNT %d
""" % ((last + 1), msg_count))

    # Generate object type range checking for inheritance classes

    # @fixme These should be determined algorithmicly
    out.write("""
/*
 * Macros to check if an object ID is within an inheritance class range
 */
""")
    # Alphabetical order for 'last'
    last_ids = dict(of_action="OF_ACTION_STRIP_VLAN",
                    of_oxm="OF_OXM_VLAN_VID_MASKED",
                    of_instruction="OF_INSTRUCTION_WRITE_METADATA",
                    of_queue_prop="OF_QUEUE_PROP_MIN_RATE",
                    of_table_feature_prop="OF_TABLE_FEATURE_PROP_WRITE_SETFIELD_MISS",
                    # @FIXME add meter_band ?
                    )
    for cls, last in last_ids.items():
        out.write("""
#define %(enum)s_FIRST_ID      (%(enum)s + 1)
#define %(enum)s_LAST_ID       %(last)s
#define %(enum)s_VALID_ID(id) \\
    ((id) >= %(enum)s_FIRST_ID && \\
     (id) <= %(enum)s_LAST_ID)
""" % dict(enum=enum_name(cls), last=last))
    out.write("""
/**
 * Function to check a wire ID
 * @param object_id The ID to check
 * @param base_object_id The inheritance parent, if applicable
 * @returns boolean: If base_object_id is an inheritance class, check if
 * object_id is valid as a subclass.  Otherwise return 1.
 *
 * Note: Could check that object_id == base_object_id in the
 * second case.
 */
static inline int
of_wire_id_valid(int object_id, int base_object_id) {
    switch (base_object_id) {
    case OF_ACTION:
        return OF_ACTION_VALID_ID(object_id);
    case OF_OXM:
        return OF_OXM_VALID_ID(object_id);
    case OF_QUEUE_PROP:
        return OF_QUEUE_PROP_VALID_ID(object_id);
    case OF_TABLE_FEATURE_PROP:
        return OF_TABLE_FEATURE_PROP_VALID_ID(object_id);
    case OF_INSTRUCTION:
        return OF_INSTRUCTION_VALID_ID(object_id);
    default:
        break;
    }
    return 1;
}
""")

def gen_object_enum_str(out):
    out.write("\nconst char *of_object_id_str[] = {\n")
    out.write("    \"of_object\",\n")
    for cls in of_g.ordered_messages:
        out.write("    \"%s\",\n" % cls)
    out.write("\n    /* Non-message objects */\n")
    for cls in of_g.ordered_non_messages:
        out.write("    \"%s\",\n" % cls)
    out.write("\n    /* List objects */\n")
    for cls in of_g.ordered_list_objects:
        out.write("    \"%s\",\n" % cls)
    out.write("\n    /* Generic stats request/reply types; pseudo objects */\n")
    for cls in of_g.ordered_pseudo_objects:
        out.write("    \"%s\",\n" % cls)
    out.write("\n    \"of_unknown_object\"\n};\n")

    # We'll do version strings while we're at it
    out.write("""
 const char *of_version_str[] = {
    "Unknown OpenFlow Version",
    "OpenFlow-1.0",
    "OpenFlow-1.1",
    "OpenFlow-1.2"
};

const of_mac_addr_t of_mac_addr_all_ones = {
    {
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff
    }
};
/* Just to be explicit; static duration vars are init'd to 0 */
const of_mac_addr_t of_mac_addr_all_zeros = {
    {
        0, 0, 0, 0, 0, 0
    }
};

const of_ipv6_t of_ipv6_all_ones = {
    {
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
    }
};
/* Just to be explicit; static duration vars are init'd to 0 */
const of_ipv6_t of_ipv6_all_zeros = {
    {
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0
    }
};

/** @var of_error_strings
 * The error string map; use abs value to index
 */
const char *of_error_strings[] = { OF_ERROR_STRINGS };
""")

################################################################
#
# Internal Utility Functions
#
################################################################


def acc_name(cls, m_name):
    """
    Generate the root name of an accessor function for typedef
    @param cls The class name
    @param m_name The member name
    """
    (m_type, get_rv) = get_acc_rv(cls, m_name)
    return "%s_%s" % (cls, m_type)

def get_acc_rv(cls, m_name):
    """
    Determine the data type and return type for a get accessor.

    The return type may be "void" or it may be the accessor type
    depending on the system configuration and on the data type.

    @param cls The class name
    @param m_name The member name
    @return A pair (m_type, rv) where m_type is the unified type of the
    member and rv is the get_accessor return type
    """
    member = of_g.unified[cls]["union"][m_name]
    m_type = member["m_type"]
    rv = "int"
    if member_returns_val(cls, m_name):
        rv = m_type
    if m_type[-2:] == "_t":
        m_type = m_type[:-2]

    return (m_type, rv)

def param_list(cls, m_name, a_type):
    """
    Generate the parameter list (no parens) for an a_type accessor
    @param cls The class name
    @param m_name The member name
    @param a_type One of "set" or "get" or TBD
    """
    member = of_g.unified[cls]["union"][m_name]
    m_type = member["m_type"]
    params = ["%s_t *obj" % cls]
    if a_type == "set":
        if loxi_utils.type_is_scalar(m_type):
            params.append("%s %s" % (m_type, m_name))
        else:
            params.append("%s *%s" % (m_type, m_name))
    elif a_type in ["get", "bind"]:
        params.append("%s *%s" % (m_type, m_name))
    else:
        debug("Class %s, name %s Bad param list a_type: %s" %
            (cls, m_name, a_type))
        sys.exit(1)
    return params

def typed_function_base(cls, m_name):
    """
    Generate the core name for accessors based on the type
    @param cls The class name
    @param m_name The member name
    """
    (m_type, get_rv) = get_acc_rv(cls, m_name)
    return "%s_%s" % (cls, m_type)

def member_function_base(cls, m_name):
    """
    Generate the core name for accessors based on the member name
    @param cls The class name
    @param m_name The member name
    """
    return "%s_%s" % (cls, m_name)

def field_ver_get(cls, m_name):
    """
    Generate a dict, indexed by wire version, giving a pair (type, offset)

    @param cls The class name
    @param m_name The name of the class member

    If offset is not known for m_name, the type
    A dict is used for more convenient indexing.
    """
    result = {}

    for ver in of_g.unified[cls]:
        if type(ver) == type(0): # It's a version
            if "use_version" in of_g.unified[cls][ver]: # deref version ref
                ref_ver = of_g.unified[cls][ver]["use_version"]
                members = of_g.unified[cls][ref_ver]["members"]
            else:
                members = of_g.unified[cls][ver]["members"]
            idx = loxi_utils.member_to_index(m_name, members)
            if (idx < 0):
                continue # Member not in this version
            m_type = members[idx]["m_type"]
            offset = members[idx]["offset"]

            # If m_type is mixed, get wire version type from global data
            if m_type in of_g.of_mixed_types and \
                    ver in of_g.of_mixed_types[m_type]:
                m_type = of_g.of_mixed_types[m_type][ver]

            # add version to result list
            result[ver] = (m_type, offset)

    return result

def v3_match_offset_get(cls):
    """
    Return the offset of an OF 1.2 match in an object if it has such; 
    otherwise return -1
    """
    result = field_ver_get(cls, "match")
    if of_g.VERSION_1_2 in result:
        if result[of_g.VERSION_1_2][0] == "of_match_v3_t":
            return result[of_g.VERSION_1_2][1]
    return -1

################################################################
#
# OpenFlow Object Definitions
#
################################################################


def gen_of_object_defs(out):
    """
    Generate low level of_object core operations
    @param out The file for output, already open
    """

def gen_generics(out):
    for (cls, subclasses) in type_maps.inheritance_map.items():
        out.write("""
/**
 * Inheritance super class for %(cls)s
 *
 * This class is the union of %(cls)s classes.  You can refer
 * to it untyped by refering to the member 'header' whose structure
 * is common across all sub-classes.
 */

union %(cls)s_u {
    %(cls)s_header_t header; /* Generic instance */
""" % dict(cls=cls))
        for subcls in sorted(subclasses):
            out.write("    %s_%s_t %s;\n" % (cls, subcls, subcls))
        out.write("};\n")

def gen_struct_typedefs(out):
    """
    Generate typedefs for all struct objects
    @param out The file for output, already open
    """

    out.write("\n/* LOCI inheritance parent typedefs */\n")
    for cls in type_maps.inheritance_map:
        out.write("typedef union %(cls)s_u %(cls)s_t;\n" % dict(cls=cls))
    out.write("\n/* LOCI object typedefs */\n")
    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            continue
        if config_check("gen_fn_ptrs"):
            out.write("typedef struct %(cls)s_s %(cls)s_t;\n" % dict(cls=cls))
        else:
            template = "typedef of_object_t %(cls)s_t;\n"
            out.write(template % dict(cls=cls))

    out.write("""
/****************************************************************
 *
 * Additional of_object defines
 * These are needed for some static inline ops, so we put them here.
 *
 ****************************************************************/

/* Delete an OpenFlow object without reference to its type */
extern void of_object_delete(of_object_t *obj);

""")

def gen_generic_union(out):
    """
    Generate the generic union object composing all LOCI objects

    @param out The file to which to write the decs
    """
    out.write("""
/**
 * The common LOCI object is a union of all possible objects.
 */
union of_generic_u {
    of_object_t object;  /* Common base class with fundamental accessors */

    /* Message objects */
""")
    for cls in of_g.ordered_messages:
        out.write("    %s_t %s;\n" % (cls, cls))
    out.write("\n    /* Non-message composite objects */\n")
    for cls in of_g.ordered_non_messages:
        if cls in type_maps.inheritance_map:
            continue
        out.write("    %s_t %s;\n" % (cls, cls))
    out.write("\n    /* List objects */\n")
    for cls in of_g.ordered_list_objects:
        out.write("    %s_t %s;\n" % (cls, cls))
    out.write("};\n")

def gen_common_struct_definitions(out):
    out.write("""
/****************************************************************
 *
 * Unified structure definitions
 *
 ****************************************************************/

struct of_object_s {
    /* Common members */
%(common)s
};
""" % dict(common=of_g.base_object_members))

def gen_flow_add_setup_function_declarations(out):
    """
    Add the declarations for functions that can be initialized
    by a flow add.  These are defined external to LOXI.
    """

    out.write("""
/****************************************************************
 * Functions for objects that can be initialized by a flow add message.
 * These are defined in a non-autogenerated file
 ****************************************************************/

/**
 * @brief Set up a flow removed message from the original add
 * @param obj The flow removed message being updated
 * @param flow_add The flow_add message to use
 *
 * Initialize the following fields of obj to be identical
 * to what was originally on the wire from the flow_add object:
 *     match
 *     cookie
 *     priority
 *     idle_timeout
 *     hard_timeout
 *
 */

extern int
of_flow_removed_setup_from_flow_add(of_flow_removed_t *obj,
                                    of_flow_add_t *flow_add);


/**
 * @brief Set up the packet in match structure from the original add
 * @param obj The packet in message being updated
 * @param flow_add The flow_add message to use
 * @returns Indigo error code.  Does not return a version error if
 * the version does not require initializing obj.
 *
 * Initialize the match member of obj to be identical to what was originally
 * on the wire from the flow_add object.  If applicable, the table ID is also
 * initialized from the flow_add object.
 *
 * This API applies to 1.2 and later only.
 */

extern int
of_packet_in_setup_from_flow_add(of_packet_in_t *obj,
                                 of_flow_add_t *flow_add);


/**
 * @brief Set up the flow stats entry from the original add
 * @param obj The packet in message being updated
 * @param flow_add The flow_add message to use
 * @param effects Optional actions or instructions; see below.
 *
 * Initialize the following fields of obj to be identical
 * to what was originally on the wire from the flow_add object:
 *     match
 *     actions/instructions (effects)
 *     cookie
 *     priority
 *     idle_timeout
 *     hard_timeout
 *
 * Note that the actions/instructions of a flow may be modified by a 
 * subsequent flow modify message.  To facilitate implementations,
 * the "effects" parameter is provided.  If effects is NULL, the
 * actions/instructions are taken from the flow_add message.
 * Otherwise, effects is coerced to the proper type (actions or
 * instructions) and used to init obj.
 */

extern int
of_flow_stats_entry_setup_from_flow_add(of_flow_stats_entry_t *obj,
                                        of_flow_add_t *flow_add,
                                        of_object_t *effects);
""")

def gen_struct_definitions(out):
    """
    Generate the declaration of all of_ C structures

    @param out The file to which to write the decs
    """

    # This should only get called if gen_fn_ptr is true in code_gen_config
    if not config_check("gen_fn_ptrs"):
        debug("Error: gen_struct_defs called, but no fn ptrs set")
        return

    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            continue # These are generated elsewhere
        note = ""
        if loxi_utils.class_is_message(cls):
            note = " /* Class is message */"
        out.write("struct %s_s {%s\n" % (cls, note))
        out.write("""    /* Common members */
%s
    /* Class specific members */
""" % of_g.base_object_members)
        if loxi_utils.class_is_list(cls):
            out.write("""
    %(cls)s_first_f first;
    %(cls)s_next_f next;
    %(cls)s_append_bind_f append_bind;
    %(cls)s_append_f append;
};

""" % {"cls": cls})
            continue   # All done with list object

        # Else, not a list instance; add accessors for all data members
        for m_name in of_g.ordered_members[cls]:
            if m_name in of_g.skip_members:
                # These members (length, etc) are handled internally
                continue
            f_name = acc_name(cls, m_name)
            out.write("    %s_get_f %s;\n" % (f_name, m_name + "_get"))
            out.write("    %s_set_f %s;\n" % (f_name, m_name + "_set"))
        out.write("};\n\n")


################################################################
#
# List accessor code generation
#
# Currently these all implement copy on read semantics
#
################################################################

def init_call(e_type, obj, ver, length, cw):
    """
    Generate the init call given the strings for params
    """
    hdr = "" # If inheritance type, coerce to hdr object
    obj_name = obj
    if e_type in type_maps.inheritance_map:
        hdr = "_header"
        obj_name = "(%s_header_t *)" % e_type + obj

    return """\
%(e_type)s%(hdr)s_init(%(obj_name)s,
            %(ver)s, %(length)s, %(cw)s)\
""" % dict(e_type=e_type, hdr=hdr, obj_name=obj_name, ver=ver,
           length=length, cw=cw)

def gen_list_first(out, cls, e_type):
    """
    Generate the body of a list_first operation
    @param cls The class name for which code is being generated
    @param e_type The element type of the list
    @param out The file to which to write
    """
    i_call = init_call(e_type, "obj", "list->version", "0", "1")
    if e_type in type_maps.inheritance_map:
        len_str = "obj->header.length"
    else:
        len_str = "obj->length"

    out.write("""
/**
 * Associate an iterator with a list
 * @param list The list to iterate over
 * @param obj The list entry iteration pointer
 * @return OF_ERROR_RANGE if the list is empty (end of list)
 *
 * The obj instance is completely initialized.  The caller is responsible
 * for cleaning up any wire buffers associated with obj before this call
 */

int
%(cls)s_first(%(cls)s_t *list,
    %(e_type)s_t *obj)
{
    int rv;

    %(i_call)s;
    if ((rv = of_list_first((of_object_t *)list, (of_object_t *)obj)) < 0) {
        return rv;
    }
""" % dict(cls=cls, e_type=e_type, i_call=i_call))

    # Special case flow_stats_entry lists

    out.write("""
    of_object_wire_init((of_object_t *) obj, %(u_type)s,
                        list->length);
    if (%(len_str)s == 0) {
        return OF_ERROR_PARSE;
    }

    return rv;
}
""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))


def gen_bind(out, cls, m_name, m_type):
    """
    Generate the body of a bind function
    @param out The file to which to write
    @param cls The class name for which code is being generated
    @param m_name The name of the data member
    @param m_type The type of the data member
    """

    bparams = ",\n    ".join(param_list(cls, m_name, "bind"))

    i_call = init_call(e_type, "child", "parent->version", "0", "1")

    out.write("""
/**
 * Bind the child object to the parent object for read processing
 * @param parent The parent object
 * @param child The child object
 *
 * The child obj instance is completely initialized.
 */

int
%(cls)s_%(m_name)_bind(%(cls)s_t *parent,
    %(e_type)s_t *child)
{
    int rv;

    %(i_call)s;

    /* Derive offset and length of child in parent */
    OF_TRY(of_object_child_attach(parent, child, 
    if ((rv = of_list_first((of_object_t *)list, (of_object_t *)obj)) < 0) {
        return rv;
    }
""" % dict(cls=cls, e_type=e_type, i_call=i_call))

    # Special case flow_stats_entry lists

    out.write("""
    rv = of_object_wire_init((of_object_t *) obj, %(u_type)s,
                               list->length);
    if ((rv == OF_ERROR_NONE) && (%(len_str)s == 0)) {
        return OF_ERROR_PARSE;
    }

    return rv;
}
""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))


def gen_list_next(out, cls, e_type):
    """
    Generate the body of a list_next operation
    @param cls The class name for which code is being generated
    @param e_type The element type of the list
    @param out The file to which to write
    """

    if e_type in type_maps.inheritance_map:
        len_str = "obj->header.length"
    else:
        len_str = "obj->length"
        
    out.write("""
/**
 * Advance an iterator to the next element in a list
 * @param list The list being iterated
 * @param obj The list entry iteration pointer
 * @return OF_ERROR_RANGE if already at the last entry on the list
 *
 */

int
%(cls)s_next(%(cls)s_t *list,
    %(e_type)s_t *obj)
{
    int rv;

    if ((rv = of_list_next((of_object_t *)list, (of_object_t *)obj)) < 0) {
        return rv;
    }

    rv = of_object_wire_init((of_object_t *) obj, %(u_type)s,
        list->length);

    if ((rv == OF_ERROR_NONE) && (%(len_str)s == 0)) {
        return OF_ERROR_PARSE;
    }

    return rv;
}
""" % dict(cls=cls, e_type=e_type, u_type=enum_name(e_type), len_str=len_str))

def gen_list_append(out, cls, e_type):
    """
    Generate the body of a list append functions
    @param cls The class name for which code is being generated
    @param e_type The element type of the list
    @param out The file to which to write
    """

    out.write("""
/**
 * Set up to append an object of type %(e_type)s to an %(cls)s.
 * @param list The list that is prepared for append
 * @param obj Pointer to object to hold data to append
 *
 * The obj instance is completely initialized.  The caller is responsible
 * for cleaning up any wire buffers associated with obj before this call.
 *
 * See the generic documentation for of_list_append_bind.
 */

int
%(cls)s_append_bind(%(cls)s_t *list,
    %(e_type)s_t *obj)
{
    return of_list_append_bind((of_object_t *)list, (of_object_t *)obj);
}

/**
 * Append an item to a %(cls)s list.
 *
 * This copies data from item and leaves item untouched.
 *
 * See the generic documentation for of_list_append.
 */

int
%(cls)s_append(%(cls)s_t *list,
    %(e_type)s_t *item)
{
    return of_list_append((of_object_t *)list, (of_object_t *)item);
}

""" % dict(cls=cls, e_type=e_type))

def gen_list_accessors(out, cls):
    e_type = loxi_utils.list_to_entry_type(cls)
    gen_list_first(out, cls, e_type)
    gen_list_next(out, cls, e_type)
    gen_list_append(out, cls, e_type)

################################################################
#
# Accessor Functions
#
################################################################

    
def gen_accessor_declarations(out):
    """
    Generate the declaration of each version independent accessor

    @param out The file to which to write the decs
    """

    out.write("""
/****************************************************************
 *
 * Unified, per-member accessor function declarations
 *
 ****************************************************************/
""")
    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            continue
        out.write("\n/* Unified accessor functions for %s */\n" % cls)
        for m_name in of_g.ordered_members[cls]:
            if m_name in of_g.skip_members:
                continue
            m_type = loxi_utils.member_base_type(cls, m_name)
            base_name = "%s_%s" % (cls, m_name)
            gparams = ",\n    ".join(param_list(cls, m_name, "get"))
            get_ret_type = accessor_return_type("get", m_type)
            sparams = ",\n    ".join(param_list(cls, m_name, "set"))
            set_ret_type = accessor_return_type("set", m_type)
            bparams = ",\n    ".join(param_list(cls, m_name, "bind"))
            bind_ret_type = accessor_return_type("bind", m_type)

            if loxi_utils.type_is_of_object(m_type):
                # Generate bind accessors, but not get accessor
                out.write("""
extern %(set_ret_type)s %(base_name)s_set(
    %(sparams)s);
extern %(bind_ret_type)s %(base_name)s_bind(
    %(bparams)s);
extern %(m_type)s *%(cls)s_%(m_name)s_get(
    %(cls)s_t *obj);
""" % dict(base_name=base_name, sparams=sparams, bparams=bparams,
           m_name=m_name, m_type=m_type, cls=cls,
           set_ret_type=set_ret_type, bind_ret_type=bind_ret_type))
            else:
                out.write("""
extern %(set_ret_type)s %(base_name)s_set(
    %(sparams)s);
extern %(get_ret_type)s %(base_name)s_get(
    %(gparams)s);
""" % dict(base_name=base_name, gparams=gparams, sparams=sparams,
           get_ret_type=get_ret_type, set_ret_type=set_ret_type))
            
        if loxi_utils.class_is_list(cls):
            e_type = loxi_utils.list_to_entry_type(cls)
            out.write("""
extern int %(cls)s_first(
    %(cls)s_t *list, %(e_type)s_t *obj);
extern int %(cls)s_next(
    %(cls)s_t *list, %(e_type)s_t *obj);
extern int %(cls)s_append_bind(
    %(cls)s_t *list, %(e_type)s_t *obj);
extern int %(cls)s_append(
    %(cls)s_t *list, %(e_type)s_t *obj);

/**
 * Iteration macro for list of type %(cls)s
 * @param list Pointer to the list being iterated over of
 * type %(cls)s
 * @param elt Pointer to an element of type %(e_type)s
 * @param rv On exiting the loop will have the value OF_ERROR_RANGE.
 */
#define %(u_cls)s_ITER(list, elt, rv)  \\
    for ((rv) = %(cls)s_first((list), (elt));   \\
         (rv) == OF_ERROR_NONE;   \\
         (rv) = %(cls)s_next((list), (elt)))
""" % dict(u_cls=cls.upper(), cls=cls, e_type=e_type))


def wire_accessor(m_type, a_type):
    """
    Returns the name of the a_type accessor for low level wire buff offset
    @param m_type The member type
    @param a_type The accessor type (set or get)
    """
    # Strip off _t if present
    if m_type in of_g.of_base_types:
        m_type = of_g.of_base_types[m_type]["short_name"]
    if m_type in of_g.of_mixed_types:
        m_type = of_g.of_mixed_types[m_type]["short_name"]
    if m_type[-2:] == "_t":
        m_type = m_type[:-2]
    if m_type == "octets":
        m_type = "octets_data"
    return "of_wire_buffer_%s_%s" % (m_type, a_type)

def get_len_macro(cls, m_type, version):
    """
    Get the length macro for m_type in cls
    """
    if m_type.find("of_match") == 0:
        return "_WIRE_MATCH_PADDED_LEN(obj, offset)"
    if m_type.find("of_list_oxm") == 0:
        return "wire_match_len(obj, 0) - 4"
    if loxi_utils.class_is_tlv16(m_type):
        return "_TLV16_LEN(obj, offset)"
    if cls == "of_packet_out" and m_type == "of_list_action_t":
        return "_PACKET_OUT_ACTION_LEN(obj)"
    # Default is everything to the end of the object
    return "_END_LEN(obj, offset)"

def gen_accessor_offsets(out, cls, m_name, version, a_type, m_type, offset):
    """
    Generate the sub-object offset and length calculations for accessors
    @param out File being written
    @param m_name Name of member
    @param version Wire version being processed
    @param a_type The accessor type (set or get)
    @param m_type The original member type
    @param offset The offset of the object or -1 if not fixed
    """
    # determine offset
    o_str = "%d" % offset  # Default is fixed length
    if offset == -1:
        # There are currently 4 special cases for this
        # In general, get offset and length of predecessor
        if (loxi_utils.cls_is_flow_mod(cls) and m_name == "instructions"):
            pass
        elif (cls == "of_flow_stats_entry" and m_name == "instructions"):
            pass
        elif (cls == "of_packet_in" and m_name == "data"):
            pass
        elif (cls == "of_packet_out" and m_name == "data"):
            pass
        else:
            debug("Error: Unknown member with offset == -1")
            debug("  cls %s, m_name %s, version %d" % (cls, m_name, version))
            sys.exit(1)
        o_str = "_%s_%s_OFFSET(obj)" % (cls.upper()[3:], m_name.upper())

    out.write("""\
        offset = %s;
""" % o_str);

    # This could be moved to main body but for version check
    if not loxi_utils.type_is_scalar(m_type):
        if loxi_utils.class_is_var_len(m_type[:-2], version) or \
                m_type == "of_match_t":
            len_macro = get_len_macro(cls, m_type, version)
        else:
            len_macro = "%d" % of_g.base_length[(m_type[:-2], version)]
        out.write("        cur_len = %s;\n" % len_macro)
    out.write("        break;\n")

def length_of(m_type, version):
    """
    Return the length of a type based on the version
    """
    if m_type in of_g.of_mixed_types:
        m_type = of_g.of_mixed_types[m_type][version]
    if m_type in of_g.of_base_types:
        return of_g.of_base_types[m_type]["bytes"]
    if (m_type[:-2], version) in of_g.base_length:
        return of_g.base_length[(m_type[:-2], version)]
    print "Unknown length request", m_type, version
    sys.exit(1)
        

def gen_get_accessor_body(out, cls, m_type, m_name):
    """
    Generate the common operations for a get accessor
    """
    if loxi_utils.type_is_scalar(m_type):
        ver = ""      # See if version required for scalar update
        if m_type in of_g.of_mixed_types:
            ver = "ver, "
        out.write("""\
    %(wa)s(%(ver)swbuf, abs_offset, %(m_name)s);
""" % dict(wa=wire_accessor(m_type, "get"), ver=ver, m_name=m_name))

        if m_type == "of_port_no_t":
           out.write("    OF_PORT_NO_VALUE_CHECK(*%s, ver);\n" % m_name)
    elif m_type == "of_octets_t":
        out.write("""\
    ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
    %(m_name)s->bytes = cur_len;
    %(m_name)s->data = OF_WIRE_BUFFER_INDEX(wbuf, abs_offset);
""" % dict(m_name=m_name))
    elif m_type == "of_match_t":
        out.write("""
    ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
    match_octets.bytes = cur_len;
    match_octets.data = OF_OBJECT_BUFFER_INDEX(obj, offset);
    OF_TRY(of_match_deserialize(ver, %(m_name)s, &match_octets));
""" % dict(m_name=m_name))
    else:
        out.write("""
    /* Initialize child */
    %(m_type)s_init(%(m_name)s, obj->version, 0, 1);
    /* Attach to parent */
    %(m_name)s->parent = (of_object_t *)obj;
    %(m_name)s->wire_object.wbuf = obj->wire_object.wbuf;
    %(m_name)s->wire_object.obj_offset = abs_offset;
    %(m_name)s->wire_object.owned = 0;
    %(m_name)s->length = cur_len;
""" % dict(m_type=m_type[:-2], m_name=m_name))


def gen_set_accessor_body(out, cls, m_type, m_name):
    """
    Generate the contents of a set accessor
    """
    if loxi_utils.type_is_scalar(m_type) or m_type == "of_octets_t":
        ver = "" # See if version required for scalar update
        if m_type in of_g.of_mixed_types:
            ver = "ver, "
        cur_len = "" # See if version required for scalar update
        if m_type == "of_octets_t":
            cur_len = ", cur_len"
            out.write("""\
    new_len = %(m_name)s->bytes;
    of_wire_buffer_grow(wbuf, abs_offset + (new_len - cur_len));
""" % dict(m_name=m_name))
        out.write("""\
    %(wa)s(%(ver)swbuf, abs_offset, %(m_name)s%(cur_len)s);
""" % dict(wa=wire_accessor(m_type, "set"), ver=ver, cur_len=cur_len,
           m_name=m_name))

    elif m_type == "of_match_t":
        out.write("""
    /* Match object */
    OF_TRY(of_match_serialize(ver, %(m_name)s, &match_octets));
    new_len = match_octets.bytes;
    of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
        match_octets.data, new_len);
    /* Free match serialized octets */
    FREE(match_octets.data);
""" % dict(m_name=m_name))

    else:  # Other object type
        out.write("\n    /* LOCI object type */")
        # Need to special case OXM list
        out.write("""
    new_len = %(m_name)s->length;
    /* If underlying buffer already shared; nothing to do */
    if (obj->wire_object.wbuf == %(m_name)s->wire_object.wbuf) {
        of_wire_buffer_grow(wbuf, abs_offset + new_len);
        /* Verify that the offsets are correct */
        ASSERT(abs_offset == OF_OBJECT_ABSOLUTE_OFFSET(%(m_name)s, 0));
        /* ASSERT(new_len == cur_len); */ /* fixme: may fail for OXM lists */
        return %(ret_success)s;
    }

    /* Otherwise, replace existing object in data buffer */
    of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
        OF_OBJECT_BUFFER_INDEX(%(m_name)s, 0), new_len);
""" % dict(m_name=m_name, ret_success=accessor_return_success("set", m_type)))

    if not loxi_utils.type_is_scalar(m_type):
        if cls == "of_packet_out" and m_type == "of_list_action_t":
            out.write("""
    /* Special case for setting action lengths */
    _PACKET_OUT_ACTION_LEN_SET(obj, %(m_name)s->length);
""" % dict(m_name=m_name))
        elif m_type not in ["of_match_t", "of_octets_t"]:
            out.write("""
    /* @fixme Shouldn't this precede copying value's data to buffer? */
    if (%(m_name)s->wire_length_set != NULL) {
        %(m_name)s->wire_length_set((of_object_t *)%(m_name)s, %(m_name)s->length);
    }
""" % dict(m_name=m_name))
        out.write("""
    /* Not scalar, update lengths if needed */
    delta = new_len - cur_len;
    if (delta != 0) {
        /* Update parent(s) */
        of_object_parent_length_update((of_object_t *)obj, delta);
    }
""")

def obj_assert_check(cls):
    """
    The body of the assert check for an accessor
    We allow all versions of add/delete/modify to use the same accessors
    """
    if cls in ["of_flow_modify", "of_flow_modify_strict",
               "of_flow_delete", "of_flow_delete_strict",
               "of_flow_add"]:
        return "IS_FLOW_MOD_SUBTYPE(obj->object_id)"
    else:
        return "obj->object_id == %s" % cls.upper()

def gen_of_object_get(out, cls, m_name, m_type):
    sub_cls = m_type[:-2]
    out.write("""
/**
 * Create a copy of %(m_name)s into a new variable of type %(m_type)s from 
 * a %(cls)s instance.
 *
 * @param obj Pointer to the source of type %(cls)s_t
 * @returns A pointer to a new instance of type %(m_type)s whose contents
 * match that of %(m_name)s from source
 * @returns NULL if an error occurs
 */
%(m_type)s *
%(cls)s_%(m_name)s_get(%(cls)s_t *obj) {
    %(m_type)s _%(m_name)s;
    %(m_type)s *_%(m_name)s_ptr;

    %(cls)s_%(m_name)s_bind(obj, &_%(m_name)s);
    _%(m_name)s_ptr = (%(m_type)s *)of_object_dup(&_%(m_name)s);
    return _%(m_name)s_ptr;
}
""" % dict(m_name=m_name, m_type=m_type, cls=cls, sub_cls=sub_cls))

def gen_unified_acc_body(out, cls, m_name, ver_type_map, a_type, m_type):
    """
    Generate the body of a set or get accessor function

    @param out The file to which to write the decs
    @param cls The class name
    @param m_name The member name
    @param ver_type_map Maps (type, offset) pairs to a list of versions
    @param a_type The accessor type, set or get
    @param m_type The original member type

    The type values in ver_type_map are now ignored as we've pushed down
    the type munging to the lower level.

    This is unified because the version switch case processing is the
    same for both set and get
    """
    out.write("""{
    of_wire_buffer_t *wbuf;
    int offset = 0; /* Offset of value relative to the start obj */
    int abs_offset; /* Offset of value relative to start of wbuf */
    of_version_t ver;
""")

    if not loxi_utils.type_is_scalar(m_type):
        out.write("""\
    int cur_len = 0; /* Current length of object data */
""")
        if a_type == "set":
            out.write("""\
    int new_len, delta; /* For set, need new length and delta */
""")

    # For match, need octet string for set/get
    if m_type == "of_match_t":
        out.write("""\
    of_octets_t match_octets; /* Serialized string for match */
""")

    out.write("""
    ASSERT(%(assert_str)s);
    ver = obj->version;
    wbuf = OF_OBJECT_TO_WBUF(obj);
    ASSERT(wbuf != NULL);

    /* By version, determine offset and current length (where needed) */
    switch (ver) {
""" % dict(assert_str=obj_assert_check(cls)))

    for first in sorted(ver_type_map):
        (prev_t, prev_o) = ver_type_map[first]
        prev_len = length_of(prev_t, first)
        prev = first
        out.write("    case %s:\n" % of_g.wire_ver_map[first])
        break

    for next in sorted(ver_type_map):
        if next == first:
            continue

        (t, o) = ver_type_map[next]
        cur_len = length_of(t, next)
        if o == prev_o and cur_len == prev_len:
            out.write("    case %s:\n" % of_g.wire_ver_map[next])
            continue
        gen_accessor_offsets(out, cls, m_name, prev, a_type, m_type, prev_o)
        out.write("    case %s:\n" % of_g.wire_ver_map[next])
        (prev_t, prev_o, prev_len, prev) = (t, o, cur_len, next)

    gen_accessor_offsets(out, cls, m_name, next, a_type, m_type, prev_o)
    out.write("""\
    default:
        ASSERT(0);
    }

    abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, offset);
    ASSERT(abs_offset >= 0);
""")
    if not loxi_utils.type_is_scalar(m_type):
        out.write("    ASSERT(cur_len >= 0 && cur_len < 64 * 1024);\n")

    # Now generate the common accessor code
    if a_type in ["get", "bind"]:
        gen_get_accessor_body(out, cls, m_type, m_name)
    else:
        gen_set_accessor_body(out, cls, m_type, m_name)

    out.write("""
    OF_LENGTH_CHECK_ASSERT(obj);

    return %s;
}
""" % accessor_return_success(a_type, m_type))

def gen_of_obj_bind(out, cls, m_name, m_type, ver_type_map):
    """
    For generating the bind call for OF sub-objects
    """

    params = ",\n    ".join(param_list(cls, m_name, "bind"))
    out.write("""
/**
 * Bind an object of type %(m_type)s to the parent of type %(cls)s for
 * member %(m_name)s
 * @param obj Pointer to an object of type %(cls)s.
 * @param %(m_name)s Pointer to the child object of type
 * %(m_type)s to be filled out.
 * \ingroup %(cls)s
 *
 * The parameter %(m_name)s is filled out to point to the same underlying
 * wire buffer as its parent.
 *
 */
""" % dict(m_name=m_name, cls=cls, m_type=m_type))

    ret_type = accessor_return_type("bind", m_type)
    out.write("%s\n%s_%s_bind(\n    %s)\n" % (ret_type, cls, m_name, params))
    gen_unified_acc_body(out, cls, m_name, ver_type_map, "bind", m_type)

def gen_get_accessor(out, cls, m_name, m_type, ver_type_map):
    """
    For generating the get call for non- OF sub-objects
    """
    params = ",\n    ".join(param_list(cls, m_name, "get"))
    out.write("""
/**
 * Get %(m_name)s from an object of type %(cls)s.
 * @param obj Pointer to an object of type %(cls)s.
 * @param %(m_name)s Pointer to the child object of type
 * %(m_type)s to be filled out.
 *
 */
""" % dict(m_name=m_name, cls=cls, m_type=m_type))

    ret_type =  accessor_return_type("get", m_type)
    out.write("%s\n%s_%s_get(\n    %s)\n" % (ret_type, cls, m_name, params))
    gen_unified_acc_body(out, cls, m_name, ver_type_map, "get", m_type)

def gen_accessor_definitions(out):
    """
    Generate the body of each version independent accessor

    @param out The file to which to write the decs
    """

    out.write("""
/****************************************************************
 *
 * Unified accessor function definitions
 *
 ****************************************************************/
""")
    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            continue
        out.write("\n/* Unified accessor functions for %s */\n" % cls)
        if loxi_utils.class_is_list(cls):
            gen_list_accessors(out, cls)
            continue
        out.write("/** \\ingroup %s \n * @{ */\n" % cls)
        for m_name in of_g.ordered_members[cls]:
            if m_name in of_g.skip_members:
                continue
            m_type = loxi_utils.member_base_type(cls, m_name)
            ver_type_map = field_ver_get(cls, m_name)

            # Generate get/bind pending on member type
            # FIXME:  Does this do the right thing for match?
            if loxi_utils.type_is_of_object(m_type):
                gen_of_obj_bind(out, cls, m_name, m_type, ver_type_map)
                gen_of_object_get(out, cls, m_name, m_type)
            else:
                gen_get_accessor(out, cls, m_name, m_type, ver_type_map)

            # Now generate set accessor for all objects
            params = ",\n    ".join(param_list(cls, m_name, "set"))
            out.write("""
/**
 * Set %(m_name)s in an object of type %(cls)s.
 * @param obj Pointer to an object of type %(cls)s.
""" % dict(m_name=m_name, cls=cls, m_type=m_type))
            if loxi_utils.type_is_scalar(m_type) or m_type == "of_octets_t":
                out.write("""\
 * @param %(m_name)s The value to write into the object
 */
""" % dict(m_name=m_name, cls=cls, m_type=m_type))
            else:
                out.write("""\
 * @param %(m_name)s Pointer to the child of type %(m_type)s.
 *
 * If the child's wire buffer is the same as the parent's, then
 * nothing is done as the changes have already been registered in the
 * parent.  Otherwise, the data in the child's wire buffer is inserted
 * into the parent's and the appropriate lengths are updated.
 */
""" % dict(m_name=m_name, cls=cls, m_type=m_type))
            ret_type = accessor_return_type("set", m_type)
            out.write("%s\n%s_%s_set(\n    %s)\n" % (ret_type, cls, m_name, params))
            gen_unified_acc_body(out, cls, m_name, ver_type_map, "set", m_type)

        out.write("\n/** @} */\n")

def gen_acc_pointer_typedefs(out):
    """
    Generate the function pointer typedefs for in-struct accessors
    @param out The file to which to write the typedefs
    """

    out.write("""
/****************************************************************
 *
 * Accessor function pointer typedefs
 *
 ****************************************************************/

/*
 * Generic accessors:
 *
 * Many objects have a length represented in the wire buffer
 * wire_length_get and wire_length_set access these values directly on the
 * wire.
 *
 * Many objects have a length represented in the wire buffer
 * wire_length_get and wire_length_set access these values directly on the
 * wire.
 *
 * FIXME: TBD if wire_length_set and wire_type_set are required.
 */
typedef void (*of_wire_length_get_f)(of_object_t *obj, int *bytes);
typedef void (*of_wire_length_set_f)(of_object_t *obj, int bytes);
typedef void (*of_wire_type_get_f)(of_object_t *obj, of_object_id_t *id);
typedef void (*of_wire_type_set_f)(of_object_t *obj, of_object_id_t id);
""")
    # If not using function pointers in classes, don't gen typedefs below
    if not config_check("gen_fn_ptrs"):
        return

    # For each class, for each type it uses, generate a typedef
    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            continue
        out.write("\n/* Accessor function pointer typedefs for %s */\n" % cls)
        types_done = list()
        for m_name in of_g.ordered_members[cls]:
            (m_type, get_rv) = get_acc_rv(cls, m_name)
            if (m_type, get_rv) in types_done:
                continue
            types_done.append((m_type, get_rv))
            fn = "%s_%s" % (cls, m_type)
            params = ", ".join(param_list(cls, m_name, "get"))
            out.write("typedef int (*%s_get_f)(\n    %s);\n" %
                      (fn, params))

            params = ", ".join(param_list(cls, m_name, "set"))
            out.write("typedef int (*%s_set_f)(\n    %s);\n" %
                      (fn, params))
        if loxi_utils.class_is_list(cls):
            obj_type = loxi_utils.list_to_entry_type(cls)
            out.write("""typedef int (*%(cls)s_first_f)(
    %(cls)s_t *list,
    %(obj_type)s_t *obj);
typedef int (*%(cls)s_next_f)(
    %(cls)s_t *list,
    %(obj_type)s_t *obj);
typedef int (*%(cls)s_append_bind_f)(
    %(cls)s_t *list,
    %(obj_type)s_t *obj);
typedef int (*%(cls)s_append_f)(
    %(cls)s_t *list,
    %(obj_type)s_t *obj);
""" % {"cls":cls, "obj_type":obj_type})

#             out.write("""
# typedef int (*%(cls)s_get_f)(
#     %(cls)s_t *list,
#     %(obj_type)s_t *obj, int index);
# typedef int (*%(cls)s_set_f)(
#     %(cls)s_t *list,
#     %(obj_type)s_t *obj, int index);
# typedef int (*%(cls)s_append_f)(
#     %(cls)s_t *list,
#     %(obj_type)s_t *obj, int index);
# typedef int (*%(cls)s_insert_f)(
#     %(cls)s_t *list,
#     %(obj_type)s_t *obj, int index);
# typedef int (*%(cls)s_remove_f)(
#     %(cls)s_t *list,
#     int index);
# """ % {"cls":cls, "obj_type":obj_type})

################################################################
#
# New/Delete Function Definitions
#
################################################################


################################################################
# First, some utility functions for new/delete
################################################################

def del_function_proto(cls):
    """
    Return the prototype for the delete operator for the given class
    @param cls The class name
    """
    fn = "void\n"
    return fn


def instantiate_fn_ptrs(cls, ilvl, out):
    """
    Generate the C code to instantiate function pointers for a class
    @param cls The class name
    @param ilvl The base indentation level
    @param out The file to which to write the functions
    """
    for m_name in of_g.ordered_members[cls]:
        if m_name in of_g.skip_members:
            continue
        out.write(" " * ilvl + "obj->%s_get = %s_%s_get;\n" %
                  (m_name, cls, m_name))
        out.write(" " * ilvl + "obj->%s_set = %s_%s_set;\n" %
                  (m_name, cls, m_name))

################################################################
# Routines to generate the body of new/delete functions
################################################################

def gen_init_fn_body(cls, out):
    """
    Generate function body for init function
    @param cls The class name for the function
    @param out The file to which to write
    """
    if cls in type_maps.inheritance_map:
        param = "obj_p"
    else:
        param = "obj"

    out.write("""
/**
 * Initialize an object of type %(cls)s.
 *
 * @param obj Pointer to the object to initialize
 * @param version The wire version to use for the object
 * @param bytes How many bytes in the object
 * @param clean_wire Boolean: If true, clear the wire object control struct
 *
 * If bytes < 0, then the default fixed length is used for the object
 *
 * This is a "coerce" function that sets up the pointers for the
 * accessors properly.  
 *
 * If anything other than 0 is passed in for the buffer size, the underlying
 * wire buffer will have 'grow' called.
 */

void
%(cls)s_init(%(cls)s_t *%(param)s,
    of_version_t version, int bytes, int clean_wire)
{
""" % dict(cls=cls, param=param))

    # Use an extra pointer to deal with inheritance classes
    if cls in type_maps.inheritance_map:
        out.write("""\
    %s_header_t *obj;

    obj = &obj_p->header;  /* Need instantiable subclass */
""" % cls)

    out.write("""
    ASSERT(of_object_fixed_len[version][%(enum)s] >= 0);
    if (clean_wire) {
        MEMSET(obj, 0, sizeof(*obj));
    }
    if (bytes < 0) {
        bytes = of_object_fixed_len[version][%(enum)s];
    }
    obj->version = version;
    obj->length = bytes;
    obj->object_id = %(enum)s;
""" % dict(cls=cls, enum=enum_name(cls)))
    gen_coerce_ops(out, cls)

    out.write("""
    /* Grow the wire buffer */
    if (obj->wire_object.wbuf != NULL) {
        int tot_bytes;

        tot_bytes = bytes + obj->wire_object.obj_offset;
        of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes);
    }
}

""")

## @fixme This should also be updated once there is a map from
# class instance to wire length/type accessors
def gen_wire_push_fn(cls, out):
    """
    Generate the calls to push values into the wire buffer
    """
    if type_maps.class_is_virtual(cls):
        print "Push fn gen called for virtual class " + cls
        return

    out.write("""
/**
 * Helper function to push values into the wire buffer
 */
static inline int
%(cls)s_push_wire_values(%(cls)s_t *obj)
{
""" % dict(cls=cls))

    if loxi_utils.class_is_message(cls):
        out.write("""
    /* Message obj; push version, length and type to wire */
    of_message_t msg;

    if ((msg = OF_OBJECT_TO_MESSAGE(obj)) != NULL) {
        of_message_version_set(msg, obj->version);
        of_message_length_set(msg, obj->length);
        OF_TRY(of_wire_message_object_id_set(OF_OBJECT_TO_WBUF(obj),
                 %(name)s));
    }
""" % dict(name = enum_name(cls)))
 
        for version in of_g.of_version_range:
            if type_maps.class_is_extension(cls, version):
                exp_name = type_maps.extension_to_experimenter_macro_name(cls)
                subtype = type_maps.extension_message_to_subtype(cls, version)
                if subtype is None or exp_name is None:
                    print "Error in mapping extension message"
                    print cls, version
                    sys.exit(1)
                out.write("""
    if (obj->version == %(version)s) {
        of_message_experimenter_id_set(OF_OBJECT_TO_MESSAGE(obj),
                                       %(exp_name)s);
        of_message_experimenter_subtype_set(OF_OBJECT_TO_MESSAGE(obj),
                                            %(subtype)s);
    }
""" % dict(exp_name=exp_name, version=of_g.wire_ver_map[version],
           subtype=str(subtype)))
           
    else: # Not a message
        if loxi_utils.class_is_tlv16(cls):
            out.write("""
    /* TLV obj; set length and type */
    of_tlv16_wire_length_set((of_object_t *)obj, obj->length);
    of_tlv16_wire_object_id_set((of_object_t *)obj,
           %(enum)s);
""" % dict(enum=enum_name(cls)))
            # Some tlv16 types may be extensions requiring more work
            if cls in ["of_action_bsn_mirror", "of_action_id_bsn_mirror",
                       "of_action_bsn_set_tunnel_dst", "of_action_id_bsn_set_tunnel_dst",
                       "of_action_nicira_dec_ttl", "of_action_id_nicira_dec_ttl"]:
                out.write("""
    /* Extended TLV obj; Call specific accessor */
    of_extension_object_id_set(obj, %(enum)s);
""" % dict(cls=cls, enum=enum_name(cls)))
                

        if loxi_utils.class_is_oxm(cls):
            out.write("""\
    /* OXM obj; set length and type */
    of_oxm_wire_length_set((of_object_t *)obj, obj->length);
    of_oxm_wire_object_id_set((of_object_t *)obj, %(enum)s);
""" % dict(enum=enum_name(cls)))
        if loxi_utils.class_is_u16_len(cls) or cls == "of_packet_queue":
            out.write("""
    obj->wire_length_set((of_object_t *)obj, obj->length);
""")

        if cls == "of_meter_stats":
            out.write("""
    of_meter_stats_wire_length_set((of_object_t *)obj, obj->length);
""" % dict(enum=enum_name(cls)))

    out.write("""
    return OF_ERROR_NONE;
}
""")

def gen_new_fn_body(cls, out):
    """
    Generate function body for new function
    @param cls The class name for the function
    @param out The file to which to write
    """

    out.write("""
/**
 * \\defgroup %(cls)s %(cls)s
 */
""" % dict(cls=cls))

    if not type_maps.class_is_virtual(cls):
        gen_wire_push_fn(cls, out)

    out.write("""
/**
 * Create a new %(cls)s object
 *
 * @param version The wire version to use for the object
 * @return Pointer to the newly create object or NULL on error
 *
 * Initializes the new object with it's default fixed length associating
 * a new underlying wire buffer.
 *
 * Use new_from_message to bind an existing message to a message object,
 * or a _get function for non-message objects.
 *
 * \\ingroup %(cls)s
 */

%(cls)s_t *
%(cls)s_new_(of_version_t version)
{
    %(cls)s_t *obj;
    int bytes;

    bytes = of_object_fixed_len[version][%(enum)s];

    /* Allocate a maximum-length wire buffer assuming we'll be appending to it. */
    if ((obj = (%(cls)s_t *)of_object_new(OF_WIRE_BUFFER_MAX_LENGTH)) == NULL) {
        return NULL;
    }

    %(cls)s_init(obj, version, bytes, 0);
""" % dict(cls=cls, enum=enum_name(cls)))
    if not type_maps.class_is_virtual(cls):
        out.write("""
    if (%(cls)s_push_wire_values(obj) < 0) {
        FREE(obj);
        return NULL;
    }
""" % dict(cls=cls))

    match_offset = v3_match_offset_get(cls)
    if match_offset >= 0:
        # Init length field for match object
        out.write("""
    /* Initialize match TLV for 1.2 */
    /* FIXME: Check 1.3 below */
    if ((version == OF_VERSION_1_2) || (version == OF_VERSION_1_3)) {
        of_object_u16_set((of_object_t *)obj, %(match_offset)d + 2, 4);
    }
""" % dict(match_offset=match_offset))
    out.write("""
    return obj;
}

#if defined(OF_OBJECT_TRACKING)

/*
 * Tracking objects.  Call the new function and then record location
 */

%(cls)s_t *
%(cls)s_new_tracking(of_version_t version,
     const char *file, int line)
{
    %(cls)s_t *obj;

    obj = %(cls)s_new_(version);
    of_object_track((of_object_t *)obj, file, line);

    return obj;
}
#endif
""" % dict(cls=cls))


def gen_from_message_fn_body(cls, out):
    """
    Generate function body for from_message function
    @param cls The class name for the function
    @param out The file to which to write
    """
    out.write("""
/**
 * Create a new %(cls)s object and bind it to an existing message
 *
 * @param msg The message to bind the new object to
 * @return Pointer to the newly create object or NULL on error
 *
 * \ingroup %(cls)s
 */

%(cls)s_t *
%(cls)s_new_from_message_(of_message_t msg)
{
    %(cls)s_t *obj = NULL;
    of_version_t version;
    int length;

    if (msg == NULL) return NULL;

    version = of_message_version_get(msg);
    if (!OF_VERSION_OKAY(version)) return NULL;

    length = of_message_length_get(msg);

    if ((obj = (%(cls)s_t *)of_object_new(-1)) == NULL) {
        return NULL;
    }

    %(cls)s_init(obj, version, 0, 0);

    if ((of_object_buffer_bind((of_object_t *)obj, OF_MESSAGE_TO_BUFFER(msg),
                               length, OF_MESSAGE_FREE_FUNCTION)) < 0) {
       FREE(obj);
       return NULL;
    }
    obj->length = length;
    obj->version = version;

    return obj;
}

#if defined(OF_OBJECT_TRACKING)

/*
 * Tracking objects.  Call the new function and then record location
 */

%(cls)s_t *
%(cls)s_new_from_message_tracking(of_message_t msg,
    const char *file, int line)
{
    %(cls)s_t *obj;

    obj = %(cls)s_new_from_message_(msg);
    of_object_track((of_object_t *)obj, file, line);

    return obj;
}
#endif
""" % dict(cls=cls))


################################################################
# Now the top level generator functions
################################################################

def gen_new_function_declarations(out):
    """
    Gerenate the header file declarations for new operators for all classes
    @param out The file to which to write the decs
    """

    out.write("""
/****************************************************************
 *
 * New operator declarations
 *
 * _new: Create a new object for writing; includes init
 * _new_from_message: Create a new instance of the object and bind the
 *    message data to the object
 * _init: Initialize and optionally allocate buffer space for an
 *    automatic instance
 *
 * _new and _from_message require a delete operation to be called
 * on the object.
 *
 ****************************************************************/
""")
    out.write("""
/*
 * If object tracking is enabled, map "new" and "new from msg"
 * calls to tracking versions; otherwise, directly to internal
 * versions of fns which have the same name but end in _.
 */

#if defined(OF_OBJECT_TRACKING)
""")
    for cls in of_g.standard_class_order:
        out.write("""
extern %(cls)s_t *
    %(cls)s_new_tracking(of_version_t version,
        const char *file, int line);
#define %(cls)s_new(version) \\
    %(cls)s_new_tracking(version, \\
        __FILE__, __LINE__)
""" % dict(cls=cls))
        if loxi_utils.class_is_message(cls):
            out.write("""extern %(cls)s_t *
    %(cls)s_new_from_message_tracking(of_message_t msg,
        const char *file, int line);
#define %(cls)s_new_from_message(msg) \\
    %(cls)s_new_from_message_tracking(msg, \\
        __FILE__, __LINE__)
""" % dict(cls=cls))

    out.write("""
#else /* No object tracking */
""")
    for cls in of_g.standard_class_order:
        out.write("""
#define %(cls)s_new(version) \\
    %(cls)s_new_(version)
""" % dict(cls=cls))
        if loxi_utils.class_is_message(cls):
            out.write("""#define %(cls)s_new_from_message(msg) \\
    %(cls)s_new_from_message_(msg)
""" % dict(cls=cls))

    out.write("""
#endif /* Object tracking */
""")

    for cls in of_g.standard_class_order:
        out.write("""
extern %(cls)s_t *
    %(cls)s_new_(of_version_t version);
""" % dict(cls=cls))
        if loxi_utils.class_is_message(cls):
            out.write("""extern %(cls)s_t *
    %(cls)s_new_from_message_(of_message_t msg);
""" % dict(cls=cls))
        out.write("""extern void %(cls)s_init(
    %(cls)s_t *obj, of_version_t version, int bytes, int clean_wire);
""" % dict(cls=cls))

    out.write("""
/****************************************************************
 *
 * Delete operator static inline definitions.
 * These are here for type checking purposes only
 *
 ****************************************************************/
""")
    for cls in of_g.standard_class_order:
#        if cls in type_maps.inheritance_map:
#            continue
        out.write("""
/**
 * Delete an object of type %(cls)s_t
 * @param obj An instance of type %(cls)s_t
 *
 * \ingroup %(cls)s
 */
static inline void
%(cls)s_delete(%(cls)s_t *obj) {
    of_object_delete((of_object_t *)(obj));
}
""" % dict(cls=cls))

    out.write("""
typedef void (*of_object_init_f)(of_object_t *obj, of_version_t version,
    int bytes, int clean_wire);
extern of_object_init_f of_object_init_map[];
""")

    out.write("""
/****************************************************************
 *
 * Function pointer initialization functions
 * These are part of the "coerce" type casting for objects
 *
 ****************************************************************/
""")

#
# @fixme Not clear that these should all be set for virtual fns
#
# @fixme Clean up.  should have a (language specific) map from class
# to length and type get/set functions
#

def gen_coerce_ops(out, cls):
    out.write("""
    /* Set up the object's function pointers */
""")

    if loxi_utils.class_is_message(cls):
        out.write("""
    obj->wire_length_get = of_object_message_wire_length_get;
    obj->wire_length_set = of_object_message_wire_length_set;
""")
    else:
        if loxi_utils.class_is_tlv16(cls):
            if not (cls in type_maps.inheritance_map): # Don't set for super
                out.write("""
    obj->wire_length_set = of_tlv16_wire_length_set;
    obj->wire_type_set = of_tlv16_wire_object_id_set;\
""")
            out.write("""
    obj->wire_length_get = of_tlv16_wire_length_get;
""")
            if loxi_utils.class_is_action(cls):
                out.write("""
    obj->wire_type_get = of_action_wire_object_id_get;
""")
            if loxi_utils.class_is_action_id(cls):
                out.write("""
    obj->wire_type_get = of_action_id_wire_object_id_get;
""")
            if loxi_utils.class_is_instruction(cls):
                out.write("""
    obj->wire_type_get = of_instruction_wire_object_id_get;
""")
            if loxi_utils.class_is_queue_prop(cls):
                    out.write("""
    obj->wire_type_get = of_queue_prop_wire_object_id_get;
""")
            if loxi_utils.class_is_table_feature_prop(cls):
                    out.write("""
    obj->wire_type_get = of_table_feature_prop_wire_object_id_get;
""")
            if loxi_utils.class_is_meter_band(cls):
                    out.write("""
    obj->wire_type_get = of_meter_band_wire_object_id_get;
""")
            if loxi_utils.class_is_hello_elem(cls):
                    out.write("""
    obj->wire_type_get = of_hello_elem_wire_object_id_get;
""")
        if loxi_utils.class_is_oxm(cls):
            out.write("""
    obj->wire_length_get = of_oxm_wire_length_get;
    obj->wire_length_set = of_oxm_wire_length_set;
    obj->wire_type_get = of_oxm_wire_object_id_get;
    obj->wire_type_set = of_oxm_wire_object_id_set;
""")
        if loxi_utils.class_is_u16_len(cls):
            out.write("""
    obj->wire_length_get = of_u16_len_wire_length_get;
    obj->wire_length_set = of_u16_len_wire_length_set;
""")
        if cls == "of_packet_queue":
            out.write("""
    obj->wire_length_get = of_packet_queue_wire_length_get;
    obj->wire_length_set = of_packet_queue_wire_length_set;
""")
#        if cls == "of_list_meter_band_stats":
#            out.write("""
#    obj->wire_length_get = of_list_meter_band_stats_wire_length_get;
#""")
        if cls == "of_meter_stats":
            out.write("""
    obj->wire_length_get = of_meter_stats_wire_length_get;
    obj->wire_length_set = of_meter_stats_wire_length_set;
""")

    if config_check("gen_fn_ptrs"):
        if loxi_utils.class_is_list(cls):
            out.write("""
    obj->first = %(cls)s_first;
    obj->next = %(cls)s_next;
    obj->append = %(cls)s_append;
    obj->append_bind = %(cls)s_append_bind;
""" % dict(cls=cls))
        else:
            instantiate_fn_ptrs(cls, 4, out)

def gen_new_function_definitions(out):
    """
    Generate the new operator for all classes

    @param out The file to which to write the functions
    """

    out.write("\n/* New operators for each message class */\n")
    for cls in of_g.standard_class_order:
        out.write("\n/* New operators for %s */\n" % cls)
        gen_new_fn_body(cls, out)
        gen_init_fn_body(cls, out)
        if loxi_utils.class_is_message(cls):
            gen_from_message_fn_body(cls, out)

def gen_init_map(out):
    """
    Generate map from object ID to type coerce function
    """
    out.write("""
/**
 * Map from object ID to type coerce function
 */
of_object_init_f of_object_init_map[] = {
    (of_object_init_f)NULL,
""")
    count = 1
    for i, cls in enumerate(of_g.standard_class_order):
        if count != of_g.unified[cls]["object_id"]:
            print "Error in class mapping: object IDs not sequential"
            print cls, count, of_g.unified[cls]["object_id"]
            sys.exit(1)
        s = "(of_object_init_f)%s_init" % cls
        if cls in type_maps.inheritance_map:
            s = "(of_object_init_f)%s_header_init" % cls
        if i < len(of_g.standard_class_order) - 1:
            s += ","
        out.write("    %-65s /* %d */\n" % (s, count))
        count += 1
    out.write("};\n")

"""
Document generation functions

The main reason this is here is to generate documentation per
accessor that indicates the versions that support the interface.
"""


def gen_accessor_doc(out, name):
    """
    Generate documentation for each accessor function that indicates
    the versions supporting the accessor.
    """

    common_top_matter(out, name)

    out.write("/* DOCUMENTATION ONLY */\n")

    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            pass # Check this

        out.write("""
/**
 * Structure for %(cls)s object.  Get/set 
 * accessors available in all versions unless noted otherwise
 *
""" % dict(cls=cls))
        if loxi_utils.class_is_list(cls):
            out.write("""\
 * @param first Function of type %(cls)s_first_f.
 * Setup a TBD class object to the first entry in the list
 * @param next Function of type %(cls)s_next_f.
 * Advance a TBD class object to the next entry in the list
 * @param append_bind Function of type %(cls)s_append_bind_f
 * Setup a TBD class object for append to the end of the current list
 * @param append  Function of type @ref %(cls)s_append_f.
 * Copy an item to the end of a list
""" % dict(cls=cls))

        for m_name in of_g.ordered_members[cls]:
            if m_name in of_g.skip_members:
                continue
            ver_type_map = field_ver_get(cls, m_name)
            (m_type, get_rv) = get_acc_rv(cls, m_name)
            if len(ver_type_map) == 3:
                # ver_string = "Available in all versions"
                ver_string = ""
            else:
                ver_string = "("
                for ver in sorted(ver_type_map):
                    ver_string += " " + of_g.short_version_names[ver]
                ver_string += ")."

            f_name = acc_name(cls, m_name)
            out.write("""\
 * @param %(m_name)s_get/set %(ver_string)s
 *   Accessors for %(m_name)s, a variable of type %(m_type)s.  Functions
 *   are of type %(f_name)s_get_f and _set_f.
 *
""" % dict(f_name=f_name, m_name=m_name, ver_string=ver_string, m_type=m_type))

        out.write("""\
 */
typedef struct %(cls)s_s %(cls)s_t;
""" % dict(cls=cls))

    out.write("#endif /* _LOCI_DOC_H_ */\n")

################################################################
#
# For fun, here are some unified, traditional C structure representation
#
################################################################

def gen_cof_to_wire(out):
    pass

def gen_wire_to_cof(out):
    pass

def gen_cof_instance(out, cls):
    out.write("struct c%s_s {\n" % cls)
    for m in of_g.ordered_members[cls]:
        if m in of_g.skip_members:
            continue
        entry = of_g.unified[cls]["union"][m]
        cof_type = type_to_cof_type(entry["m_type"])
        out.write("    %-20s %s;\n" % (cof_type, m))
    out.write("};\n\n");

def gen_cof_structs(out):
    """
    Generate non-version specific (common) representation of structures

    @param out The file to which to write the functions
    """

    out.write("\n/* Common, unified OpenFlow structure representations */\n")
    for cls in of_g.standard_class_order:
        if cls in type_maps.inheritance_map:
            continue
        gen_cof_instance(out, cls)

################################################################
#
# Generate code samples for applications.
#
################################################################

def gen_code_samples(out, name):
    out.write("""
#if 0 /* Do not compile in */
/**
 * @file %(name)s
 *
 * These are code samples for inclusion in other components
 */

""" % dict(name=name))

    gen_jump_table_template(out)
    # These are messages that a switch might expect.
    msg_list = ["of_echo_request",
                "of_hello",
                "of_packet_in",
                "of_packet_out",
                "of_port_mod",
                "of_port_stats_request",
                "of_queue_get_config_request",
                "of_queue_stats_request",
                "of_flow_add",
                "of_flow_modify",
                "of_flow_modify_strict",
                "of_flow_delete",
                "of_flow_delete_strict",
                "of_get_config_request",
                "of_flow_stats_request",
                "of_barrier_request",
                "of_echo_reply",
                "of_aggregate_stats_request",
                "of_desc_stats_request",
                "of_table_stats_request",
                "of_features_request",
                "of_table_mod",
                "of_set_config",
                "of_experimenter",
                "of_experimenter_stats_request",
                "of_group_desc_stats_request",
                "of_group_features_stats_request",
                "of_role_request"]

    gen_message_handler_templates(out, msgs=msg_list)

    out.write("""
#endif
""")

def gen_jump_table_template(out=sys.stdout, all_unhandled=True,
                            cxn_type="ls_cxn_handle_t", 
                            unhandled="unhandled_message"):
    """
    Generate a template for a jump table.
    @param out The file to which to write the functions
    """
    out.write("""
/*
 * Simple jump table definition for message handling
 */
typedef int (*msg_handler_f)(%(cxn_type)s cxn, of_object_t *obj);
typedef msg_handler_f msg_jump_table_t[OF_MESSAGE_OBJECT_COUNT];

/* Jump table template for message objects */
extern msg_jump_table_t jump_table;

/* C-code template */
msg_jump_table_t jump_table = {
    %(unhandled)s, /* OF_OBJECT; place holder for generic object  */
""" % dict(unhandled=unhandled, cxn_type=cxn_type))
    count = 0
    fn_name = unhandled
    for cls in of_g.ordered_messages:
        comma = ","
        count += 1
        if count == len(of_g.ordered_messages):
            comma = " "
        if not all_unhandled:
            fn_name = "%s_handler" % cls[3:]
        out.write("    %s%s /* %s */\n" % (fn_name, comma, enum_name(cls)))
            
    out.write("};\n")

def gen_message_switch_stmt_tmeplate(out=sys.stdout, all_unhandled=True,
                                     cxn_type="ls_cxn_handle_t", 
                                     unhandled="unhandled_message"):
    out.write("""
/*
 * Simple switch statement for message handling
 */

    switch (obj->object_id):
""")
    fn_name = unhandled
    for cls in of_g.ordered_messages:
        if not all_unhandled:
            fn_name = "%s_handler" % cls[3:]
        out.write("""
    case %(enum)s:
        rv = %(fn_name)s(cxn, obj);
        break;
""" % dict(fn_name=fn_name, cls=cls, enum=enum_name(cls)))
    out.write("""
    default:
        rv = LS_ERROR_PARAM;
        break;
    }

    TRACE("Handled msg %p with rv %d (%s)", obj, rv, ls_error_strings[rv]);

    return rv;
""")


def gen_message_handler_templates(out=sys.stdout, cxn_type="ls_cxn_handle_t",
                                  unhandled="unhandled_message", msgs=None):
    gen_jump_table_template(out, False, cxn_type)
    out.write("""
/**
 * Function for unhandled message
 */
static int
unhandled_message(%(cxn_type)s cxn, of_object_t *obj)
{
    (void)cxn;
    (void)obj;
    TRACE("Unhandled message %%p.  Object id %%d", obj, obj->object_id);

    return LS_ERROR_UNAVAIL;
}
""" % dict(unhandled=unhandled, cxn_type=cxn_type))

    if not msgs:
        msgs = of_g.ordered_messages
    for cls in msgs:
        out.write("""
/**
 * Handle a %(s_cls)s message
 * @param cxn Connection handler for the owning connection
 * @param _obj Generic type object for the message to be coerced
 * @returns Error code
 */

static int
%(s_cls)s_handler(%(cxn_type)s cxn, of_object_t *_obj)
{
    %(cls)s_t *obj;

    TRACE("Handling %(cls)s message: %%p.", obj);
    obj = (%(cls)s_t *)_obj;

    /* Handle object of type %(cls)s_t */

    return LS_ERROR_NONE;
}
""" % dict(s_cls=cls[3:], cls=cls, cxn_type=cxn_type))
    gen_message_switch_stmt_tmeplate(out, False, cxn_type)

def gen_setup_from_add_fns(out):
    """
    Generate functions that setup up objects based on an add

    Okay, this is getting out of hand.  We need to refactor the code
    so that this can be done without so much pain.
    """
    out.write("""

/* Flow stats entry setup for all versions */

static int
flow_stats_entry_setup_from_flow_add_common(of_flow_stats_entry_t *obj,
                                            of_flow_add_t *flow_add,
                                            of_object_t *effects,
                                            int entry_match_offset,
                                            int add_match_offset)
{
    of_list_action_t actions;
    int entry_len, add_len;
    of_wire_buffer_t *wbuf;
    int abs_offset;
    int delta;
    uint16_t val16;
    uint64_t cookie;
    of_octets_t match_octets;

    /* Effects may come from different places */
    if (effects != NULL) {
        OF_TRY(of_flow_stats_entry_actions_set(obj,
               (of_list_action_t *)effects));
    } else {
        of_flow_add_actions_bind(flow_add, &actions);
        OF_TRY(of_flow_stats_entry_actions_set(obj, &actions));
    }

    /* Transfer the match underlying object from add to stats entry */
    wbuf = OF_OBJECT_TO_WBUF(obj);
    entry_len = _WIRE_MATCH_PADDED_LEN(obj, entry_match_offset);
    add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset);

    match_octets.bytes = add_len;
    match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset);

    /* Copy data into flow entry */
    abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, entry_match_offset);
    of_wire_buffer_replace_data(wbuf, abs_offset, entry_len,
                                match_octets.data, add_len);

    /* Not scalar, update lengths if needed */
    delta = add_len - entry_len;
    if (delta != 0) {
        /* Update parent(s) */
        of_object_parent_length_update((of_object_t *)obj, delta);
    }

    of_flow_add_cookie_get(flow_add, &cookie);
    of_flow_stats_entry_cookie_set(obj, cookie);

    of_flow_add_priority_get(flow_add, &val16);
    of_flow_stats_entry_priority_set(obj, val16);

    of_flow_add_idle_timeout_get(flow_add, &val16);
    of_flow_stats_entry_idle_timeout_set(obj, val16);

    of_flow_add_hard_timeout_get(flow_add, &val16);
    of_flow_stats_entry_hard_timeout_set(obj, val16);

    return OF_ERROR_NONE;
}

/* Flow removed setup for all versions */

static int
flow_removed_setup_from_flow_add_common(of_flow_removed_t *obj,
                                        of_flow_add_t *flow_add,
                                        int removed_match_offset,
                                        int add_match_offset)
{
    int add_len, removed_len;
    of_wire_buffer_t *wbuf;
    int abs_offset;
    int delta;
    uint16_t val16;
    uint64_t cookie;
    of_octets_t match_octets;

    /* Transfer the match underlying object from add to removed obj */
    wbuf = OF_OBJECT_TO_WBUF(obj);
    removed_len = _WIRE_MATCH_PADDED_LEN(obj, removed_match_offset);
    add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset);

    match_octets.bytes = add_len;
    match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset);

    /* Copy data into flow removed */
    abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, removed_match_offset);
    of_wire_buffer_replace_data(wbuf, abs_offset, removed_len,
                                match_octets.data, add_len);

    /* Not scalar, update lengths if needed */
    delta = add_len - removed_len;
    if (delta != 0) {
        /* Update parent(s) */
        of_object_parent_length_update((of_object_t *)obj, delta);
    }

    of_flow_add_cookie_get(flow_add, &cookie);
    of_flow_removed_cookie_set(obj, cookie);

    of_flow_add_priority_get(flow_add, &val16);
    of_flow_removed_priority_set(obj, val16);

    of_flow_add_idle_timeout_get(flow_add, &val16);
    of_flow_removed_idle_timeout_set(obj, val16);
 
    if (obj->version >= OF_VERSION_1_2) {
        of_flow_add_hard_timeout_get(flow_add, &val16);
        of_flow_removed_hard_timeout_set(obj, val16);
    }

    return OF_ERROR_NONE;
}

/* Set up a flow removed message from the original add */

int
of_flow_removed_setup_from_flow_add(of_flow_removed_t *obj,
                                    of_flow_add_t *flow_add)
{
    switch (obj->version) {
    case OF_VERSION_1_0:
        return flow_removed_setup_from_flow_add_common(obj, flow_add, 
                                                       8, 8);
        break;
    case OF_VERSION_1_1:
    case OF_VERSION_1_2:
    case OF_VERSION_1_3:
        return flow_removed_setup_from_flow_add_common(obj, flow_add, 
                                                       48, 48);
        break;
    default:
        return OF_ERROR_VERSION;
        break;
    }

    return OF_ERROR_NONE;
}


/* Set up a packet in message from the original add */

int
of_packet_in_setup_from_flow_add(of_packet_in_t *obj,
                                 of_flow_add_t *flow_add)
{
    int add_len, pkt_in_len;
    of_wire_buffer_t *wbuf;
    int abs_offset;
    int delta;
    const int pkt_in_match_offset = 16;
    const int add_match_offset = 48;
    of_octets_t match_octets;

    if (obj->version < OF_VERSION_1_2) {
        /* Nothing to be done before OF 1.2 */
        return OF_ERROR_NONE;
    }

    /* Transfer match struct from flow add to packet in object */
    wbuf = OF_OBJECT_TO_WBUF(obj);
    pkt_in_len = _WIRE_MATCH_PADDED_LEN(obj, pkt_in_match_offset);
    add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset);

    match_octets.bytes = add_len;
    match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset);

    /* Copy data into pkt_in msg */
    abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, pkt_in_match_offset);
    of_wire_buffer_replace_data(wbuf, abs_offset, pkt_in_len,
                                match_octets.data, add_len);

    /* Not scalar, update lengths if needed */
    delta = add_len - pkt_in_len;
    if (delta != 0) {
        /* Update parent(s) */
        of_object_parent_length_update((of_object_t *)obj, delta);
    }

    return OF_ERROR_NONE;
}

/* Set up a stats entry from the original add */

int
of_flow_stats_entry_setup_from_flow_add(of_flow_stats_entry_t *obj,
                                        of_flow_add_t *flow_add,
                                        of_object_t *effects)
{
    switch (obj->version) {
    case OF_VERSION_1_0:
        return flow_stats_entry_setup_from_flow_add_common(obj, flow_add,
                                                           effects, 4, 8);
        break;
    case OF_VERSION_1_1:
    case OF_VERSION_1_2:
    case OF_VERSION_1_3:
        return flow_stats_entry_setup_from_flow_add_common(obj, flow_add, 
                                                           effects, 48, 48);
        break;
    default:
        return OF_ERROR_VERSION;
    }

    return OF_ERROR_NONE;
}
""")
