java_gen: add optional instrumentation
diff --git a/java_gen/codegen.py b/java_gen/codegen.py
index 4369b30..6c589c9 100644
--- a/java_gen/codegen.py
+++ b/java_gen/codegen.py
@@ -37,6 +37,7 @@
 from loxi_ir import *
 import lang_java
 import test_data
+from collections import namedtuple
 from import_cleaner import ImportCleaner
 
 import loxi_utils.loxi_utils as loxi_utils
@@ -52,20 +53,21 @@
         shutil.rmtree(basedir)
     os.makedirs(basedir)
     copy_prewrite_tree(basedir)
-    gen = JavaGenerator(basedir)
+    gen = JavaGenerator(basedir, JavaGeneratorOptions(instrument=True))
     gen.create_of_interfaces()
     gen.create_of_classes()
     gen.create_of_const_enums()
     gen.create_of_factories()
 
-
+JavaGeneratorOptions = namedtuple("JavaGeneratorOptions", ("instrument",))
 
 class JavaGenerator(object):
     templates_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'templates')
 
-    def __init__(self, basedir):
+    def __init__(self, basedir, gen_opts):
         self.basedir = basedir
         self.java_model = java_model.model
+        self.gen_opts = gen_opts
 
     def render_class(self, clazz, template, src_dir=None, **context):
         if not src_dir:
@@ -74,6 +76,7 @@
         context['class_name'] = clazz.name
         context['package'] = clazz.package
         context['template_dir'] = self.templates_dir
+        context['genopts']= self.gen_opts
 
         filename = os.path.join(self.basedir, src_dir, "%s/%s.java" % (clazz.package.replace(".", "/"), clazz.name))
         dirname = os.path.dirname(filename)
@@ -83,14 +86,13 @@
         print "filename: %s" % filename
         with open(filename, "w") as f:
             loxi_utils.render_template(f, template, [self.templates_dir], context, prefix=prefix)
-        
+
         try:
             cleaner = ImportCleaner(filename)
             cleaner.find_used_imports()
             cleaner.rewrite_file(filename)
         except:
             print 'Cannot clean imports from file %s' % filename
-        
 
     def create_of_const_enums(self):
         for enum in self.java_model.enums:
diff --git a/java_gen/pre-written/pom.xml b/java_gen/pre-written/pom.xml
index 5715704..e93b6f5 100644
--- a/java_gen/pre-written/pom.xml
+++ b/java_gen/pre-written/pom.xml
@@ -55,6 +55,11 @@
             <artifactId>guava</artifactId>
             <version>15.0</version>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.5</version>
+        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFInstrumentationOptions.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFInstrumentationOptions.java
new file mode 100644
index 0000000..97d7165
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFInstrumentationOptions.java
@@ -0,0 +1,7 @@
+package org.projectfloodlight.openflow.protocol;
+
+public final class OFInstrumentationOptions {
+    public static final boolean TRACE_READS = false;
+
+    private OFInstrumentationOptions() { }
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/ChannelUtils.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/ChannelUtils.java
index 13cfdc7..f024fa3 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/ChannelUtils.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/ChannelUtils.java
@@ -4,8 +4,11 @@
 
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.projectfloodlight.openflow.exceptions.OFParseError;
+import org.projectfloodlight.openflow.protocol.OFInstrumentationOptions;
 import org.projectfloodlight.openflow.protocol.OFMessageReader;
 import org.projectfloodlight.openflow.protocol.Writeable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
@@ -18,6 +21,7 @@
  */
 
 public class ChannelUtils {
+    private static final Logger logger = LoggerFactory.getLogger(ChannelUtils.class);
     public static String readFixedLengthString(ChannelBuffer bb, int length) {
         byte[] dst = new byte[length];
         bb.readBytes(dst, 0, length);
@@ -56,8 +60,15 @@
     public static <T> List<T> readList(ChannelBuffer bb, int length, OFMessageReader<T> reader) throws OFParseError {
         int end = bb.readerIndex() + length;
         Builder<T> builder = ImmutableList.<T>builder();
+        if(OFInstrumentationOptions.TRACE_READS)
+            if(logger.isTraceEnabled())
+                logger.trace("readList(length={}, reader={})", length, reader.getClass());
         while(bb.readerIndex() < end) {
-            builder.add(reader.readFrom(bb));
+            T read = reader.readFrom(bb);
+            if(OFInstrumentationOptions.TRACE_READS)
+                if(logger.isTraceEnabled())
+                    logger.trace("readList: read={}, left={}", read, end - bb.readerIndex());
+            builder.add(read);
         }
         if(bb.readerIndex() != end) {
             throw new IllegalStateException("Overread length: length="+length + " overread by "+ (bb.readerIndex() - end) + " reader: "+reader);
diff --git a/java_gen/templates/_imports.java b/java_gen/templates/_imports.java
index 55e9a2d..2187bab 100644
--- a/java_gen/templates/_imports.java
+++ b/java_gen/templates/_imports.java
@@ -14,6 +14,8 @@
 import org.projectfloodlight.openflow.types.*;
 import org.projectfloodlight.openflow.util.*;
 import org.projectfloodlight.openflow.exceptions.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.jboss.netty.buffer.ChannelBuffers;
 import com.google.common.collect.ImmutableList;
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index 7b3b762..ee38beb 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -38,6 +38,9 @@
 //:: include("_imports.java", msg=msg)
 
 class ${impl_class} implements ${msg.interface.inherited_declaration()} {
+//:: if genopts.instrument:
+    private static final Logger logger = LoggerFactory.getLogger(${impl_class}.class);
+//:: #endif
     // version: ${version}
     final static byte WIRE_VERSION = ${version.int_version};
 //:: if msg.is_fixed_length:
@@ -216,6 +219,11 @@
                 bb.readerIndex(start);
                 return null;
             }
+            //:: if genopts.instrument:
+            if(OFInstrumentationOptions.TRACE_READS)
+                if(logger.isTraceEnabled())
+                    logger.trace("readFrom - length={}", ${prop.name});
+            //:: #endif
 //:: elif prop.is_fixed_value:
             // fixed value property ${prop.name} == ${prop.value}
             ${prop.java_type.priv_type} ${prop.name} = ${prop.java_type.read_op(version, pub_type=False)};
@@ -242,11 +250,22 @@
             //:: if os.path.exists("%s/custom/%s.Reader_normalize_stanza.java" % (template_dir, msg.name)):
             //:: include("custom/%s.Reader_normalize_stanza.java" % msg.name, msg=msg, has_parent=False)
             //:: #endif
-             return new ${impl_class}(
+            ${impl_class} ${msg.variable_name} = new ${impl_class}(
                     ${",\n                      ".join(
                          [ prop.name for prop in msg.data_members])}
                     );
+            //:: if genopts.instrument:
+            if(OFInstrumentationOptions.TRACE_READS)
+                if(logger.isTraceEnabled())
+                    logger.trace("readFrom - read={}", ${msg.variable_name});
+            //:: #endif
+            return ${msg.variable_name};
             //:: else:
+            //:: if genopts.instrument:
+            if(OFInstrumentationOptions.TRACE_READS)
+                if(logger.isTraceEnabled())
+                    logger.trace("readFrom - returning shared instance={}", INSTANCE);
+            //:: #endif
             return INSTANCE;
             //:: #endif
         }