// 
// Decompiled by Procyon v0.6.0
// 

package io.netty.handler.codec.protobuf;

import io.netty.buffer.ByteBufUtil;
import java.util.List;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.internal.ObjectUtil;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.MessageLite;
import io.netty.channel.ChannelHandler;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.MessageToMessageDecoder;

@ChannelHandler.Sharable
public class ProtobufDecoder extends MessageToMessageDecoder<ByteBuf>
{
    private static final boolean HAS_PARSER;
    private final MessageLite prototype;
    private final ExtensionRegistryLite extensionRegistry;
    
    public ProtobufDecoder(final MessageLite prototype) {
        this(prototype, null);
    }
    
    public ProtobufDecoder(final MessageLite prototype, final ExtensionRegistry extensionRegistry) {
        this(prototype, (ExtensionRegistryLite)extensionRegistry);
    }
    
    public ProtobufDecoder(final MessageLite prototype, final ExtensionRegistryLite extensionRegistry) {
        super(ByteBuf.class);
        this.prototype = ObjectUtil.checkNotNull(prototype, "prototype").getDefaultInstanceForType();
        this.extensionRegistry = extensionRegistry;
    }
    
    @Override
    protected void decode(final ChannelHandlerContext ctx, final ByteBuf msg, final List<Object> out) throws Exception {
        final int length = msg.readableBytes();
        byte[] array;
        int offset;
        if (msg.hasArray()) {
            array = msg.array();
            offset = msg.arrayOffset() + msg.readerIndex();
        }
        else {
            array = ByteBufUtil.getBytes(msg, msg.readerIndex(), length, false);
            offset = 0;
        }
        if (this.extensionRegistry == null) {
            if (ProtobufDecoder.HAS_PARSER) {
                out.add(this.prototype.getParserForType().parseFrom(array, offset, length));
            }
            else {
                out.add(this.prototype.newBuilderForType().mergeFrom(array, offset, length).build());
            }
        }
        else if (ProtobufDecoder.HAS_PARSER) {
            out.add(this.prototype.getParserForType().parseFrom(array, offset, length, this.extensionRegistry));
        }
        else {
            out.add(this.prototype.newBuilderForType().mergeFrom(array, offset, length, this.extensionRegistry).build());
        }
    }
    
    static {
        boolean hasParser = false;
        try {
            MessageLite.class.getDeclaredMethod("getParserForType", (Class<?>[])new Class[0]);
            hasParser = true;
        }
        catch (final Throwable t) {}
        HAS_PARSER = hasParser;
    }
}
