# 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_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 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
 *
 ****************************************************************/

#ifdef __GNUC__
#ifdef __linux__
/* glibc */
#include <features.h>
#else
/* NetBSD etc */
#include <sys/cdefs.h>
#ifdef __GNUC_PREREQ__
#define __GNUC_PREREQ __GNUC_PREREQ__
#endif
#endif

#ifndef __GNUC_PREREQ
/* fallback */
#define __GNUC_PREREQ(maj, min) 0
#endif

#if __GNUC_PREREQ(4,4)
#pragma GCC optimize ("s")
#endif

#if __GNUC_PREREQ(4,6)
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif

#endif

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

""")
    gen_object_enum_str(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)
    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/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 *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;
}
""")

def gen_object_enum_str(out):
    out.write("\nconst char *const 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 *const 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 *const 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, 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)

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

    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
 */
const 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)
{
    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;

    /* 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);

    /* Effects may come from different places */
    if (effects != NULL) {
        if (obj->version == OF_VERSION_1_0) {
            OF_TRY(of_flow_stats_entry_actions_set(obj,
                (of_list_action_t *)effects));
        } else {
            OF_TRY(of_flow_stats_entry_instructions_set(obj,
                (of_list_instruction_t *)effects));
        }
    } else {
        if (obj->version == OF_VERSION_1_0) {
            of_list_action_t actions;
            of_flow_add_actions_bind(flow_add, &actions);
            OF_TRY(of_flow_stats_entry_actions_set(obj, &actions));
        } else {
            of_list_instruction_t instructions;
            of_flow_add_instructions_bind(flow_add, &instructions);
            OF_TRY(of_flow_stats_entry_instructions_set(obj, &instructions));
        }
    }

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