# 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 c_gen.of_g_legacy as of_g
import c_match
from generic_utils import *
from c_gen import flags, type_maps, c_type_maps
import c_gen.loxi_utils_legacy as loxi_utils
from c_gen.loxi_utils_legacy import config_check
import loxi_globals

import c_gen.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)#x)
#define %(ident)s_BY_VERSION(version) (%(value)#x)
""" % 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("%#x" % 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);
""")

    # gen_base_types(out)

    gen_flow_add_setup_function_declarations(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 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)
    c_type_maps.gen_extra_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 *const 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];

typedef struct of_bitmap_128_s {
    uint64_t hi;
    uint64_t lo;
} of_bitmap_128_t;

/* 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/loci_classes.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_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 *const 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;
}
""")

################################################################
#
# 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
        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_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);
""")

################################################################
#
# 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, 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)

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


################################################################
# 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] + of_object_extra_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))

    import loxi_globals
    uclass = loxi_globals.unified.class_by_name(cls)
    if uclass and not uclass.virtual and uclass.has_type_members:
        out.write("""
    %(cls)s_push_wire_types(obj);
""" % dict(cls=cls))

    if loxi_utils.class_is_message(cls):
        out.write("""
    /* Message obj; set length */
    of_message_t msg;

    if ((msg = OF_OBJECT_TO_MESSAGE(obj)) != NULL) {
        of_message_length_set(msg, obj->length);
    }
""" % dict(name = enum_name(cls)))

    else: # Not a message
        if loxi_utils.class_is_tlv16(cls):
            out.write("""
    /* TLV obj; set length */
    of_tlv16_wire_length_set((of_object_t *)obj, obj->length);
""" % 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] + of_object_extra_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 const 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 */
""")

    uclass = loxi_globals.unified.class_by_name(cls)
    if uclass and not uclass.virtual and uclass.has_type_members:
        out.write("""
    obj->wire_type_set = %(cls)s_push_wire_types;
""" % dict(cls=cls))

    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;
""")
            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_type_get = of_oxm_wire_object_id_get;
""")
        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;
""")

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

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

    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)

"""
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)
