// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
// Copyright (c) 2011, 2012 Open Networking Foundation
// Copyright (c) 2012, 2013 Big Switch Networks, Inc.
// This library was generated by the LoxiGen Compiler.
// See the file LICENSE.txt which should have been included in the source distribution

// Automatically generated by LOXI from template of_class.java
// Do not modify

package org.projectfloodlight.openflow.protocol.ver13;

import org.projectfloodlight.openflow.protocol.*;
import org.projectfloodlight.openflow.protocol.action.*;
import org.projectfloodlight.openflow.protocol.actionid.*;
import org.projectfloodlight.openflow.protocol.bsntlv.*;
import org.projectfloodlight.openflow.protocol.errormsg.*;
import org.projectfloodlight.openflow.protocol.meterband.*;
import org.projectfloodlight.openflow.protocol.instruction.*;
import org.projectfloodlight.openflow.protocol.instructionid.*;
import org.projectfloodlight.openflow.protocol.match.*;
import org.projectfloodlight.openflow.protocol.oxm.*;
import org.projectfloodlight.openflow.protocol.queueprop.*;
import org.projectfloodlight.openflow.types.*;
import org.projectfloodlight.openflow.util.*;
import org.projectfloodlight.openflow.exceptions.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Set;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.common.hash.PrimitiveSink;
import com.google.common.hash.Funnel;

class OFBsnSwitchPipelineStatsEntryVer13 implements OFBsnSwitchPipelineStatsEntry {
    private static final Logger logger = LoggerFactory.getLogger(OFBsnSwitchPipelineStatsEntryVer13.class);
    // version: 1.3
    final static byte WIRE_VERSION = 4;
    final static int LENGTH = 256;

        private final static String DEFAULT_PIPELINE = "";

    // OF message fields
    private final String pipeline;
//
    // Immutable default instance
    final static OFBsnSwitchPipelineStatsEntryVer13 DEFAULT = new OFBsnSwitchPipelineStatsEntryVer13(
        DEFAULT_PIPELINE
    );

    // package private constructor - used by readers, builders, and factory
    OFBsnSwitchPipelineStatsEntryVer13(String pipeline) {
        this.pipeline = pipeline;
    }

    // Accessors for OF message fields
    @Override
    public String getPipeline() {
        return pipeline;
    }

    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_13;
    }



    public OFBsnSwitchPipelineStatsEntry.Builder createBuilder() {
        return new BuilderWithParent(this);
    }

    static class BuilderWithParent implements OFBsnSwitchPipelineStatsEntry.Builder {
        final OFBsnSwitchPipelineStatsEntryVer13 parentMessage;

        // OF message fields
        private boolean pipelineSet;
        private String pipeline;

        BuilderWithParent(OFBsnSwitchPipelineStatsEntryVer13 parentMessage) {
            this.parentMessage = parentMessage;
        }

    @Override
    public String getPipeline() {
        return pipeline;
    }

    @Override
    public OFBsnSwitchPipelineStatsEntry.Builder setPipeline(String pipeline) {
        this.pipeline = pipeline;
        this.pipelineSet = true;
        return this;
    }
    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_13;
    }



        @Override
        public OFBsnSwitchPipelineStatsEntry build() {
                String pipeline = this.pipelineSet ? this.pipeline : parentMessage.pipeline;
                if(pipeline == null)
                    throw new NullPointerException("Property pipeline must not be null");

                //
                return new OFBsnSwitchPipelineStatsEntryVer13(
                    pipeline
                );
        }

    }

    static class Builder implements OFBsnSwitchPipelineStatsEntry.Builder {
        // OF message fields
        private boolean pipelineSet;
        private String pipeline;

    @Override
    public String getPipeline() {
        return pipeline;
    }

    @Override
    public OFBsnSwitchPipelineStatsEntry.Builder setPipeline(String pipeline) {
        this.pipeline = pipeline;
        this.pipelineSet = true;
        return this;
    }
    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_13;
    }

//
        @Override
        public OFBsnSwitchPipelineStatsEntry build() {
            String pipeline = this.pipelineSet ? this.pipeline : DEFAULT_PIPELINE;
            if(pipeline == null)
                throw new NullPointerException("Property pipeline must not be null");


            return new OFBsnSwitchPipelineStatsEntryVer13(
                    pipeline
                );
        }

    }


    final static Reader READER = new Reader();
    static class Reader implements OFMessageReader<OFBsnSwitchPipelineStatsEntry> {
        @Override
        public OFBsnSwitchPipelineStatsEntry readFrom(ChannelBuffer bb) throws OFParseError {
            String pipeline = ChannelUtils.readFixedLengthString(bb, 256);

            OFBsnSwitchPipelineStatsEntryVer13 bsnSwitchPipelineStatsEntryVer13 = new OFBsnSwitchPipelineStatsEntryVer13(
                    pipeline
                    );
            if(logger.isTraceEnabled())
                logger.trace("readFrom - read={}", bsnSwitchPipelineStatsEntryVer13);
            return bsnSwitchPipelineStatsEntryVer13;
        }
    }

    public void putTo(PrimitiveSink sink) {
        FUNNEL.funnel(this, sink);
    }

    final static OFBsnSwitchPipelineStatsEntryVer13Funnel FUNNEL = new OFBsnSwitchPipelineStatsEntryVer13Funnel();
    static class OFBsnSwitchPipelineStatsEntryVer13Funnel implements Funnel<OFBsnSwitchPipelineStatsEntryVer13> {
        private static final long serialVersionUID = 1L;
        @Override
        public void funnel(OFBsnSwitchPipelineStatsEntryVer13 message, PrimitiveSink sink) {
            sink.putUnencodedChars(message.pipeline);
        }
    }


    public void writeTo(ChannelBuffer bb) {
        WRITER.write(bb, this);
    }

    final static Writer WRITER = new Writer();
    static class Writer implements OFMessageWriter<OFBsnSwitchPipelineStatsEntryVer13> {
        @Override
        public void write(ChannelBuffer bb, OFBsnSwitchPipelineStatsEntryVer13 message) {
            ChannelUtils.writeFixedLengthString(bb, message.pipeline, 256);


        }
    }

    @Override
    public String toString() {
        StringBuilder b = new StringBuilder("OFBsnSwitchPipelineStatsEntryVer13(");
        b.append("pipeline=").append(pipeline);
        b.append(")");
        return b.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        OFBsnSwitchPipelineStatsEntryVer13 other = (OFBsnSwitchPipelineStatsEntryVer13) obj;

        if (pipeline == null) {
            if (other.pipeline != null)
                return false;
        } else if (!pipeline.equals(other.pipeline))
            return false;
        return true;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;

        result = prime * result + ((pipeline == null) ? 0 : pipeline.hashCode());
        return result;
    }

}
