/**
 * * @@@ START COPYRIGHT @@@
 * *
 * * Licensed to the Apache Software Foundation (ASF) under one
 * * or more contributor license agreements.  See the NOTICE file
 * * distributed with this work for additional information
 * * regarding copyright ownership.  The ASF licenses this file
 * * to you under the Apache License, Version 2.0 (the
 * * "License"); you may not use this file except in compliance
 * * with the License.  You may obtain a copy of the License at
 * *
 * *   http://www.apache.org/licenses/LICENSE-2.0
 * *
 * * 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 License for the
 * * specific language governing permissions and limitations
 * * under the License.
 * *
 * * @@@ END COPYRIGHT @@@
 * **/


// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: SsccRegion.proto

package org.apache.hadoop.hbase.coprocessor.transactional.generated;

public final class SsccRegionProtos {
  private SsccRegionProtos() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
  }
  public interface SsccAbortTransactionRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required bytes regionName = 1;
    /**
     * <code>required bytes regionName = 1;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 1;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required int64 transactionId = 2;
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    long getTransactionId();
  }
  /**
   * Protobuf type {@code SsccAbortTransactionRequest}
   */
  public static final class SsccAbortTransactionRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccAbortTransactionRequestOrBuilder {
    // Use SsccAbortTransactionRequest.newBuilder() to construct.
    private SsccAbortTransactionRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccAbortTransactionRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccAbortTransactionRequest defaultInstance;
    public static SsccAbortTransactionRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccAbortTransactionRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccAbortTransactionRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              regionName_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              transactionId_ = input.readInt64();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccAbortTransactionRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccAbortTransactionRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccAbortTransactionRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccAbortTransactionRequest>() {
      public SsccAbortTransactionRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccAbortTransactionRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccAbortTransactionRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required bytes regionName = 1;
    public static final int REGIONNAME_FIELD_NUMBER = 1;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 1;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required bytes regionName = 1;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required int64 transactionId = 2;
    public static final int TRANSACTIONID_FIELD_NUMBER = 2;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    private void initFields() {
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      transactionId_ = 0L;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, regionName_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, transactionId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, regionName_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, transactionId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccAbortTransactionRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccAbortTransactionRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccAbortTransactionRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccAbortTransactionRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.transactionId_ = transactionId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest.getDefaultInstance()) return this;
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasTransactionId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required bytes regionName = 1;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required int64 transactionId = 2;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000002;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccAbortTransactionRequest)
    }

    static {
      defaultInstance = new SsccAbortTransactionRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccAbortTransactionRequest)
  }

  public interface SsccAbortTransactionResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional string exception = 1;
    /**
     * <code>optional string exception = 1;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 1;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 1;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 2;
    /**
     * <code>optional bool hasException = 2;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 2;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccAbortTransactionResponse}
   */
  public static final class SsccAbortTransactionResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccAbortTransactionResponseOrBuilder {
    // Use SsccAbortTransactionResponse.newBuilder() to construct.
    private SsccAbortTransactionResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccAbortTransactionResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccAbortTransactionResponse defaultInstance;
    public static SsccAbortTransactionResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccAbortTransactionResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccAbortTransactionResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              exception_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccAbortTransactionResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccAbortTransactionResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccAbortTransactionResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccAbortTransactionResponse>() {
      public SsccAbortTransactionResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccAbortTransactionResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccAbortTransactionResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional string exception = 1;
    public static final int EXCEPTION_FIELD_NUMBER = 1;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 1;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string exception = 1;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 1;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 2;
    public static final int HASEXCEPTION_FIELD_NUMBER = 2;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 2;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional bool hasException = 2;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBool(2, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(2, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccAbortTransactionResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccAbortTransactionResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccAbortTransactionResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccAbortTransactionResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.getDefaultInstance()) return this;
        if (other.hasException()) {
          bitField0_ |= 0x00000001;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional string exception = 1;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 1;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 2;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000002;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccAbortTransactionResponse)
    }

    static {
      defaultInstance = new SsccAbortTransactionResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccAbortTransactionResponse)
  }

  public interface SsccBeginTransactionRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();
  }
  /**
   * Protobuf type {@code SsccBeginTransactionRequest}
   */
  public static final class SsccBeginTransactionRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccBeginTransactionRequestOrBuilder {
    // Use SsccBeginTransactionRequest.newBuilder() to construct.
    private SsccBeginTransactionRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccBeginTransactionRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccBeginTransactionRequest defaultInstance;
    public static SsccBeginTransactionRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccBeginTransactionRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccBeginTransactionRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccBeginTransactionRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccBeginTransactionRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccBeginTransactionRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccBeginTransactionRequest>() {
      public SsccBeginTransactionRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccBeginTransactionRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccBeginTransactionRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccBeginTransactionRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccBeginTransactionRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccBeginTransactionRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccBeginTransactionRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccBeginTransactionRequest)
    }

    static {
      defaultInstance = new SsccBeginTransactionRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccBeginTransactionRequest)
  }

  public interface SsccBeginTransactionResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional string exception = 1;
    /**
     * <code>optional string exception = 1;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 1;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 1;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 2;
    /**
     * <code>optional bool hasException = 2;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 2;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccBeginTransactionResponse}
   */
  public static final class SsccBeginTransactionResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccBeginTransactionResponseOrBuilder {
    // Use SsccBeginTransactionResponse.newBuilder() to construct.
    private SsccBeginTransactionResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccBeginTransactionResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccBeginTransactionResponse defaultInstance;
    public static SsccBeginTransactionResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccBeginTransactionResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccBeginTransactionResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              exception_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccBeginTransactionResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccBeginTransactionResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccBeginTransactionResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccBeginTransactionResponse>() {
      public SsccBeginTransactionResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccBeginTransactionResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccBeginTransactionResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional string exception = 1;
    public static final int EXCEPTION_FIELD_NUMBER = 1;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 1;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string exception = 1;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 1;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 2;
    public static final int HASEXCEPTION_FIELD_NUMBER = 2;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 2;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional bool hasException = 2;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBool(2, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(2, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccBeginTransactionResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccBeginTransactionResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccBeginTransactionResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccBeginTransactionResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.getDefaultInstance()) return this;
        if (other.hasException()) {
          bitField0_ |= 0x00000001;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional string exception = 1;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 1;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 2;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000002;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccBeginTransactionResponse)
    }

    static {
      defaultInstance = new SsccBeginTransactionResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccBeginTransactionResponse)
  }

  public interface SsccCommitRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required bytes regionName = 1;
    /**
     * <code>required bytes regionName = 1;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 1;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required int64 transactionId = 2;
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    long getTransactionId();

    // required int64 commitId = 3;
    /**
     * <code>required int64 commitId = 3;</code>
     */
    boolean hasCommitId();
    /**
     * <code>required int64 commitId = 3;</code>
     */
    long getCommitId();

    // optional bool ignoreUnknownTransactionException = 4;
    /**
     * <code>optional bool ignoreUnknownTransactionException = 4;</code>
     */
    boolean hasIgnoreUnknownTransactionException();
    /**
     * <code>optional bool ignoreUnknownTransactionException = 4;</code>
     */
    boolean getIgnoreUnknownTransactionException();
  }
  /**
   * Protobuf type {@code SsccCommitRequest}
   */
  public static final class SsccCommitRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccCommitRequestOrBuilder {
    // Use SsccCommitRequest.newBuilder() to construct.
    private SsccCommitRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCommitRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCommitRequest defaultInstance;
    public static SsccCommitRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCommitRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCommitRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              regionName_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              transactionId_ = input.readInt64();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              commitId_ = input.readInt64();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              ignoreUnknownTransactionException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCommitRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccCommitRequest>() {
      public SsccCommitRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCommitRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCommitRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required bytes regionName = 1;
    public static final int REGIONNAME_FIELD_NUMBER = 1;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 1;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required bytes regionName = 1;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required int64 transactionId = 2;
    public static final int TRANSACTIONID_FIELD_NUMBER = 2;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 commitId = 3;
    public static final int COMMITID_FIELD_NUMBER = 3;
    private long commitId_;
    /**
     * <code>required int64 commitId = 3;</code>
     */
    public boolean hasCommitId() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required int64 commitId = 3;</code>
     */
    public long getCommitId() {
      return commitId_;
    }

    // optional bool ignoreUnknownTransactionException = 4;
    public static final int IGNOREUNKNOWNTRANSACTIONEXCEPTION_FIELD_NUMBER = 4;
    private boolean ignoreUnknownTransactionException_;
    /**
     * <code>optional bool ignoreUnknownTransactionException = 4;</code>
     */
    public boolean hasIgnoreUnknownTransactionException() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional bool ignoreUnknownTransactionException = 4;</code>
     */
    public boolean getIgnoreUnknownTransactionException() {
      return ignoreUnknownTransactionException_;
    }

    private void initFields() {
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      transactionId_ = 0L;
      commitId_ = 0L;
      ignoreUnknownTransactionException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasCommitId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, regionName_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, transactionId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt64(3, commitId_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBool(4, ignoreUnknownTransactionException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, regionName_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, transactionId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, commitId_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(4, ignoreUnknownTransactionException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCommitRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        commitId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000004);
        ignoreUnknownTransactionException_ = false;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.commitId_ = commitId_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.ignoreUnknownTransactionException_ = ignoreUnknownTransactionException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest.getDefaultInstance()) return this;
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasCommitId()) {
          setCommitId(other.getCommitId());
        }
        if (other.hasIgnoreUnknownTransactionException()) {
          setIgnoreUnknownTransactionException(other.getIgnoreUnknownTransactionException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasCommitId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required bytes regionName = 1;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required int64 transactionId = 2;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000002;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 commitId = 3;
      private long commitId_ ;
      /**
       * <code>required int64 commitId = 3;</code>
       */
      public boolean hasCommitId() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required int64 commitId = 3;</code>
       */
      public long getCommitId() {
        return commitId_;
      }
      /**
       * <code>required int64 commitId = 3;</code>
       */
      public Builder setCommitId(long value) {
        bitField0_ |= 0x00000004;
        commitId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 commitId = 3;</code>
       */
      public Builder clearCommitId() {
        bitField0_ = (bitField0_ & ~0x00000004);
        commitId_ = 0L;
        onChanged();
        return this;
      }

      // optional bool ignoreUnknownTransactionException = 4;
      private boolean ignoreUnknownTransactionException_ ;
      /**
       * <code>optional bool ignoreUnknownTransactionException = 4;</code>
       */
      public boolean hasIgnoreUnknownTransactionException() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional bool ignoreUnknownTransactionException = 4;</code>
       */
      public boolean getIgnoreUnknownTransactionException() {
        return ignoreUnknownTransactionException_;
      }
      /**
       * <code>optional bool ignoreUnknownTransactionException = 4;</code>
       */
      public Builder setIgnoreUnknownTransactionException(boolean value) {
        bitField0_ |= 0x00000008;
        ignoreUnknownTransactionException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool ignoreUnknownTransactionException = 4;</code>
       */
      public Builder clearIgnoreUnknownTransactionException() {
        bitField0_ = (bitField0_ & ~0x00000008);
        ignoreUnknownTransactionException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCommitRequest)
    }

    static {
      defaultInstance = new SsccCommitRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCommitRequest)
  }

  public interface SsccCommitResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional string exception = 1;
    /**
     * <code>optional string exception = 1;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 1;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 1;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 2;
    /**
     * <code>optional bool hasException = 2;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 2;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccCommitResponse}
   */
  public static final class SsccCommitResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccCommitResponseOrBuilder {
    // Use SsccCommitResponse.newBuilder() to construct.
    private SsccCommitResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCommitResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCommitResponse defaultInstance;
    public static SsccCommitResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCommitResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCommitResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              exception_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCommitResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccCommitResponse>() {
      public SsccCommitResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCommitResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCommitResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional string exception = 1;
    public static final int EXCEPTION_FIELD_NUMBER = 1;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 1;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string exception = 1;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 1;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 2;
    public static final int HASEXCEPTION_FIELD_NUMBER = 2;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 2;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional bool hasException = 2;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBool(2, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(2, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCommitResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.getDefaultInstance()) return this;
        if (other.hasException()) {
          bitField0_ |= 0x00000001;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional string exception = 1;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 1;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 2;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000002;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCommitResponse)
    }

    static {
      defaultInstance = new SsccCommitResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCommitResponse)
  }

  public interface SsccCommitRequestRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required bytes regionName = 1;
    /**
     * <code>required bytes regionName = 1;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 1;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required int64 transactionId = 2;
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    long getTransactionId();
  }
  /**
   * Protobuf type {@code SsccCommitRequestRequest}
   */
  public static final class SsccCommitRequestRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccCommitRequestRequestOrBuilder {
    // Use SsccCommitRequestRequest.newBuilder() to construct.
    private SsccCommitRequestRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCommitRequestRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCommitRequestRequest defaultInstance;
    public static SsccCommitRequestRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCommitRequestRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCommitRequestRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              regionName_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              transactionId_ = input.readInt64();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequestRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequestRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCommitRequestRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccCommitRequestRequest>() {
      public SsccCommitRequestRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCommitRequestRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCommitRequestRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required bytes regionName = 1;
    public static final int REGIONNAME_FIELD_NUMBER = 1;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 1;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required bytes regionName = 1;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required int64 transactionId = 2;
    public static final int TRANSACTIONID_FIELD_NUMBER = 2;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    private void initFields() {
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      transactionId_ = 0L;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, regionName_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, transactionId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, regionName_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, transactionId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCommitRequestRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequestRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequestRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequestRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.transactionId_ = transactionId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest.getDefaultInstance()) return this;
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasTransactionId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required bytes regionName = 1;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required int64 transactionId = 2;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000002;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCommitRequestRequest)
    }

    static {
      defaultInstance = new SsccCommitRequestRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCommitRequestRequest)
  }

  public interface SsccCommitRequestResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int32 result = 1;
    /**
     * <code>required int32 result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>required int32 result = 1;</code>
     */
    int getResult();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccCommitRequestResponse}
   */
  public static final class SsccCommitRequestResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccCommitRequestResponseOrBuilder {
    // Use SsccCommitRequestResponse.newBuilder() to construct.
    private SsccCommitRequestResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCommitRequestResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCommitRequestResponse defaultInstance;
    public static SsccCommitRequestResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCommitRequestResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCommitRequestResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              result_ = input.readInt32();
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequestResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequestResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCommitRequestResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccCommitRequestResponse>() {
      public SsccCommitRequestResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCommitRequestResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCommitRequestResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int32 result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private int result_;
    /**
     * <code>required int32 result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 result = 1;</code>
     */
    public int getResult() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      result_ = 0;
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasResult()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCommitRequestResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequestResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequestResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        result_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitRequestResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.result_ = result_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          setResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasResult()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int32 result = 1;
      private int result_ ;
      /**
       * <code>required int32 result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 result = 1;</code>
       */
      public int getResult() {
        return result_;
      }
      /**
       * <code>required int32 result = 1;</code>
       */
      public Builder setResult(int value) {
        bitField0_ |= 0x00000001;
        result_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 result = 1;</code>
       */
      public Builder clearResult() {
        bitField0_ = (bitField0_ & ~0x00000001);
        result_ = 0;
        onChanged();
        return this;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCommitRequestResponse)
    }

    static {
      defaultInstance = new SsccCommitRequestResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCommitRequestResponse)
  }

  public interface SsccCommitIfPossibleRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required bytes regionName = 1;
    /**
     * <code>required bytes regionName = 1;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 1;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required int64 transactionId = 2;
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    long getTransactionId();
  }
  /**
   * Protobuf type {@code SsccCommitIfPossibleRequest}
   */
  public static final class SsccCommitIfPossibleRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccCommitIfPossibleRequestOrBuilder {
    // Use SsccCommitIfPossibleRequest.newBuilder() to construct.
    private SsccCommitIfPossibleRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCommitIfPossibleRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCommitIfPossibleRequest defaultInstance;
    public static SsccCommitIfPossibleRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCommitIfPossibleRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCommitIfPossibleRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              regionName_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              transactionId_ = input.readInt64();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitIfPossibleRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitIfPossibleRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCommitIfPossibleRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccCommitIfPossibleRequest>() {
      public SsccCommitIfPossibleRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCommitIfPossibleRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCommitIfPossibleRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required bytes regionName = 1;
    public static final int REGIONNAME_FIELD_NUMBER = 1;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 1;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required bytes regionName = 1;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required int64 transactionId = 2;
    public static final int TRANSACTIONID_FIELD_NUMBER = 2;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    private void initFields() {
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      transactionId_ = 0L;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, regionName_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, transactionId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, regionName_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, transactionId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCommitIfPossibleRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitIfPossibleRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitIfPossibleRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitIfPossibleRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.transactionId_ = transactionId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest.getDefaultInstance()) return this;
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasTransactionId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required bytes regionName = 1;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 1;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required int64 transactionId = 2;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000002;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCommitIfPossibleRequest)
    }

    static {
      defaultInstance = new SsccCommitIfPossibleRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCommitIfPossibleRequest)
  }

  public interface SsccCommitIfPossibleResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional string exception = 1;
    /**
     * <code>optional string exception = 1;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 1;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 1;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 2;
    /**
     * <code>optional bool hasException = 2;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 2;</code>
     */
    boolean getHasException();

    // optional bool wasSuccessful = 3;
    /**
     * <code>optional bool wasSuccessful = 3;</code>
     */
    boolean hasWasSuccessful();
    /**
     * <code>optional bool wasSuccessful = 3;</code>
     */
    boolean getWasSuccessful();
  }
  /**
   * Protobuf type {@code SsccCommitIfPossibleResponse}
   */
  public static final class SsccCommitIfPossibleResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccCommitIfPossibleResponseOrBuilder {
    // Use SsccCommitIfPossibleResponse.newBuilder() to construct.
    private SsccCommitIfPossibleResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCommitIfPossibleResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCommitIfPossibleResponse defaultInstance;
    public static SsccCommitIfPossibleResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCommitIfPossibleResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCommitIfPossibleResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              exception_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              hasException_ = input.readBool();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              wasSuccessful_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitIfPossibleResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitIfPossibleResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCommitIfPossibleResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccCommitIfPossibleResponse>() {
      public SsccCommitIfPossibleResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCommitIfPossibleResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCommitIfPossibleResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional string exception = 1;
    public static final int EXCEPTION_FIELD_NUMBER = 1;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 1;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string exception = 1;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 1;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 2;
    public static final int HASEXCEPTION_FIELD_NUMBER = 2;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 2;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional bool hasException = 2;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    // optional bool wasSuccessful = 3;
    public static final int WASSUCCESSFUL_FIELD_NUMBER = 3;
    private boolean wasSuccessful_;
    /**
     * <code>optional bool wasSuccessful = 3;</code>
     */
    public boolean hasWasSuccessful() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool wasSuccessful = 3;</code>
     */
    public boolean getWasSuccessful() {
      return wasSuccessful_;
    }

    private void initFields() {
      exception_ = "";
      hasException_ = false;
      wasSuccessful_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBool(2, hasException_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, wasSuccessful_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(2, hasException_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, wasSuccessful_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCommitIfPossibleResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitIfPossibleResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitIfPossibleResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000002);
        wasSuccessful_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCommitIfPossibleResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.hasException_ = hasException_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.wasSuccessful_ = wasSuccessful_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.getDefaultInstance()) return this;
        if (other.hasException()) {
          bitField0_ |= 0x00000001;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        if (other.hasWasSuccessful()) {
          setWasSuccessful(other.getWasSuccessful());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional string exception = 1;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 1;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 2;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000002;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        onChanged();
        return this;
      }

      // optional bool wasSuccessful = 3;
      private boolean wasSuccessful_ ;
      /**
       * <code>optional bool wasSuccessful = 3;</code>
       */
      public boolean hasWasSuccessful() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool wasSuccessful = 3;</code>
       */
      public boolean getWasSuccessful() {
        return wasSuccessful_;
      }
      /**
       * <code>optional bool wasSuccessful = 3;</code>
       */
      public Builder setWasSuccessful(boolean value) {
        bitField0_ |= 0x00000004;
        wasSuccessful_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool wasSuccessful = 3;</code>
       */
      public Builder clearWasSuccessful() {
        bitField0_ = (bitField0_ & ~0x00000004);
        wasSuccessful_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCommitIfPossibleResponse)
    }

    static {
      defaultInstance = new SsccCommitIfPossibleResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCommitIfPossibleResponse)
  }

  public interface SsccCheckAndDeleteRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required bytes row = 4;
    /**
     * <code>required bytes row = 4;</code>
     */
    boolean hasRow();
    /**
     * <code>required bytes row = 4;</code>
     */
    com.google.protobuf.ByteString getRow();

    // required bytes family = 5;
    /**
     * <code>required bytes family = 5;</code>
     */
    boolean hasFamily();
    /**
     * <code>required bytes family = 5;</code>
     */
    com.google.protobuf.ByteString getFamily();

    // required bytes qualifier = 6;
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    boolean hasQualifier();
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    com.google.protobuf.ByteString getQualifier();

    // required bytes value = 7;
    /**
     * <code>required bytes value = 7;</code>
     */
    boolean hasValue();
    /**
     * <code>required bytes value = 7;</code>
     */
    com.google.protobuf.ByteString getValue();

    // required .MutationProto delete = 8;
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    boolean hasDelete();
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete();
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder();
  }
  /**
   * Protobuf type {@code SsccCheckAndDeleteRequest}
   */
  public static final class SsccCheckAndDeleteRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccCheckAndDeleteRequestOrBuilder {
    // Use SsccCheckAndDeleteRequest.newBuilder() to construct.
    private SsccCheckAndDeleteRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCheckAndDeleteRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCheckAndDeleteRequest defaultInstance;
    public static SsccCheckAndDeleteRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCheckAndDeleteRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCheckAndDeleteRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              bitField0_ |= 0x00000008;
              row_ = input.readBytes();
              break;
            }
            case 42: {
              bitField0_ |= 0x00000010;
              family_ = input.readBytes();
              break;
            }
            case 50: {
              bitField0_ |= 0x00000020;
              qualifier_ = input.readBytes();
              break;
            }
            case 58: {
              bitField0_ |= 0x00000040;
              value_ = input.readBytes();
              break;
            }
            case 66: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder subBuilder = null;
              if (((bitField0_ & 0x00000080) == 0x00000080)) {
                subBuilder = delete_.toBuilder();
              }
              delete_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(delete_);
                delete_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000080;
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCheckAndDeleteRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccCheckAndDeleteRequest>() {
      public SsccCheckAndDeleteRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCheckAndDeleteRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCheckAndDeleteRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required bytes row = 4;
    public static final int ROW_FIELD_NUMBER = 4;
    private com.google.protobuf.ByteString row_;
    /**
     * <code>required bytes row = 4;</code>
     */
    public boolean hasRow() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required bytes row = 4;</code>
     */
    public com.google.protobuf.ByteString getRow() {
      return row_;
    }

    // required bytes family = 5;
    public static final int FAMILY_FIELD_NUMBER = 5;
    private com.google.protobuf.ByteString family_;
    /**
     * <code>required bytes family = 5;</code>
     */
    public boolean hasFamily() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>required bytes family = 5;</code>
     */
    public com.google.protobuf.ByteString getFamily() {
      return family_;
    }

    // required bytes qualifier = 6;
    public static final int QUALIFIER_FIELD_NUMBER = 6;
    private com.google.protobuf.ByteString qualifier_;
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    public boolean hasQualifier() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    public com.google.protobuf.ByteString getQualifier() {
      return qualifier_;
    }

    // required bytes value = 7;
    public static final int VALUE_FIELD_NUMBER = 7;
    private com.google.protobuf.ByteString value_;
    /**
     * <code>required bytes value = 7;</code>
     */
    public boolean hasValue() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    /**
     * <code>required bytes value = 7;</code>
     */
    public com.google.protobuf.ByteString getValue() {
      return value_;
    }

    // required .MutationProto delete = 8;
    public static final int DELETE_FIELD_NUMBER = 8;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto delete_;
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    public boolean hasDelete() {
      return ((bitField0_ & 0x00000080) == 0x00000080);
    }
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete() {
      return delete_;
    }
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder() {
      return delete_;
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      row_ = com.google.protobuf.ByteString.EMPTY;
      family_ = com.google.protobuf.ByteString.EMPTY;
      qualifier_ = com.google.protobuf.ByteString.EMPTY;
      value_ = com.google.protobuf.ByteString.EMPTY;
      delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRow()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasFamily()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasQualifier()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasValue()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasDelete()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getDelete().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBytes(4, row_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeBytes(5, family_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeBytes(6, qualifier_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        output.writeBytes(7, value_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        output.writeMessage(8, delete_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(4, row_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(5, family_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(6, qualifier_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(7, value_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, delete_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCheckAndDeleteRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getDeleteFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        row_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000008);
        family_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000010);
        qualifier_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000020);
        value_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000040);
        if (deleteBuilder_ == null) {
          delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
        } else {
          deleteBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.row_ = row_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.family_ = family_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.qualifier_ = qualifier_;
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000040;
        }
        result.value_ = value_;
        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
          to_bitField0_ |= 0x00000080;
        }
        if (deleteBuilder_ == null) {
          result.delete_ = delete_;
        } else {
          result.delete_ = deleteBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasRow()) {
          setRow(other.getRow());
        }
        if (other.hasFamily()) {
          setFamily(other.getFamily());
        }
        if (other.hasQualifier()) {
          setQualifier(other.getQualifier());
        }
        if (other.hasValue()) {
          setValue(other.getValue());
        }
        if (other.hasDelete()) {
          mergeDelete(other.getDelete());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasRow()) {
          
          return false;
        }
        if (!hasFamily()) {
          
          return false;
        }
        if (!hasQualifier()) {
          
          return false;
        }
        if (!hasValue()) {
          
          return false;
        }
        if (!hasDelete()) {
          
          return false;
        }
        if (!getDelete().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required bytes row = 4;
      private com.google.protobuf.ByteString row_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes row = 4;</code>
       */
      public boolean hasRow() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public com.google.protobuf.ByteString getRow() {
        return row_;
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public Builder setRow(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        row_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public Builder clearRow() {
        bitField0_ = (bitField0_ & ~0x00000008);
        row_ = getDefaultInstance().getRow();
        onChanged();
        return this;
      }

      // required bytes family = 5;
      private com.google.protobuf.ByteString family_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes family = 5;</code>
       */
      public boolean hasFamily() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public com.google.protobuf.ByteString getFamily() {
        return family_;
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public Builder setFamily(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        family_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public Builder clearFamily() {
        bitField0_ = (bitField0_ & ~0x00000010);
        family_ = getDefaultInstance().getFamily();
        onChanged();
        return this;
      }

      // required bytes qualifier = 6;
      private com.google.protobuf.ByteString qualifier_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public boolean hasQualifier() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public com.google.protobuf.ByteString getQualifier() {
        return qualifier_;
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public Builder setQualifier(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        qualifier_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public Builder clearQualifier() {
        bitField0_ = (bitField0_ & ~0x00000020);
        qualifier_ = getDefaultInstance().getQualifier();
        onChanged();
        return this;
      }

      // required bytes value = 7;
      private com.google.protobuf.ByteString value_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes value = 7;</code>
       */
      public boolean hasValue() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public com.google.protobuf.ByteString getValue() {
        return value_;
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public Builder setValue(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000040;
        value_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public Builder clearValue() {
        bitField0_ = (bitField0_ & ~0x00000040);
        value_ = getDefaultInstance().getValue();
        onChanged();
        return this;
      }

      // required .MutationProto delete = 8;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> deleteBuilder_;
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public boolean hasDelete() {
        return ((bitField0_ & 0x00000080) == 0x00000080);
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete() {
        if (deleteBuilder_ == null) {
          return delete_;
        } else {
          return deleteBuilder_.getMessage();
        }
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public Builder setDelete(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          delete_ = value;
          onChanged();
        } else {
          deleteBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public Builder setDelete(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (deleteBuilder_ == null) {
          delete_ = builderForValue.build();
          onChanged();
        } else {
          deleteBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public Builder mergeDelete(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (((bitField0_ & 0x00000080) == 0x00000080) &&
              delete_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance()) {
            delete_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.newBuilder(delete_).mergeFrom(value).buildPartial();
          } else {
            delete_ = value;
          }
          onChanged();
        } else {
          deleteBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public Builder clearDelete() {
        if (deleteBuilder_ == null) {
          delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
          onChanged();
        } else {
          deleteBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder getDeleteBuilder() {
        bitField0_ |= 0x00000080;
        onChanged();
        return getDeleteFieldBuilder().getBuilder();
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder() {
        if (deleteBuilder_ != null) {
          return deleteBuilder_.getMessageOrBuilder();
        } else {
          return delete_;
        }
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
          getDeleteFieldBuilder() {
        if (deleteBuilder_ == null) {
          deleteBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder>(
                  delete_,
                  getParentForChildren(),
                  isClean());
          delete_ = null;
        }
        return deleteBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:SsccCheckAndDeleteRequest)
    }

    static {
      defaultInstance = new SsccCheckAndDeleteRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCheckAndDeleteRequest)
  }

  public interface SsccCheckAndDeleteResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required bool result = 1;
    /**
     * <code>required bool result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>required bool result = 1;</code>
     */
    boolean getResult();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccCheckAndDeleteResponse}
   */
  public static final class SsccCheckAndDeleteResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccCheckAndDeleteResponseOrBuilder {
    // Use SsccCheckAndDeleteResponse.newBuilder() to construct.
    private SsccCheckAndDeleteResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCheckAndDeleteResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCheckAndDeleteResponse defaultInstance;
    public static SsccCheckAndDeleteResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCheckAndDeleteResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCheckAndDeleteResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              result_ = input.readBool();
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCheckAndDeleteResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccCheckAndDeleteResponse>() {
      public SsccCheckAndDeleteResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCheckAndDeleteResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCheckAndDeleteResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required bool result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private boolean result_;
    /**
     * <code>required bool result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required bool result = 1;</code>
     */
    public boolean getResult() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      result_ = false;
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasResult()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBool(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCheckAndDeleteResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        result_ = false;
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.result_ = result_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          setResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasResult()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required bool result = 1;
      private boolean result_ ;
      /**
       * <code>required bool result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public boolean getResult() {
        return result_;
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public Builder setResult(boolean value) {
        bitField0_ |= 0x00000001;
        result_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public Builder clearResult() {
        bitField0_ = (bitField0_ & ~0x00000001);
        result_ = false;
        onChanged();
        return this;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCheckAndDeleteResponse)
    }

    static {
      defaultInstance = new SsccCheckAndDeleteResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCheckAndDeleteResponse)
  }

  public interface SsccCheckAndDeleteRegionTxRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 tid = 1;
    /**
     * <code>required int64 tid = 1;</code>
     */
    boolean hasTid();
    /**
     * <code>required int64 tid = 1;</code>
     */
    long getTid();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required bytes row = 4;
    /**
     * <code>required bytes row = 4;</code>
     */
    boolean hasRow();
    /**
     * <code>required bytes row = 4;</code>
     */
    com.google.protobuf.ByteString getRow();

    // required bytes family = 5;
    /**
     * <code>required bytes family = 5;</code>
     */
    boolean hasFamily();
    /**
     * <code>required bytes family = 5;</code>
     */
    com.google.protobuf.ByteString getFamily();

    // required bytes qualifier = 6;
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    boolean hasQualifier();
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    com.google.protobuf.ByteString getQualifier();

    // required bytes value = 7;
    /**
     * <code>required bytes value = 7;</code>
     */
    boolean hasValue();
    /**
     * <code>required bytes value = 7;</code>
     */
    com.google.protobuf.ByteString getValue();

    // required .MutationProto delete = 8;
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    boolean hasDelete();
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete();
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder();

    // required bool autoCommit = 9;
    /**
     * <code>required bool autoCommit = 9;</code>
     */
    boolean hasAutoCommit();
    /**
     * <code>required bool autoCommit = 9;</code>
     */
    boolean getAutoCommit();
  }
  /**
   * Protobuf type {@code SsccCheckAndDeleteRegionTxRequest}
   */
  public static final class SsccCheckAndDeleteRegionTxRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccCheckAndDeleteRegionTxRequestOrBuilder {
    // Use SsccCheckAndDeleteRegionTxRequest.newBuilder() to construct.
    private SsccCheckAndDeleteRegionTxRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCheckAndDeleteRegionTxRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCheckAndDeleteRegionTxRequest defaultInstance;
    public static SsccCheckAndDeleteRegionTxRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCheckAndDeleteRegionTxRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCheckAndDeleteRegionTxRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              tid_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              bitField0_ |= 0x00000008;
              row_ = input.readBytes();
              break;
            }
            case 42: {
              bitField0_ |= 0x00000010;
              family_ = input.readBytes();
              break;
            }
            case 50: {
              bitField0_ |= 0x00000020;
              qualifier_ = input.readBytes();
              break;
            }
            case 58: {
              bitField0_ |= 0x00000040;
              value_ = input.readBytes();
              break;
            }
            case 66: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder subBuilder = null;
              if (((bitField0_ & 0x00000080) == 0x00000080)) {
                subBuilder = delete_.toBuilder();
              }
              delete_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(delete_);
                delete_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000080;
              break;
            }
            case 72: {
              bitField0_ |= 0x00000100;
              autoCommit_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRegionTxRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRegionTxRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCheckAndDeleteRegionTxRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccCheckAndDeleteRegionTxRequest>() {
      public SsccCheckAndDeleteRegionTxRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCheckAndDeleteRegionTxRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCheckAndDeleteRegionTxRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 tid = 1;
    public static final int TID_FIELD_NUMBER = 1;
    private long tid_;
    /**
     * <code>required int64 tid = 1;</code>
     */
    public boolean hasTid() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 tid = 1;</code>
     */
    public long getTid() {
      return tid_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required bytes row = 4;
    public static final int ROW_FIELD_NUMBER = 4;
    private com.google.protobuf.ByteString row_;
    /**
     * <code>required bytes row = 4;</code>
     */
    public boolean hasRow() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required bytes row = 4;</code>
     */
    public com.google.protobuf.ByteString getRow() {
      return row_;
    }

    // required bytes family = 5;
    public static final int FAMILY_FIELD_NUMBER = 5;
    private com.google.protobuf.ByteString family_;
    /**
     * <code>required bytes family = 5;</code>
     */
    public boolean hasFamily() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>required bytes family = 5;</code>
     */
    public com.google.protobuf.ByteString getFamily() {
      return family_;
    }

    // required bytes qualifier = 6;
    public static final int QUALIFIER_FIELD_NUMBER = 6;
    private com.google.protobuf.ByteString qualifier_;
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    public boolean hasQualifier() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    public com.google.protobuf.ByteString getQualifier() {
      return qualifier_;
    }

    // required bytes value = 7;
    public static final int VALUE_FIELD_NUMBER = 7;
    private com.google.protobuf.ByteString value_;
    /**
     * <code>required bytes value = 7;</code>
     */
    public boolean hasValue() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    /**
     * <code>required bytes value = 7;</code>
     */
    public com.google.protobuf.ByteString getValue() {
      return value_;
    }

    // required .MutationProto delete = 8;
    public static final int DELETE_FIELD_NUMBER = 8;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto delete_;
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    public boolean hasDelete() {
      return ((bitField0_ & 0x00000080) == 0x00000080);
    }
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete() {
      return delete_;
    }
    /**
     * <code>required .MutationProto delete = 8;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder() {
      return delete_;
    }

    // required bool autoCommit = 9;
    public static final int AUTOCOMMIT_FIELD_NUMBER = 9;
    private boolean autoCommit_;
    /**
     * <code>required bool autoCommit = 9;</code>
     */
    public boolean hasAutoCommit() {
      return ((bitField0_ & 0x00000100) == 0x00000100);
    }
    /**
     * <code>required bool autoCommit = 9;</code>
     */
    public boolean getAutoCommit() {
      return autoCommit_;
    }

    private void initFields() {
      tid_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      row_ = com.google.protobuf.ByteString.EMPTY;
      family_ = com.google.protobuf.ByteString.EMPTY;
      qualifier_ = com.google.protobuf.ByteString.EMPTY;
      value_ = com.google.protobuf.ByteString.EMPTY;
      delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      autoCommit_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTid()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRow()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasFamily()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasQualifier()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasValue()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasDelete()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasAutoCommit()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getDelete().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, tid_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBytes(4, row_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeBytes(5, family_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeBytes(6, qualifier_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        output.writeBytes(7, value_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        output.writeMessage(8, delete_);
      }
      if (((bitField0_ & 0x00000100) == 0x00000100)) {
        output.writeBool(9, autoCommit_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, tid_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(4, row_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(5, family_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(6, qualifier_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(7, value_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, delete_);
      }
      if (((bitField0_ & 0x00000100) == 0x00000100)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(9, autoCommit_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCheckAndDeleteRegionTxRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRegionTxRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRegionTxRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getDeleteFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        tid_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        row_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000008);
        family_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000010);
        qualifier_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000020);
        value_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000040);
        if (deleteBuilder_ == null) {
          delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
        } else {
          deleteBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        autoCommit_ = false;
        bitField0_ = (bitField0_ & ~0x00000100);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRegionTxRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.tid_ = tid_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.row_ = row_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.family_ = family_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.qualifier_ = qualifier_;
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000040;
        }
        result.value_ = value_;
        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
          to_bitField0_ |= 0x00000080;
        }
        if (deleteBuilder_ == null) {
          result.delete_ = delete_;
        } else {
          result.delete_ = deleteBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
          to_bitField0_ |= 0x00000100;
        }
        result.autoCommit_ = autoCommit_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest.getDefaultInstance()) return this;
        if (other.hasTid()) {
          setTid(other.getTid());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasRow()) {
          setRow(other.getRow());
        }
        if (other.hasFamily()) {
          setFamily(other.getFamily());
        }
        if (other.hasQualifier()) {
          setQualifier(other.getQualifier());
        }
        if (other.hasValue()) {
          setValue(other.getValue());
        }
        if (other.hasDelete()) {
          mergeDelete(other.getDelete());
        }
        if (other.hasAutoCommit()) {
          setAutoCommit(other.getAutoCommit());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTid()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasRow()) {
          
          return false;
        }
        if (!hasFamily()) {
          
          return false;
        }
        if (!hasQualifier()) {
          
          return false;
        }
        if (!hasValue()) {
          
          return false;
        }
        if (!hasDelete()) {
          
          return false;
        }
        if (!hasAutoCommit()) {
          
          return false;
        }
        if (!getDelete().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 tid = 1;
      private long tid_ ;
      /**
       * <code>required int64 tid = 1;</code>
       */
      public boolean hasTid() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public long getTid() {
        return tid_;
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public Builder setTid(long value) {
        bitField0_ |= 0x00000001;
        tid_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public Builder clearTid() {
        bitField0_ = (bitField0_ & ~0x00000001);
        tid_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required bytes row = 4;
      private com.google.protobuf.ByteString row_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes row = 4;</code>
       */
      public boolean hasRow() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public com.google.protobuf.ByteString getRow() {
        return row_;
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public Builder setRow(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        row_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public Builder clearRow() {
        bitField0_ = (bitField0_ & ~0x00000008);
        row_ = getDefaultInstance().getRow();
        onChanged();
        return this;
      }

      // required bytes family = 5;
      private com.google.protobuf.ByteString family_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes family = 5;</code>
       */
      public boolean hasFamily() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public com.google.protobuf.ByteString getFamily() {
        return family_;
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public Builder setFamily(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        family_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public Builder clearFamily() {
        bitField0_ = (bitField0_ & ~0x00000010);
        family_ = getDefaultInstance().getFamily();
        onChanged();
        return this;
      }

      // required bytes qualifier = 6;
      private com.google.protobuf.ByteString qualifier_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public boolean hasQualifier() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public com.google.protobuf.ByteString getQualifier() {
        return qualifier_;
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public Builder setQualifier(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        qualifier_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public Builder clearQualifier() {
        bitField0_ = (bitField0_ & ~0x00000020);
        qualifier_ = getDefaultInstance().getQualifier();
        onChanged();
        return this;
      }

      // required bytes value = 7;
      private com.google.protobuf.ByteString value_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes value = 7;</code>
       */
      public boolean hasValue() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public com.google.protobuf.ByteString getValue() {
        return value_;
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public Builder setValue(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000040;
        value_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public Builder clearValue() {
        bitField0_ = (bitField0_ & ~0x00000040);
        value_ = getDefaultInstance().getValue();
        onChanged();
        return this;
      }

      // required .MutationProto delete = 8;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> deleteBuilder_;
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public boolean hasDelete() {
        return ((bitField0_ & 0x00000080) == 0x00000080);
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete() {
        if (deleteBuilder_ == null) {
          return delete_;
        } else {
          return deleteBuilder_.getMessage();
        }
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public Builder setDelete(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          delete_ = value;
          onChanged();
        } else {
          deleteBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public Builder setDelete(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (deleteBuilder_ == null) {
          delete_ = builderForValue.build();
          onChanged();
        } else {
          deleteBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public Builder mergeDelete(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (((bitField0_ & 0x00000080) == 0x00000080) &&
              delete_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance()) {
            delete_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.newBuilder(delete_).mergeFrom(value).buildPartial();
          } else {
            delete_ = value;
          }
          onChanged();
        } else {
          deleteBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public Builder clearDelete() {
        if (deleteBuilder_ == null) {
          delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
          onChanged();
        } else {
          deleteBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder getDeleteBuilder() {
        bitField0_ |= 0x00000080;
        onChanged();
        return getDeleteFieldBuilder().getBuilder();
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder() {
        if (deleteBuilder_ != null) {
          return deleteBuilder_.getMessageOrBuilder();
        } else {
          return delete_;
        }
      }
      /**
       * <code>required .MutationProto delete = 8;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
          getDeleteFieldBuilder() {
        if (deleteBuilder_ == null) {
          deleteBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder>(
                  delete_,
                  getParentForChildren(),
                  isClean());
          delete_ = null;
        }
        return deleteBuilder_;
      }

      // required bool autoCommit = 9;
      private boolean autoCommit_ ;
      /**
       * <code>required bool autoCommit = 9;</code>
       */
      public boolean hasAutoCommit() {
        return ((bitField0_ & 0x00000100) == 0x00000100);
      }
      /**
       * <code>required bool autoCommit = 9;</code>
       */
      public boolean getAutoCommit() {
        return autoCommit_;
      }
      /**
       * <code>required bool autoCommit = 9;</code>
       */
      public Builder setAutoCommit(boolean value) {
        bitField0_ |= 0x00000100;
        autoCommit_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool autoCommit = 9;</code>
       */
      public Builder clearAutoCommit() {
        bitField0_ = (bitField0_ & ~0x00000100);
        autoCommit_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCheckAndDeleteRegionTxRequest)
    }

    static {
      defaultInstance = new SsccCheckAndDeleteRegionTxRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCheckAndDeleteRegionTxRequest)
  }

  public interface SsccCheckAndDeleteRegionTxResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required bool result = 1;
    /**
     * <code>required bool result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>required bool result = 1;</code>
     */
    boolean getResult();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccCheckAndDeleteRegionTxResponse}
   */
  public static final class SsccCheckAndDeleteRegionTxResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccCheckAndDeleteRegionTxResponseOrBuilder {
    // Use SsccCheckAndDeleteRegionTxResponse.newBuilder() to construct.
    private SsccCheckAndDeleteRegionTxResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCheckAndDeleteRegionTxResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCheckAndDeleteRegionTxResponse defaultInstance;
    public static SsccCheckAndDeleteRegionTxResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCheckAndDeleteRegionTxResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCheckAndDeleteRegionTxResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              result_ = input.readBool();
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRegionTxResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRegionTxResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCheckAndDeleteRegionTxResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccCheckAndDeleteRegionTxResponse>() {
      public SsccCheckAndDeleteRegionTxResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCheckAndDeleteRegionTxResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCheckAndDeleteRegionTxResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required bool result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private boolean result_;
    /**
     * <code>required bool result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required bool result = 1;</code>
     */
    public boolean getResult() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      result_ = false;
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasResult()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBool(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCheckAndDeleteRegionTxResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRegionTxResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRegionTxResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        result_ = false;
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndDeleteRegionTxResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.result_ = result_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          setResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasResult()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required bool result = 1;
      private boolean result_ ;
      /**
       * <code>required bool result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public boolean getResult() {
        return result_;
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public Builder setResult(boolean value) {
        bitField0_ |= 0x00000001;
        result_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public Builder clearResult() {
        bitField0_ = (bitField0_ & ~0x00000001);
        result_ = false;
        onChanged();
        return this;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCheckAndDeleteRegionTxResponse)
    }

    static {
      defaultInstance = new SsccCheckAndDeleteRegionTxResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCheckAndDeleteRegionTxResponse)
  }

  public interface SsccCheckAndPutRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required bytes row = 4;
    /**
     * <code>required bytes row = 4;</code>
     */
    boolean hasRow();
    /**
     * <code>required bytes row = 4;</code>
     */
    com.google.protobuf.ByteString getRow();

    // required bytes family = 5;
    /**
     * <code>required bytes family = 5;</code>
     */
    boolean hasFamily();
    /**
     * <code>required bytes family = 5;</code>
     */
    com.google.protobuf.ByteString getFamily();

    // required bytes qualifier = 6;
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    boolean hasQualifier();
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    com.google.protobuf.ByteString getQualifier();

    // required bytes value = 7;
    /**
     * <code>required bytes value = 7;</code>
     */
    boolean hasValue();
    /**
     * <code>required bytes value = 7;</code>
     */
    com.google.protobuf.ByteString getValue();

    // required .MutationProto put = 8;
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    boolean hasPut();
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut();
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder();
  }
  /**
   * Protobuf type {@code SsccCheckAndPutRequest}
   */
  public static final class SsccCheckAndPutRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccCheckAndPutRequestOrBuilder {
    // Use SsccCheckAndPutRequest.newBuilder() to construct.
    private SsccCheckAndPutRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCheckAndPutRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCheckAndPutRequest defaultInstance;
    public static SsccCheckAndPutRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCheckAndPutRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCheckAndPutRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              bitField0_ |= 0x00000008;
              row_ = input.readBytes();
              break;
            }
            case 42: {
              bitField0_ |= 0x00000010;
              family_ = input.readBytes();
              break;
            }
            case 50: {
              bitField0_ |= 0x00000020;
              qualifier_ = input.readBytes();
              break;
            }
            case 58: {
              bitField0_ |= 0x00000040;
              value_ = input.readBytes();
              break;
            }
            case 66: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder subBuilder = null;
              if (((bitField0_ & 0x00000080) == 0x00000080)) {
                subBuilder = put_.toBuilder();
              }
              put_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(put_);
                put_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000080;
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCheckAndPutRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccCheckAndPutRequest>() {
      public SsccCheckAndPutRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCheckAndPutRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCheckAndPutRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required bytes row = 4;
    public static final int ROW_FIELD_NUMBER = 4;
    private com.google.protobuf.ByteString row_;
    /**
     * <code>required bytes row = 4;</code>
     */
    public boolean hasRow() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required bytes row = 4;</code>
     */
    public com.google.protobuf.ByteString getRow() {
      return row_;
    }

    // required bytes family = 5;
    public static final int FAMILY_FIELD_NUMBER = 5;
    private com.google.protobuf.ByteString family_;
    /**
     * <code>required bytes family = 5;</code>
     */
    public boolean hasFamily() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>required bytes family = 5;</code>
     */
    public com.google.protobuf.ByteString getFamily() {
      return family_;
    }

    // required bytes qualifier = 6;
    public static final int QUALIFIER_FIELD_NUMBER = 6;
    private com.google.protobuf.ByteString qualifier_;
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    public boolean hasQualifier() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    public com.google.protobuf.ByteString getQualifier() {
      return qualifier_;
    }

    // required bytes value = 7;
    public static final int VALUE_FIELD_NUMBER = 7;
    private com.google.protobuf.ByteString value_;
    /**
     * <code>required bytes value = 7;</code>
     */
    public boolean hasValue() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    /**
     * <code>required bytes value = 7;</code>
     */
    public com.google.protobuf.ByteString getValue() {
      return value_;
    }

    // required .MutationProto put = 8;
    public static final int PUT_FIELD_NUMBER = 8;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto put_;
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    public boolean hasPut() {
      return ((bitField0_ & 0x00000080) == 0x00000080);
    }
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut() {
      return put_;
    }
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder() {
      return put_;
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      row_ = com.google.protobuf.ByteString.EMPTY;
      family_ = com.google.protobuf.ByteString.EMPTY;
      qualifier_ = com.google.protobuf.ByteString.EMPTY;
      value_ = com.google.protobuf.ByteString.EMPTY;
      put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRow()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasFamily()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasQualifier()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasValue()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasPut()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getPut().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBytes(4, row_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeBytes(5, family_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeBytes(6, qualifier_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        output.writeBytes(7, value_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        output.writeMessage(8, put_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(4, row_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(5, family_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(6, qualifier_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(7, value_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, put_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCheckAndPutRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getPutFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        row_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000008);
        family_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000010);
        qualifier_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000020);
        value_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000040);
        if (putBuilder_ == null) {
          put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
        } else {
          putBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.row_ = row_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.family_ = family_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.qualifier_ = qualifier_;
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000040;
        }
        result.value_ = value_;
        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
          to_bitField0_ |= 0x00000080;
        }
        if (putBuilder_ == null) {
          result.put_ = put_;
        } else {
          result.put_ = putBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasRow()) {
          setRow(other.getRow());
        }
        if (other.hasFamily()) {
          setFamily(other.getFamily());
        }
        if (other.hasQualifier()) {
          setQualifier(other.getQualifier());
        }
        if (other.hasValue()) {
          setValue(other.getValue());
        }
        if (other.hasPut()) {
          mergePut(other.getPut());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasRow()) {
          
          return false;
        }
        if (!hasFamily()) {
          
          return false;
        }
        if (!hasQualifier()) {
          
          return false;
        }
        if (!hasValue()) {
          
          return false;
        }
        if (!hasPut()) {
          
          return false;
        }
        if (!getPut().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required bytes row = 4;
      private com.google.protobuf.ByteString row_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes row = 4;</code>
       */
      public boolean hasRow() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public com.google.protobuf.ByteString getRow() {
        return row_;
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public Builder setRow(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        row_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public Builder clearRow() {
        bitField0_ = (bitField0_ & ~0x00000008);
        row_ = getDefaultInstance().getRow();
        onChanged();
        return this;
      }

      // required bytes family = 5;
      private com.google.protobuf.ByteString family_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes family = 5;</code>
       */
      public boolean hasFamily() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public com.google.protobuf.ByteString getFamily() {
        return family_;
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public Builder setFamily(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        family_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public Builder clearFamily() {
        bitField0_ = (bitField0_ & ~0x00000010);
        family_ = getDefaultInstance().getFamily();
        onChanged();
        return this;
      }

      // required bytes qualifier = 6;
      private com.google.protobuf.ByteString qualifier_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public boolean hasQualifier() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public com.google.protobuf.ByteString getQualifier() {
        return qualifier_;
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public Builder setQualifier(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        qualifier_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public Builder clearQualifier() {
        bitField0_ = (bitField0_ & ~0x00000020);
        qualifier_ = getDefaultInstance().getQualifier();
        onChanged();
        return this;
      }

      // required bytes value = 7;
      private com.google.protobuf.ByteString value_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes value = 7;</code>
       */
      public boolean hasValue() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public com.google.protobuf.ByteString getValue() {
        return value_;
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public Builder setValue(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000040;
        value_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public Builder clearValue() {
        bitField0_ = (bitField0_ & ~0x00000040);
        value_ = getDefaultInstance().getValue();
        onChanged();
        return this;
      }

      // required .MutationProto put = 8;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> putBuilder_;
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public boolean hasPut() {
        return ((bitField0_ & 0x00000080) == 0x00000080);
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut() {
        if (putBuilder_ == null) {
          return put_;
        } else {
          return putBuilder_.getMessage();
        }
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public Builder setPut(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          put_ = value;
          onChanged();
        } else {
          putBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public Builder setPut(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (putBuilder_ == null) {
          put_ = builderForValue.build();
          onChanged();
        } else {
          putBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public Builder mergePut(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (((bitField0_ & 0x00000080) == 0x00000080) &&
              put_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance()) {
            put_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.newBuilder(put_).mergeFrom(value).buildPartial();
          } else {
            put_ = value;
          }
          onChanged();
        } else {
          putBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public Builder clearPut() {
        if (putBuilder_ == null) {
          put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
          onChanged();
        } else {
          putBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder getPutBuilder() {
        bitField0_ |= 0x00000080;
        onChanged();
        return getPutFieldBuilder().getBuilder();
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder() {
        if (putBuilder_ != null) {
          return putBuilder_.getMessageOrBuilder();
        } else {
          return put_;
        }
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
          getPutFieldBuilder() {
        if (putBuilder_ == null) {
          putBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder>(
                  put_,
                  getParentForChildren(),
                  isClean());
          put_ = null;
        }
        return putBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:SsccCheckAndPutRequest)
    }

    static {
      defaultInstance = new SsccCheckAndPutRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCheckAndPutRequest)
  }

  public interface SsccCheckAndPutResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required bool result = 1;
    /**
     * <code>required bool result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>required bool result = 1;</code>
     */
    boolean getResult();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccCheckAndPutResponse}
   */
  public static final class SsccCheckAndPutResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccCheckAndPutResponseOrBuilder {
    // Use SsccCheckAndPutResponse.newBuilder() to construct.
    private SsccCheckAndPutResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCheckAndPutResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCheckAndPutResponse defaultInstance;
    public static SsccCheckAndPutResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCheckAndPutResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCheckAndPutResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              result_ = input.readBool();
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCheckAndPutResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccCheckAndPutResponse>() {
      public SsccCheckAndPutResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCheckAndPutResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCheckAndPutResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required bool result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private boolean result_;
    /**
     * <code>required bool result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required bool result = 1;</code>
     */
    public boolean getResult() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      result_ = false;
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasResult()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBool(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCheckAndPutResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        result_ = false;
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.result_ = result_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          setResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasResult()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required bool result = 1;
      private boolean result_ ;
      /**
       * <code>required bool result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public boolean getResult() {
        return result_;
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public Builder setResult(boolean value) {
        bitField0_ |= 0x00000001;
        result_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public Builder clearResult() {
        bitField0_ = (bitField0_ & ~0x00000001);
        result_ = false;
        onChanged();
        return this;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCheckAndPutResponse)
    }

    static {
      defaultInstance = new SsccCheckAndPutResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCheckAndPutResponse)
  }

  public interface SsccCheckAndPutRegionTxRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 tid = 1;
    /**
     * <code>required int64 tid = 1;</code>
     */
    boolean hasTid();
    /**
     * <code>required int64 tid = 1;</code>
     */
    long getTid();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required bytes row = 4;
    /**
     * <code>required bytes row = 4;</code>
     */
    boolean hasRow();
    /**
     * <code>required bytes row = 4;</code>
     */
    com.google.protobuf.ByteString getRow();

    // required bytes family = 5;
    /**
     * <code>required bytes family = 5;</code>
     */
    boolean hasFamily();
    /**
     * <code>required bytes family = 5;</code>
     */
    com.google.protobuf.ByteString getFamily();

    // required bytes qualifier = 6;
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    boolean hasQualifier();
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    com.google.protobuf.ByteString getQualifier();

    // required bytes value = 7;
    /**
     * <code>required bytes value = 7;</code>
     */
    boolean hasValue();
    /**
     * <code>required bytes value = 7;</code>
     */
    com.google.protobuf.ByteString getValue();

    // required .MutationProto put = 8;
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    boolean hasPut();
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut();
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder();

    // required bool autoCommit = 9;
    /**
     * <code>required bool autoCommit = 9;</code>
     */
    boolean hasAutoCommit();
    /**
     * <code>required bool autoCommit = 9;</code>
     */
    boolean getAutoCommit();
  }
  /**
   * Protobuf type {@code SsccCheckAndPutRegionTxRequest}
   */
  public static final class SsccCheckAndPutRegionTxRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccCheckAndPutRegionTxRequestOrBuilder {
    // Use SsccCheckAndPutRegionTxRequest.newBuilder() to construct.
    private SsccCheckAndPutRegionTxRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCheckAndPutRegionTxRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCheckAndPutRegionTxRequest defaultInstance;
    public static SsccCheckAndPutRegionTxRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCheckAndPutRegionTxRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCheckAndPutRegionTxRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              tid_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              bitField0_ |= 0x00000008;
              row_ = input.readBytes();
              break;
            }
            case 42: {
              bitField0_ |= 0x00000010;
              family_ = input.readBytes();
              break;
            }
            case 50: {
              bitField0_ |= 0x00000020;
              qualifier_ = input.readBytes();
              break;
            }
            case 58: {
              bitField0_ |= 0x00000040;
              value_ = input.readBytes();
              break;
            }
            case 66: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder subBuilder = null;
              if (((bitField0_ & 0x00000080) == 0x00000080)) {
                subBuilder = put_.toBuilder();
              }
              put_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(put_);
                put_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000080;
              break;
            }
            case 72: {
              bitField0_ |= 0x00000100;
              autoCommit_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRegionTxRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRegionTxRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCheckAndPutRegionTxRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccCheckAndPutRegionTxRequest>() {
      public SsccCheckAndPutRegionTxRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCheckAndPutRegionTxRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCheckAndPutRegionTxRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 tid = 1;
    public static final int TID_FIELD_NUMBER = 1;
    private long tid_;
    /**
     * <code>required int64 tid = 1;</code>
     */
    public boolean hasTid() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 tid = 1;</code>
     */
    public long getTid() {
      return tid_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required bytes row = 4;
    public static final int ROW_FIELD_NUMBER = 4;
    private com.google.protobuf.ByteString row_;
    /**
     * <code>required bytes row = 4;</code>
     */
    public boolean hasRow() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required bytes row = 4;</code>
     */
    public com.google.protobuf.ByteString getRow() {
      return row_;
    }

    // required bytes family = 5;
    public static final int FAMILY_FIELD_NUMBER = 5;
    private com.google.protobuf.ByteString family_;
    /**
     * <code>required bytes family = 5;</code>
     */
    public boolean hasFamily() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>required bytes family = 5;</code>
     */
    public com.google.protobuf.ByteString getFamily() {
      return family_;
    }

    // required bytes qualifier = 6;
    public static final int QUALIFIER_FIELD_NUMBER = 6;
    private com.google.protobuf.ByteString qualifier_;
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    public boolean hasQualifier() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>required bytes qualifier = 6;</code>
     */
    public com.google.protobuf.ByteString getQualifier() {
      return qualifier_;
    }

    // required bytes value = 7;
    public static final int VALUE_FIELD_NUMBER = 7;
    private com.google.protobuf.ByteString value_;
    /**
     * <code>required bytes value = 7;</code>
     */
    public boolean hasValue() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    /**
     * <code>required bytes value = 7;</code>
     */
    public com.google.protobuf.ByteString getValue() {
      return value_;
    }

    // required .MutationProto put = 8;
    public static final int PUT_FIELD_NUMBER = 8;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto put_;
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    public boolean hasPut() {
      return ((bitField0_ & 0x00000080) == 0x00000080);
    }
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut() {
      return put_;
    }
    /**
     * <code>required .MutationProto put = 8;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder() {
      return put_;
    }

    // required bool autoCommit = 9;
    public static final int AUTOCOMMIT_FIELD_NUMBER = 9;
    private boolean autoCommit_;
    /**
     * <code>required bool autoCommit = 9;</code>
     */
    public boolean hasAutoCommit() {
      return ((bitField0_ & 0x00000100) == 0x00000100);
    }
    /**
     * <code>required bool autoCommit = 9;</code>
     */
    public boolean getAutoCommit() {
      return autoCommit_;
    }

    private void initFields() {
      tid_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      row_ = com.google.protobuf.ByteString.EMPTY;
      family_ = com.google.protobuf.ByteString.EMPTY;
      qualifier_ = com.google.protobuf.ByteString.EMPTY;
      value_ = com.google.protobuf.ByteString.EMPTY;
      put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      autoCommit_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTid()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRow()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasFamily()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasQualifier()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasValue()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasPut()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasAutoCommit()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getPut().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, tid_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBytes(4, row_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeBytes(5, family_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeBytes(6, qualifier_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        output.writeBytes(7, value_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        output.writeMessage(8, put_);
      }
      if (((bitField0_ & 0x00000100) == 0x00000100)) {
        output.writeBool(9, autoCommit_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, tid_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(4, row_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(5, family_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(6, qualifier_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(7, value_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, put_);
      }
      if (((bitField0_ & 0x00000100) == 0x00000100)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(9, autoCommit_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCheckAndPutRegionTxRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRegionTxRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRegionTxRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getPutFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        tid_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        row_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000008);
        family_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000010);
        qualifier_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000020);
        value_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000040);
        if (putBuilder_ == null) {
          put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
        } else {
          putBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        autoCommit_ = false;
        bitField0_ = (bitField0_ & ~0x00000100);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRegionTxRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.tid_ = tid_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.row_ = row_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.family_ = family_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.qualifier_ = qualifier_;
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000040;
        }
        result.value_ = value_;
        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
          to_bitField0_ |= 0x00000080;
        }
        if (putBuilder_ == null) {
          result.put_ = put_;
        } else {
          result.put_ = putBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
          to_bitField0_ |= 0x00000100;
        }
        result.autoCommit_ = autoCommit_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest.getDefaultInstance()) return this;
        if (other.hasTid()) {
          setTid(other.getTid());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasRow()) {
          setRow(other.getRow());
        }
        if (other.hasFamily()) {
          setFamily(other.getFamily());
        }
        if (other.hasQualifier()) {
          setQualifier(other.getQualifier());
        }
        if (other.hasValue()) {
          setValue(other.getValue());
        }
        if (other.hasPut()) {
          mergePut(other.getPut());
        }
        if (other.hasAutoCommit()) {
          setAutoCommit(other.getAutoCommit());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTid()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasRow()) {
          
          return false;
        }
        if (!hasFamily()) {
          
          return false;
        }
        if (!hasQualifier()) {
          
          return false;
        }
        if (!hasValue()) {
          
          return false;
        }
        if (!hasPut()) {
          
          return false;
        }
        if (!hasAutoCommit()) {
          
          return false;
        }
        if (!getPut().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 tid = 1;
      private long tid_ ;
      /**
       * <code>required int64 tid = 1;</code>
       */
      public boolean hasTid() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public long getTid() {
        return tid_;
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public Builder setTid(long value) {
        bitField0_ |= 0x00000001;
        tid_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public Builder clearTid() {
        bitField0_ = (bitField0_ & ~0x00000001);
        tid_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required bytes row = 4;
      private com.google.protobuf.ByteString row_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes row = 4;</code>
       */
      public boolean hasRow() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public com.google.protobuf.ByteString getRow() {
        return row_;
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public Builder setRow(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        row_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes row = 4;</code>
       */
      public Builder clearRow() {
        bitField0_ = (bitField0_ & ~0x00000008);
        row_ = getDefaultInstance().getRow();
        onChanged();
        return this;
      }

      // required bytes family = 5;
      private com.google.protobuf.ByteString family_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes family = 5;</code>
       */
      public boolean hasFamily() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public com.google.protobuf.ByteString getFamily() {
        return family_;
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public Builder setFamily(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        family_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes family = 5;</code>
       */
      public Builder clearFamily() {
        bitField0_ = (bitField0_ & ~0x00000010);
        family_ = getDefaultInstance().getFamily();
        onChanged();
        return this;
      }

      // required bytes qualifier = 6;
      private com.google.protobuf.ByteString qualifier_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public boolean hasQualifier() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public com.google.protobuf.ByteString getQualifier() {
        return qualifier_;
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public Builder setQualifier(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        qualifier_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes qualifier = 6;</code>
       */
      public Builder clearQualifier() {
        bitField0_ = (bitField0_ & ~0x00000020);
        qualifier_ = getDefaultInstance().getQualifier();
        onChanged();
        return this;
      }

      // required bytes value = 7;
      private com.google.protobuf.ByteString value_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes value = 7;</code>
       */
      public boolean hasValue() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public com.google.protobuf.ByteString getValue() {
        return value_;
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public Builder setValue(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000040;
        value_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes value = 7;</code>
       */
      public Builder clearValue() {
        bitField0_ = (bitField0_ & ~0x00000040);
        value_ = getDefaultInstance().getValue();
        onChanged();
        return this;
      }

      // required .MutationProto put = 8;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> putBuilder_;
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public boolean hasPut() {
        return ((bitField0_ & 0x00000080) == 0x00000080);
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut() {
        if (putBuilder_ == null) {
          return put_;
        } else {
          return putBuilder_.getMessage();
        }
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public Builder setPut(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          put_ = value;
          onChanged();
        } else {
          putBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public Builder setPut(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (putBuilder_ == null) {
          put_ = builderForValue.build();
          onChanged();
        } else {
          putBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public Builder mergePut(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (((bitField0_ & 0x00000080) == 0x00000080) &&
              put_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance()) {
            put_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.newBuilder(put_).mergeFrom(value).buildPartial();
          } else {
            put_ = value;
          }
          onChanged();
        } else {
          putBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public Builder clearPut() {
        if (putBuilder_ == null) {
          put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
          onChanged();
        } else {
          putBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder getPutBuilder() {
        bitField0_ |= 0x00000080;
        onChanged();
        return getPutFieldBuilder().getBuilder();
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder() {
        if (putBuilder_ != null) {
          return putBuilder_.getMessageOrBuilder();
        } else {
          return put_;
        }
      }
      /**
       * <code>required .MutationProto put = 8;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
          getPutFieldBuilder() {
        if (putBuilder_ == null) {
          putBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder>(
                  put_,
                  getParentForChildren(),
                  isClean());
          put_ = null;
        }
        return putBuilder_;
      }

      // required bool autoCommit = 9;
      private boolean autoCommit_ ;
      /**
       * <code>required bool autoCommit = 9;</code>
       */
      public boolean hasAutoCommit() {
        return ((bitField0_ & 0x00000100) == 0x00000100);
      }
      /**
       * <code>required bool autoCommit = 9;</code>
       */
      public boolean getAutoCommit() {
        return autoCommit_;
      }
      /**
       * <code>required bool autoCommit = 9;</code>
       */
      public Builder setAutoCommit(boolean value) {
        bitField0_ |= 0x00000100;
        autoCommit_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool autoCommit = 9;</code>
       */
      public Builder clearAutoCommit() {
        bitField0_ = (bitField0_ & ~0x00000100);
        autoCommit_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCheckAndPutRegionTxRequest)
    }

    static {
      defaultInstance = new SsccCheckAndPutRegionTxRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCheckAndPutRegionTxRequest)
  }

  public interface SsccCheckAndPutRegionTxResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required bool result = 1;
    /**
     * <code>required bool result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>required bool result = 1;</code>
     */
    boolean getResult();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccCheckAndPutRegionTxResponse}
   */
  public static final class SsccCheckAndPutRegionTxResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccCheckAndPutRegionTxResponseOrBuilder {
    // Use SsccCheckAndPutRegionTxResponse.newBuilder() to construct.
    private SsccCheckAndPutRegionTxResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCheckAndPutRegionTxResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCheckAndPutRegionTxResponse defaultInstance;
    public static SsccCheckAndPutRegionTxResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCheckAndPutRegionTxResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCheckAndPutRegionTxResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              result_ = input.readBool();
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRegionTxResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRegionTxResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCheckAndPutRegionTxResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccCheckAndPutRegionTxResponse>() {
      public SsccCheckAndPutRegionTxResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCheckAndPutRegionTxResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCheckAndPutRegionTxResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required bool result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private boolean result_;
    /**
     * <code>required bool result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required bool result = 1;</code>
     */
    public boolean getResult() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      result_ = false;
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasResult()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBool(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCheckAndPutRegionTxResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRegionTxResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRegionTxResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        result_ = false;
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCheckAndPutRegionTxResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.result_ = result_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          setResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasResult()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required bool result = 1;
      private boolean result_ ;
      /**
       * <code>required bool result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public boolean getResult() {
        return result_;
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public Builder setResult(boolean value) {
        bitField0_ |= 0x00000001;
        result_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool result = 1;</code>
       */
      public Builder clearResult() {
        bitField0_ = (bitField0_ & ~0x00000001);
        result_ = false;
        onChanged();
        return this;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCheckAndPutRegionTxResponse)
    }

    static {
      defaultInstance = new SsccCheckAndPutRegionTxResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCheckAndPutRegionTxResponse)
  }

  public interface SsccCloseScannerRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required bytes regionName = 2;
    /**
     * <code>required bytes regionName = 2;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 2;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required int64 scannerId = 3;
    /**
     * <code>required int64 scannerId = 3;</code>
     */
    boolean hasScannerId();
    /**
     * <code>required int64 scannerId = 3;</code>
     */
    long getScannerId();
  }
  /**
   * Protobuf type {@code SsccCloseScannerRequest}
   */
  public static final class SsccCloseScannerRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccCloseScannerRequestOrBuilder {
    // Use SsccCloseScannerRequest.newBuilder() to construct.
    private SsccCloseScannerRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCloseScannerRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCloseScannerRequest defaultInstance;
    public static SsccCloseScannerRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCloseScannerRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCloseScannerRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              regionName_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              scannerId_ = input.readInt64();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCloseScannerRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCloseScannerRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCloseScannerRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccCloseScannerRequest>() {
      public SsccCloseScannerRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCloseScannerRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCloseScannerRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required bytes regionName = 2;
    public static final int REGIONNAME_FIELD_NUMBER = 2;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 2;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required bytes regionName = 2;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required int64 scannerId = 3;
    public static final int SCANNERID_FIELD_NUMBER = 3;
    private long scannerId_;
    /**
     * <code>required int64 scannerId = 3;</code>
     */
    public boolean hasScannerId() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required int64 scannerId = 3;</code>
     */
    public long getScannerId() {
      return scannerId_;
    }

    private void initFields() {
      transactionId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      scannerId_ = 0L;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasScannerId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, regionName_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt64(3, scannerId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, regionName_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, scannerId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCloseScannerRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCloseScannerRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCloseScannerRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000002);
        scannerId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCloseScannerRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.scannerId_ = scannerId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasScannerId()) {
          setScannerId(other.getScannerId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasScannerId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 2;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 2;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required bytes regionName = 2;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 2;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 2;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required int64 scannerId = 3;
      private long scannerId_ ;
      /**
       * <code>required int64 scannerId = 3;</code>
       */
      public boolean hasScannerId() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required int64 scannerId = 3;</code>
       */
      public long getScannerId() {
        return scannerId_;
      }
      /**
       * <code>required int64 scannerId = 3;</code>
       */
      public Builder setScannerId(long value) {
        bitField0_ |= 0x00000004;
        scannerId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 scannerId = 3;</code>
       */
      public Builder clearScannerId() {
        bitField0_ = (bitField0_ & ~0x00000004);
        scannerId_ = 0L;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCloseScannerRequest)
    }

    static {
      defaultInstance = new SsccCloseScannerRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCloseScannerRequest)
  }

  public interface SsccCloseScannerResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional string exception = 1;
    /**
     * <code>optional string exception = 1;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 1;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 1;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 2;
    /**
     * <code>optional bool hasException = 2;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 2;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccCloseScannerResponse}
   */
  public static final class SsccCloseScannerResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccCloseScannerResponseOrBuilder {
    // Use SsccCloseScannerResponse.newBuilder() to construct.
    private SsccCloseScannerResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccCloseScannerResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccCloseScannerResponse defaultInstance;
    public static SsccCloseScannerResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccCloseScannerResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccCloseScannerResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              exception_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCloseScannerResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCloseScannerResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccCloseScannerResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccCloseScannerResponse>() {
      public SsccCloseScannerResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccCloseScannerResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccCloseScannerResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional string exception = 1;
    public static final int EXCEPTION_FIELD_NUMBER = 1;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 1;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string exception = 1;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 1;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 2;
    public static final int HASEXCEPTION_FIELD_NUMBER = 2;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 2;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional bool hasException = 2;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBool(2, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(2, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccCloseScannerResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCloseScannerResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCloseScannerResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccCloseScannerResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.getDefaultInstance()) return this;
        if (other.hasException()) {
          bitField0_ |= 0x00000001;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional string exception = 1;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 1;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 1;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 2;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000002;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 2;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccCloseScannerResponse)
    }

    static {
      defaultInstance = new SsccCloseScannerResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccCloseScannerResponse)
  }

  public interface SsccDeleteMultipleTransactionalRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // repeated .MutationProto delete = 4;
    /**
     * <code>repeated .MutationProto delete = 4;</code>
     */
    java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> 
        getDeleteList();
    /**
     * <code>repeated .MutationProto delete = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete(int index);
    /**
     * <code>repeated .MutationProto delete = 4;</code>
     */
    int getDeleteCount();
    /**
     * <code>repeated .MutationProto delete = 4;</code>
     */
    java.util.List<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
        getDeleteOrBuilderList();
    /**
     * <code>repeated .MutationProto delete = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code SsccDeleteMultipleTransactionalRequest}
   */
  public static final class SsccDeleteMultipleTransactionalRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccDeleteMultipleTransactionalRequestOrBuilder {
    // Use SsccDeleteMultipleTransactionalRequest.newBuilder() to construct.
    private SsccDeleteMultipleTransactionalRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccDeleteMultipleTransactionalRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccDeleteMultipleTransactionalRequest defaultInstance;
    public static SsccDeleteMultipleTransactionalRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccDeleteMultipleTransactionalRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccDeleteMultipleTransactionalRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
                delete_ = new java.util.ArrayList<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto>();
                mutable_bitField0_ |= 0x00000008;
              }
              delete_.add(input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
          delete_ = java.util.Collections.unmodifiableList(delete_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteMultipleTransactionalRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteMultipleTransactionalRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccDeleteMultipleTransactionalRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccDeleteMultipleTransactionalRequest>() {
      public SsccDeleteMultipleTransactionalRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccDeleteMultipleTransactionalRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccDeleteMultipleTransactionalRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // repeated .MutationProto delete = 4;
    public static final int DELETE_FIELD_NUMBER = 4;
    private java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> delete_;
    /**
     * <code>repeated .MutationProto delete = 4;</code>
     */
    public java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> getDeleteList() {
      return delete_;
    }
    /**
     * <code>repeated .MutationProto delete = 4;</code>
     */
    public java.util.List<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
        getDeleteOrBuilderList() {
      return delete_;
    }
    /**
     * <code>repeated .MutationProto delete = 4;</code>
     */
    public int getDeleteCount() {
      return delete_.size();
    }
    /**
     * <code>repeated .MutationProto delete = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete(int index) {
      return delete_.get(index);
    }
    /**
     * <code>repeated .MutationProto delete = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder(
        int index) {
      return delete_.get(index);
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      delete_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      for (int i = 0; i < getDeleteCount(); i++) {
        if (!getDelete(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      for (int i = 0; i < delete_.size(); i++) {
        output.writeMessage(4, delete_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      for (int i = 0; i < delete_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, delete_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccDeleteMultipleTransactionalRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteMultipleTransactionalRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteMultipleTransactionalRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getDeleteFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (deleteBuilder_ == null) {
          delete_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000008);
        } else {
          deleteBuilder_.clear();
        }
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteMultipleTransactionalRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (deleteBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008)) {
            delete_ = java.util.Collections.unmodifiableList(delete_);
            bitField0_ = (bitField0_ & ~0x00000008);
          }
          result.delete_ = delete_;
        } else {
          result.delete_ = deleteBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (deleteBuilder_ == null) {
          if (!other.delete_.isEmpty()) {
            if (delete_.isEmpty()) {
              delete_ = other.delete_;
              bitField0_ = (bitField0_ & ~0x00000008);
            } else {
              ensureDeleteIsMutable();
              delete_.addAll(other.delete_);
            }
            onChanged();
          }
        } else {
          if (!other.delete_.isEmpty()) {
            if (deleteBuilder_.isEmpty()) {
              deleteBuilder_.dispose();
              deleteBuilder_ = null;
              delete_ = other.delete_;
              bitField0_ = (bitField0_ & ~0x00000008);
              deleteBuilder_ = 
                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getDeleteFieldBuilder() : null;
            } else {
              deleteBuilder_.addAllMessages(other.delete_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        for (int i = 0; i < getDeleteCount(); i++) {
          if (!getDelete(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // repeated .MutationProto delete = 4;
      private java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> delete_ =
        java.util.Collections.emptyList();
      private void ensureDeleteIsMutable() {
        if (!((bitField0_ & 0x00000008) == 0x00000008)) {
          delete_ = new java.util.ArrayList<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto>(delete_);
          bitField0_ |= 0x00000008;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> deleteBuilder_;

      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> getDeleteList() {
        if (deleteBuilder_ == null) {
          return java.util.Collections.unmodifiableList(delete_);
        } else {
          return deleteBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public int getDeleteCount() {
        if (deleteBuilder_ == null) {
          return delete_.size();
        } else {
          return deleteBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete(int index) {
        if (deleteBuilder_ == null) {
          return delete_.get(index);
        } else {
          return deleteBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public Builder setDelete(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDeleteIsMutable();
          delete_.set(index, value);
          onChanged();
        } else {
          deleteBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public Builder setDelete(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (deleteBuilder_ == null) {
          ensureDeleteIsMutable();
          delete_.set(index, builderForValue.build());
          onChanged();
        } else {
          deleteBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public Builder addDelete(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDeleteIsMutable();
          delete_.add(value);
          onChanged();
        } else {
          deleteBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public Builder addDelete(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDeleteIsMutable();
          delete_.add(index, value);
          onChanged();
        } else {
          deleteBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public Builder addDelete(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (deleteBuilder_ == null) {
          ensureDeleteIsMutable();
          delete_.add(builderForValue.build());
          onChanged();
        } else {
          deleteBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public Builder addDelete(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (deleteBuilder_ == null) {
          ensureDeleteIsMutable();
          delete_.add(index, builderForValue.build());
          onChanged();
        } else {
          deleteBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public Builder addAllDelete(
          java.lang.Iterable<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> values) {
        if (deleteBuilder_ == null) {
          ensureDeleteIsMutable();
          super.addAll(values, delete_);
          onChanged();
        } else {
          deleteBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public Builder clearDelete() {
        if (deleteBuilder_ == null) {
          delete_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000008);
          onChanged();
        } else {
          deleteBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public Builder removeDelete(int index) {
        if (deleteBuilder_ == null) {
          ensureDeleteIsMutable();
          delete_.remove(index);
          onChanged();
        } else {
          deleteBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder getDeleteBuilder(
          int index) {
        return getDeleteFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder(
          int index) {
        if (deleteBuilder_ == null) {
          return delete_.get(index);  } else {
          return deleteBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public java.util.List<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
           getDeleteOrBuilderList() {
        if (deleteBuilder_ != null) {
          return deleteBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(delete_);
        }
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder addDeleteBuilder() {
        return getDeleteFieldBuilder().addBuilder(
            org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance());
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder addDeleteBuilder(
          int index) {
        return getDeleteFieldBuilder().addBuilder(
            index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance());
      }
      /**
       * <code>repeated .MutationProto delete = 4;</code>
       */
      public java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder> 
           getDeleteBuilderList() {
        return getDeleteFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
          getDeleteFieldBuilder() {
        if (deleteBuilder_ == null) {
          deleteBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder>(
                  delete_,
                  ((bitField0_ & 0x00000008) == 0x00000008),
                  getParentForChildren(),
                  isClean());
          delete_ = null;
        }
        return deleteBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:SsccDeleteMultipleTransactionalRequest)
    }

    static {
      defaultInstance = new SsccDeleteMultipleTransactionalRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccDeleteMultipleTransactionalRequest)
  }

  public interface SsccDeleteMultipleTransactionalResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional .Result result = 1;
    /**
     * <code>optional .Result result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();

    // optional int32 status = 4;
    /**
     * <code>optional int32 status = 4;</code>
     */
    boolean hasStatus();
    /**
     * <code>optional int32 status = 4;</code>
     */
    int getStatus();
  }
  /**
   * Protobuf type {@code SsccDeleteMultipleTransactionalResponse}
   */
  public static final class SsccDeleteMultipleTransactionalResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccDeleteMultipleTransactionalResponseOrBuilder {
    // Use SsccDeleteMultipleTransactionalResponse.newBuilder() to construct.
    private SsccDeleteMultipleTransactionalResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccDeleteMultipleTransactionalResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccDeleteMultipleTransactionalResponse defaultInstance;
    public static SsccDeleteMultipleTransactionalResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccDeleteMultipleTransactionalResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccDeleteMultipleTransactionalResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = result_.toBuilder();
              }
              result_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(result_);
                result_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              status_ = input.readInt32();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteMultipleTransactionalResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteMultipleTransactionalResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccDeleteMultipleTransactionalResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccDeleteMultipleTransactionalResponse>() {
      public SsccDeleteMultipleTransactionalResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccDeleteMultipleTransactionalResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccDeleteMultipleTransactionalResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional .Result result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_;
    /**
     * <code>optional .Result result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
      return result_;
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    // optional int32 status = 4;
    public static final int STATUS_FIELD_NUMBER = 4;
    private int status_;
    /**
     * <code>optional int32 status = 4;</code>
     */
    public boolean hasStatus() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int32 status = 4;</code>
     */
    public int getStatus() {
      return status_;
    }

    private void initFields() {
      result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      exception_ = "";
      hasException_ = false;
      status_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt32(4, status_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, status_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccDeleteMultipleTransactionalResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteMultipleTransactionalResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteMultipleTransactionalResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getResultFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteMultipleTransactionalResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (resultBuilder_ == null) {
          result.result_ = result_;
        } else {
          result.result_ = resultBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.status_ = status_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          mergeResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional .Result result = 1;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> resultBuilder_;
      /**
       * <code>optional .Result result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
        if (resultBuilder_ == null) {
          return result_;
        } else {
          return resultBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          result_ = value;
          onChanged();
        } else {
          resultBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder builderForValue) {
        if (resultBuilder_ == null) {
          result_ = builderForValue.build();
          onChanged();
        } else {
          resultBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder mergeResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              result_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance()) {
            result_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.newBuilder(result_).mergeFrom(value).buildPartial();
          } else {
            result_ = value;
          }
          onChanged();
        } else {
          resultBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder clearResult() {
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
          onChanged();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder getResultBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getResultFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
        if (resultBuilder_ != null) {
          return resultBuilder_.getMessageOrBuilder();
        } else {
          return result_;
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
          getResultFieldBuilder() {
        if (resultBuilder_ == null) {
          resultBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder>(
                  result_,
                  getParentForChildren(),
                  isClean());
          result_ = null;
        }
        return resultBuilder_;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // optional int32 status = 4;
      private int status_ ;
      /**
       * <code>optional int32 status = 4;</code>
       */
      public boolean hasStatus() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public int getStatus() {
        return status_;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder setStatus(int value) {
        bitField0_ |= 0x00000008;
        status_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000008);
        status_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccDeleteMultipleTransactionalResponse)
    }

    static {
      defaultInstance = new SsccDeleteMultipleTransactionalResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccDeleteMultipleTransactionalResponse)
  }

  public interface SsccDeleteRegionTxRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 tid = 1;
    /**
     * <code>required int64 tid = 1;</code>
     */
    boolean hasTid();
    /**
     * <code>required int64 tid = 1;</code>
     */
    long getTid();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required .MutationProto delete = 4;
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    boolean hasDelete();
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete();
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder();

    // required bool autoCommit = 5;
    /**
     * <code>required bool autoCommit = 5;</code>
     */
    boolean hasAutoCommit();
    /**
     * <code>required bool autoCommit = 5;</code>
     */
    boolean getAutoCommit();
  }
  /**
   * Protobuf type {@code SsccDeleteRegionTxRequest}
   */
  public static final class SsccDeleteRegionTxRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccDeleteRegionTxRequestOrBuilder {
    // Use SsccDeleteRegionTxRequest.newBuilder() to construct.
    private SsccDeleteRegionTxRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccDeleteRegionTxRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccDeleteRegionTxRequest defaultInstance;
    public static SsccDeleteRegionTxRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccDeleteRegionTxRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccDeleteRegionTxRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              tid_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder subBuilder = null;
              if (((bitField0_ & 0x00000008) == 0x00000008)) {
                subBuilder = delete_.toBuilder();
              }
              delete_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(delete_);
                delete_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000008;
              break;
            }
            case 40: {
              bitField0_ |= 0x00000010;
              autoCommit_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteRegionTxRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteRegionTxRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccDeleteRegionTxRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccDeleteRegionTxRequest>() {
      public SsccDeleteRegionTxRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccDeleteRegionTxRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccDeleteRegionTxRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 tid = 1;
    public static final int TID_FIELD_NUMBER = 1;
    private long tid_;
    /**
     * <code>required int64 tid = 1;</code>
     */
    public boolean hasTid() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 tid = 1;</code>
     */
    public long getTid() {
      return tid_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required .MutationProto delete = 4;
    public static final int DELETE_FIELD_NUMBER = 4;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto delete_;
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    public boolean hasDelete() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete() {
      return delete_;
    }
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder() {
      return delete_;
    }

    // required bool autoCommit = 5;
    public static final int AUTOCOMMIT_FIELD_NUMBER = 5;
    private boolean autoCommit_;
    /**
     * <code>required bool autoCommit = 5;</code>
     */
    public boolean hasAutoCommit() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>required bool autoCommit = 5;</code>
     */
    public boolean getAutoCommit() {
      return autoCommit_;
    }

    private void initFields() {
      tid_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      autoCommit_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTid()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasDelete()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasAutoCommit()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getDelete().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, tid_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeMessage(4, delete_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeBool(5, autoCommit_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, tid_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, delete_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(5, autoCommit_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccDeleteRegionTxRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteRegionTxRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteRegionTxRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getDeleteFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        tid_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (deleteBuilder_ == null) {
          delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
        } else {
          deleteBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        autoCommit_ = false;
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteRegionTxRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.tid_ = tid_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        if (deleteBuilder_ == null) {
          result.delete_ = delete_;
        } else {
          result.delete_ = deleteBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.autoCommit_ = autoCommit_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest.getDefaultInstance()) return this;
        if (other.hasTid()) {
          setTid(other.getTid());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasDelete()) {
          mergeDelete(other.getDelete());
        }
        if (other.hasAutoCommit()) {
          setAutoCommit(other.getAutoCommit());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTid()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasDelete()) {
          
          return false;
        }
        if (!hasAutoCommit()) {
          
          return false;
        }
        if (!getDelete().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 tid = 1;
      private long tid_ ;
      /**
       * <code>required int64 tid = 1;</code>
       */
      public boolean hasTid() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public long getTid() {
        return tid_;
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public Builder setTid(long value) {
        bitField0_ |= 0x00000001;
        tid_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public Builder clearTid() {
        bitField0_ = (bitField0_ & ~0x00000001);
        tid_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required .MutationProto delete = 4;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> deleteBuilder_;
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public boolean hasDelete() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete() {
        if (deleteBuilder_ == null) {
          return delete_;
        } else {
          return deleteBuilder_.getMessage();
        }
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public Builder setDelete(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          delete_ = value;
          onChanged();
        } else {
          deleteBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public Builder setDelete(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (deleteBuilder_ == null) {
          delete_ = builderForValue.build();
          onChanged();
        } else {
          deleteBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public Builder mergeDelete(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              delete_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance()) {
            delete_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.newBuilder(delete_).mergeFrom(value).buildPartial();
          } else {
            delete_ = value;
          }
          onChanged();
        } else {
          deleteBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public Builder clearDelete() {
        if (deleteBuilder_ == null) {
          delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
          onChanged();
        } else {
          deleteBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder getDeleteBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getDeleteFieldBuilder().getBuilder();
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder() {
        if (deleteBuilder_ != null) {
          return deleteBuilder_.getMessageOrBuilder();
        } else {
          return delete_;
        }
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
          getDeleteFieldBuilder() {
        if (deleteBuilder_ == null) {
          deleteBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder>(
                  delete_,
                  getParentForChildren(),
                  isClean());
          delete_ = null;
        }
        return deleteBuilder_;
      }

      // required bool autoCommit = 5;
      private boolean autoCommit_ ;
      /**
       * <code>required bool autoCommit = 5;</code>
       */
      public boolean hasAutoCommit() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>required bool autoCommit = 5;</code>
       */
      public boolean getAutoCommit() {
        return autoCommit_;
      }
      /**
       * <code>required bool autoCommit = 5;</code>
       */
      public Builder setAutoCommit(boolean value) {
        bitField0_ |= 0x00000010;
        autoCommit_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool autoCommit = 5;</code>
       */
      public Builder clearAutoCommit() {
        bitField0_ = (bitField0_ & ~0x00000010);
        autoCommit_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccDeleteRegionTxRequest)
    }

    static {
      defaultInstance = new SsccDeleteRegionTxRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccDeleteRegionTxRequest)
  }

  public interface SsccDeleteRegionTxResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional .Result result = 1;
    /**
     * <code>optional .Result result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();

    // optional int32 status = 4;
    /**
     * <code>optional int32 status = 4;</code>
     */
    boolean hasStatus();
    /**
     * <code>optional int32 status = 4;</code>
     */
    int getStatus();
  }
  /**
   * Protobuf type {@code SsccDeleteRegionTxResponse}
   */
  public static final class SsccDeleteRegionTxResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccDeleteRegionTxResponseOrBuilder {
    // Use SsccDeleteRegionTxResponse.newBuilder() to construct.
    private SsccDeleteRegionTxResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccDeleteRegionTxResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccDeleteRegionTxResponse defaultInstance;
    public static SsccDeleteRegionTxResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccDeleteRegionTxResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccDeleteRegionTxResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = result_.toBuilder();
              }
              result_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(result_);
                result_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              status_ = input.readInt32();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteRegionTxResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteRegionTxResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccDeleteRegionTxResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccDeleteRegionTxResponse>() {
      public SsccDeleteRegionTxResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccDeleteRegionTxResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccDeleteRegionTxResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional .Result result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_;
    /**
     * <code>optional .Result result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
      return result_;
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    // optional int32 status = 4;
    public static final int STATUS_FIELD_NUMBER = 4;
    private int status_;
    /**
     * <code>optional int32 status = 4;</code>
     */
    public boolean hasStatus() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int32 status = 4;</code>
     */
    public int getStatus() {
      return status_;
    }

    private void initFields() {
      result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      exception_ = "";
      hasException_ = false;
      status_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt32(4, status_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, status_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccDeleteRegionTxResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteRegionTxResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteRegionTxResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getResultFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteRegionTxResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (resultBuilder_ == null) {
          result.result_ = result_;
        } else {
          result.result_ = resultBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.status_ = status_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          mergeResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional .Result result = 1;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> resultBuilder_;
      /**
       * <code>optional .Result result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
        if (resultBuilder_ == null) {
          return result_;
        } else {
          return resultBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          result_ = value;
          onChanged();
        } else {
          resultBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder builderForValue) {
        if (resultBuilder_ == null) {
          result_ = builderForValue.build();
          onChanged();
        } else {
          resultBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder mergeResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              result_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance()) {
            result_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.newBuilder(result_).mergeFrom(value).buildPartial();
          } else {
            result_ = value;
          }
          onChanged();
        } else {
          resultBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder clearResult() {
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
          onChanged();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder getResultBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getResultFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
        if (resultBuilder_ != null) {
          return resultBuilder_.getMessageOrBuilder();
        } else {
          return result_;
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
          getResultFieldBuilder() {
        if (resultBuilder_ == null) {
          resultBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder>(
                  result_,
                  getParentForChildren(),
                  isClean());
          result_ = null;
        }
        return resultBuilder_;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // optional int32 status = 4;
      private int status_ ;
      /**
       * <code>optional int32 status = 4;</code>
       */
      public boolean hasStatus() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public int getStatus() {
        return status_;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder setStatus(int value) {
        bitField0_ |= 0x00000008;
        status_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000008);
        status_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccDeleteRegionTxResponse)
    }

    static {
      defaultInstance = new SsccDeleteRegionTxResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccDeleteRegionTxResponse)
  }

  public interface SsccDeleteTransactionalRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required .MutationProto delete = 4;
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    boolean hasDelete();
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete();
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder();
  }
  /**
   * Protobuf type {@code SsccDeleteTransactionalRequest}
   */
  public static final class SsccDeleteTransactionalRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccDeleteTransactionalRequestOrBuilder {
    // Use SsccDeleteTransactionalRequest.newBuilder() to construct.
    private SsccDeleteTransactionalRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccDeleteTransactionalRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccDeleteTransactionalRequest defaultInstance;
    public static SsccDeleteTransactionalRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccDeleteTransactionalRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccDeleteTransactionalRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder subBuilder = null;
              if (((bitField0_ & 0x00000008) == 0x00000008)) {
                subBuilder = delete_.toBuilder();
              }
              delete_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(delete_);
                delete_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000008;
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteTransactionalRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteTransactionalRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccDeleteTransactionalRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccDeleteTransactionalRequest>() {
      public SsccDeleteTransactionalRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccDeleteTransactionalRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccDeleteTransactionalRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required .MutationProto delete = 4;
    public static final int DELETE_FIELD_NUMBER = 4;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto delete_;
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    public boolean hasDelete() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete() {
      return delete_;
    }
    /**
     * <code>required .MutationProto delete = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder() {
      return delete_;
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasDelete()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getDelete().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeMessage(4, delete_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, delete_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccDeleteTransactionalRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteTransactionalRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteTransactionalRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getDeleteFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (deleteBuilder_ == null) {
          delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
        } else {
          deleteBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteTransactionalRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        if (deleteBuilder_ == null) {
          result.delete_ = delete_;
        } else {
          result.delete_ = deleteBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasDelete()) {
          mergeDelete(other.getDelete());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasDelete()) {
          
          return false;
        }
        if (!getDelete().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required .MutationProto delete = 4;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> deleteBuilder_;
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public boolean hasDelete() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getDelete() {
        if (deleteBuilder_ == null) {
          return delete_;
        } else {
          return deleteBuilder_.getMessage();
        }
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public Builder setDelete(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          delete_ = value;
          onChanged();
        } else {
          deleteBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public Builder setDelete(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (deleteBuilder_ == null) {
          delete_ = builderForValue.build();
          onChanged();
        } else {
          deleteBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public Builder mergeDelete(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (deleteBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              delete_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance()) {
            delete_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.newBuilder(delete_).mergeFrom(value).buildPartial();
          } else {
            delete_ = value;
          }
          onChanged();
        } else {
          deleteBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public Builder clearDelete() {
        if (deleteBuilder_ == null) {
          delete_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
          onChanged();
        } else {
          deleteBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder getDeleteBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getDeleteFieldBuilder().getBuilder();
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getDeleteOrBuilder() {
        if (deleteBuilder_ != null) {
          return deleteBuilder_.getMessageOrBuilder();
        } else {
          return delete_;
        }
      }
      /**
       * <code>required .MutationProto delete = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
          getDeleteFieldBuilder() {
        if (deleteBuilder_ == null) {
          deleteBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder>(
                  delete_,
                  getParentForChildren(),
                  isClean());
          delete_ = null;
        }
        return deleteBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:SsccDeleteTransactionalRequest)
    }

    static {
      defaultInstance = new SsccDeleteTransactionalRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccDeleteTransactionalRequest)
  }

  public interface SsccDeleteTransactionalResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional .Result result = 1;
    /**
     * <code>optional .Result result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();

    // optional int32 status = 4;
    /**
     * <code>optional int32 status = 4;</code>
     */
    boolean hasStatus();
    /**
     * <code>optional int32 status = 4;</code>
     */
    int getStatus();
  }
  /**
   * Protobuf type {@code SsccDeleteTransactionalResponse}
   */
  public static final class SsccDeleteTransactionalResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccDeleteTransactionalResponseOrBuilder {
    // Use SsccDeleteTransactionalResponse.newBuilder() to construct.
    private SsccDeleteTransactionalResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccDeleteTransactionalResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccDeleteTransactionalResponse defaultInstance;
    public static SsccDeleteTransactionalResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccDeleteTransactionalResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccDeleteTransactionalResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = result_.toBuilder();
              }
              result_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(result_);
                result_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              status_ = input.readInt32();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteTransactionalResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteTransactionalResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccDeleteTransactionalResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccDeleteTransactionalResponse>() {
      public SsccDeleteTransactionalResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccDeleteTransactionalResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccDeleteTransactionalResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional .Result result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_;
    /**
     * <code>optional .Result result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
      return result_;
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    // optional int32 status = 4;
    public static final int STATUS_FIELD_NUMBER = 4;
    private int status_;
    /**
     * <code>optional int32 status = 4;</code>
     */
    public boolean hasStatus() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int32 status = 4;</code>
     */
    public int getStatus() {
      return status_;
    }

    private void initFields() {
      result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      exception_ = "";
      hasException_ = false;
      status_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt32(4, status_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, status_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccDeleteTransactionalResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteTransactionalResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteTransactionalResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getResultFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccDeleteTransactionalResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (resultBuilder_ == null) {
          result.result_ = result_;
        } else {
          result.result_ = resultBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.status_ = status_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          mergeResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional .Result result = 1;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> resultBuilder_;
      /**
       * <code>optional .Result result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
        if (resultBuilder_ == null) {
          return result_;
        } else {
          return resultBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          result_ = value;
          onChanged();
        } else {
          resultBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder builderForValue) {
        if (resultBuilder_ == null) {
          result_ = builderForValue.build();
          onChanged();
        } else {
          resultBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder mergeResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              result_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance()) {
            result_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.newBuilder(result_).mergeFrom(value).buildPartial();
          } else {
            result_ = value;
          }
          onChanged();
        } else {
          resultBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder clearResult() {
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
          onChanged();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder getResultBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getResultFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
        if (resultBuilder_ != null) {
          return resultBuilder_.getMessageOrBuilder();
        } else {
          return result_;
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
          getResultFieldBuilder() {
        if (resultBuilder_ == null) {
          resultBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder>(
                  result_,
                  getParentForChildren(),
                  isClean());
          result_ = null;
        }
        return resultBuilder_;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // optional int32 status = 4;
      private int status_ ;
      /**
       * <code>optional int32 status = 4;</code>
       */
      public boolean hasStatus() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public int getStatus() {
        return status_;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder setStatus(int value) {
        bitField0_ |= 0x00000008;
        status_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000008);
        status_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccDeleteTransactionalResponse)
    }

    static {
      defaultInstance = new SsccDeleteTransactionalResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccDeleteTransactionalResponse)
  }

  public interface SsccGetTransactionalRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required .Get get = 4;
    /**
     * <code>required .Get get = 4;</code>
     */
    boolean hasGet();
    /**
     * <code>required .Get get = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get getGet();
    /**
     * <code>required .Get get = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetOrBuilder getGetOrBuilder();
  }
  /**
   * Protobuf type {@code SsccGetTransactionalRequest}
   */
  public static final class SsccGetTransactionalRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccGetTransactionalRequestOrBuilder {
    // Use SsccGetTransactionalRequest.newBuilder() to construct.
    private SsccGetTransactionalRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccGetTransactionalRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccGetTransactionalRequest defaultInstance;
    public static SsccGetTransactionalRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccGetTransactionalRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccGetTransactionalRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.Builder subBuilder = null;
              if (((bitField0_ & 0x00000008) == 0x00000008)) {
                subBuilder = get_.toBuilder();
              }
              get_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(get_);
                get_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000008;
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccGetTransactionalRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccGetTransactionalRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccGetTransactionalRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccGetTransactionalRequest>() {
      public SsccGetTransactionalRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccGetTransactionalRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccGetTransactionalRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required .Get get = 4;
    public static final int GET_FIELD_NUMBER = 4;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get get_;
    /**
     * <code>required .Get get = 4;</code>
     */
    public boolean hasGet() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required .Get get = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get getGet() {
      return get_;
    }
    /**
     * <code>required .Get get = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetOrBuilder getGetOrBuilder() {
      return get_;
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      get_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasGet()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getGet().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeMessage(4, get_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, get_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccGetTransactionalRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccGetTransactionalRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccGetTransactionalRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getGetFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (getBuilder_ == null) {
          get_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.getDefaultInstance();
        } else {
          getBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccGetTransactionalRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        if (getBuilder_ == null) {
          result.get_ = get_;
        } else {
          result.get_ = getBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasGet()) {
          mergeGet(other.getGet());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasGet()) {
          
          return false;
        }
        if (!getGet().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required .Get get = 4;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get get_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetOrBuilder> getBuilder_;
      /**
       * <code>required .Get get = 4;</code>
       */
      public boolean hasGet() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required .Get get = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get getGet() {
        if (getBuilder_ == null) {
          return get_;
        } else {
          return getBuilder_.getMessage();
        }
      }
      /**
       * <code>required .Get get = 4;</code>
       */
      public Builder setGet(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get value) {
        if (getBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          get_ = value;
          onChanged();
        } else {
          getBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .Get get = 4;</code>
       */
      public Builder setGet(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.Builder builderForValue) {
        if (getBuilder_ == null) {
          get_ = builderForValue.build();
          onChanged();
        } else {
          getBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .Get get = 4;</code>
       */
      public Builder mergeGet(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get value) {
        if (getBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              get_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.getDefaultInstance()) {
            get_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.newBuilder(get_).mergeFrom(value).buildPartial();
          } else {
            get_ = value;
          }
          onChanged();
        } else {
          getBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .Get get = 4;</code>
       */
      public Builder clearGet() {
        if (getBuilder_ == null) {
          get_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.getDefaultInstance();
          onChanged();
        } else {
          getBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>required .Get get = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.Builder getGetBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getGetFieldBuilder().getBuilder();
      }
      /**
       * <code>required .Get get = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetOrBuilder getGetOrBuilder() {
        if (getBuilder_ != null) {
          return getBuilder_.getMessageOrBuilder();
        } else {
          return get_;
        }
      }
      /**
       * <code>required .Get get = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetOrBuilder> 
          getGetFieldBuilder() {
        if (getBuilder_ == null) {
          getBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Get.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetOrBuilder>(
                  get_,
                  getParentForChildren(),
                  isClean());
          get_ = null;
        }
        return getBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:SsccGetTransactionalRequest)
    }

    static {
      defaultInstance = new SsccGetTransactionalRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccGetTransactionalRequest)
  }

  public interface SsccGetTransactionalResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional .Result result = 1;
    /**
     * <code>optional .Result result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccGetTransactionalResponse}
   */
  public static final class SsccGetTransactionalResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccGetTransactionalResponseOrBuilder {
    // Use SsccGetTransactionalResponse.newBuilder() to construct.
    private SsccGetTransactionalResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccGetTransactionalResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccGetTransactionalResponse defaultInstance;
    public static SsccGetTransactionalResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccGetTransactionalResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccGetTransactionalResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = result_.toBuilder();
              }
              result_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(result_);
                result_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccGetTransactionalResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccGetTransactionalResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccGetTransactionalResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccGetTransactionalResponse>() {
      public SsccGetTransactionalResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccGetTransactionalResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccGetTransactionalResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional .Result result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_;
    /**
     * <code>optional .Result result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
      return result_;
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccGetTransactionalResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccGetTransactionalResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccGetTransactionalResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getResultFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccGetTransactionalResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (resultBuilder_ == null) {
          result.result_ = result_;
        } else {
          result.result_ = resultBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          mergeResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional .Result result = 1;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> resultBuilder_;
      /**
       * <code>optional .Result result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
        if (resultBuilder_ == null) {
          return result_;
        } else {
          return resultBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          result_ = value;
          onChanged();
        } else {
          resultBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder builderForValue) {
        if (resultBuilder_ == null) {
          result_ = builderForValue.build();
          onChanged();
        } else {
          resultBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder mergeResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              result_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance()) {
            result_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.newBuilder(result_).mergeFrom(value).buildPartial();
          } else {
            result_ = value;
          }
          onChanged();
        } else {
          resultBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder clearResult() {
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
          onChanged();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder getResultBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getResultFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
        if (resultBuilder_ != null) {
          return resultBuilder_.getMessageOrBuilder();
        } else {
          return result_;
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
          getResultFieldBuilder() {
        if (resultBuilder_ == null) {
          resultBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder>(
                  result_,
                  getParentForChildren(),
                  isClean());
          result_ = null;
        }
        return resultBuilder_;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccGetTransactionalResponse)
    }

    static {
      defaultInstance = new SsccGetTransactionalResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccGetTransactionalResponse)
  }

  public interface SsccOpenScannerRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required .Scan scan = 4;
    /**
     * <code>required .Scan scan = 4;</code>
     */
    boolean hasScan();
    /**
     * <code>required .Scan scan = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan getScan();
    /**
     * <code>required .Scan scan = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder getScanOrBuilder();
  }
  /**
   * Protobuf type {@code SsccOpenScannerRequest}
   */
  public static final class SsccOpenScannerRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccOpenScannerRequestOrBuilder {
    // Use SsccOpenScannerRequest.newBuilder() to construct.
    private SsccOpenScannerRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccOpenScannerRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccOpenScannerRequest defaultInstance;
    public static SsccOpenScannerRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccOpenScannerRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccOpenScannerRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder subBuilder = null;
              if (((bitField0_ & 0x00000008) == 0x00000008)) {
                subBuilder = scan_.toBuilder();
              }
              scan_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(scan_);
                scan_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000008;
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccOpenScannerRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccOpenScannerRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccOpenScannerRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccOpenScannerRequest>() {
      public SsccOpenScannerRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccOpenScannerRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccOpenScannerRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required .Scan scan = 4;
    public static final int SCAN_FIELD_NUMBER = 4;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan scan_;
    /**
     * <code>required .Scan scan = 4;</code>
     */
    public boolean hasScan() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required .Scan scan = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan getScan() {
      return scan_;
    }
    /**
     * <code>required .Scan scan = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder getScanOrBuilder() {
      return scan_;
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      scan_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasScan()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getScan().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeMessage(4, scan_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, scan_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccOpenScannerRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccOpenScannerRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccOpenScannerRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getScanFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (scanBuilder_ == null) {
          scan_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.getDefaultInstance();
        } else {
          scanBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccOpenScannerRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        if (scanBuilder_ == null) {
          result.scan_ = scan_;
        } else {
          result.scan_ = scanBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasScan()) {
          mergeScan(other.getScan());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasScan()) {
          
          return false;
        }
        if (!getScan().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required .Scan scan = 4;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan scan_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder> scanBuilder_;
      /**
       * <code>required .Scan scan = 4;</code>
       */
      public boolean hasScan() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required .Scan scan = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan getScan() {
        if (scanBuilder_ == null) {
          return scan_;
        } else {
          return scanBuilder_.getMessage();
        }
      }
      /**
       * <code>required .Scan scan = 4;</code>
       */
      public Builder setScan(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan value) {
        if (scanBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          scan_ = value;
          onChanged();
        } else {
          scanBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .Scan scan = 4;</code>
       */
      public Builder setScan(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder builderForValue) {
        if (scanBuilder_ == null) {
          scan_ = builderForValue.build();
          onChanged();
        } else {
          scanBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .Scan scan = 4;</code>
       */
      public Builder mergeScan(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan value) {
        if (scanBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              scan_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.getDefaultInstance()) {
            scan_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.newBuilder(scan_).mergeFrom(value).buildPartial();
          } else {
            scan_ = value;
          }
          onChanged();
        } else {
          scanBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .Scan scan = 4;</code>
       */
      public Builder clearScan() {
        if (scanBuilder_ == null) {
          scan_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.getDefaultInstance();
          onChanged();
        } else {
          scanBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>required .Scan scan = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder getScanBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getScanFieldBuilder().getBuilder();
      }
      /**
       * <code>required .Scan scan = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder getScanOrBuilder() {
        if (scanBuilder_ != null) {
          return scanBuilder_.getMessageOrBuilder();
        } else {
          return scan_;
        }
      }
      /**
       * <code>required .Scan scan = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder> 
          getScanFieldBuilder() {
        if (scanBuilder_ == null) {
          scanBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder>(
                  scan_,
                  getParentForChildren(),
                  isClean());
          scan_ = null;
        }
        return scanBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:SsccOpenScannerRequest)
    }

    static {
      defaultInstance = new SsccOpenScannerRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccOpenScannerRequest)
  }

  public interface SsccOpenScannerResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 scannerId = 1;
    /**
     * <code>required int64 scannerId = 1;</code>
     */
    boolean hasScannerId();
    /**
     * <code>required int64 scannerId = 1;</code>
     */
    long getScannerId();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccOpenScannerResponse}
   */
  public static final class SsccOpenScannerResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccOpenScannerResponseOrBuilder {
    // Use SsccOpenScannerResponse.newBuilder() to construct.
    private SsccOpenScannerResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccOpenScannerResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccOpenScannerResponse defaultInstance;
    public static SsccOpenScannerResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccOpenScannerResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccOpenScannerResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              scannerId_ = input.readInt64();
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccOpenScannerResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccOpenScannerResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccOpenScannerResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccOpenScannerResponse>() {
      public SsccOpenScannerResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccOpenScannerResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccOpenScannerResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 scannerId = 1;
    public static final int SCANNERID_FIELD_NUMBER = 1;
    private long scannerId_;
    /**
     * <code>required int64 scannerId = 1;</code>
     */
    public boolean hasScannerId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 scannerId = 1;</code>
     */
    public long getScannerId() {
      return scannerId_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      scannerId_ = 0L;
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasScannerId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, scannerId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, scannerId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccOpenScannerResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccOpenScannerResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccOpenScannerResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        scannerId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccOpenScannerResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.scannerId_ = scannerId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.getDefaultInstance()) return this;
        if (other.hasScannerId()) {
          setScannerId(other.getScannerId());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasScannerId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 scannerId = 1;
      private long scannerId_ ;
      /**
       * <code>required int64 scannerId = 1;</code>
       */
      public boolean hasScannerId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 scannerId = 1;</code>
       */
      public long getScannerId() {
        return scannerId_;
      }
      /**
       * <code>required int64 scannerId = 1;</code>
       */
      public Builder setScannerId(long value) {
        bitField0_ |= 0x00000001;
        scannerId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 scannerId = 1;</code>
       */
      public Builder clearScannerId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        scannerId_ = 0L;
        onChanged();
        return this;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccOpenScannerResponse)
    }

    static {
      defaultInstance = new SsccOpenScannerResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccOpenScannerResponse)
  }

  public interface SsccPerformScanRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required int64 scannerId = 4;
    /**
     * <code>required int64 scannerId = 4;</code>
     */
    boolean hasScannerId();
    /**
     * <code>required int64 scannerId = 4;</code>
     */
    long getScannerId();

    // required int32 numberOfRows = 5;
    /**
     * <code>required int32 numberOfRows = 5;</code>
     */
    boolean hasNumberOfRows();
    /**
     * <code>required int32 numberOfRows = 5;</code>
     */
    int getNumberOfRows();

    // required bool closeScanner = 6;
    /**
     * <code>required bool closeScanner = 6;</code>
     */
    boolean hasCloseScanner();
    /**
     * <code>required bool closeScanner = 6;</code>
     */
    boolean getCloseScanner();

    // required int64 nextCallSeq = 7;
    /**
     * <code>required int64 nextCallSeq = 7;</code>
     */
    boolean hasNextCallSeq();
    /**
     * <code>required int64 nextCallSeq = 7;</code>
     */
    long getNextCallSeq();
  }
  /**
   * Protobuf type {@code SsccPerformScanRequest}
   */
  public static final class SsccPerformScanRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccPerformScanRequestOrBuilder {
    // Use SsccPerformScanRequest.newBuilder() to construct.
    private SsccPerformScanRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccPerformScanRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccPerformScanRequest defaultInstance;
    public static SsccPerformScanRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccPerformScanRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccPerformScanRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              scannerId_ = input.readInt64();
              break;
            }
            case 40: {
              bitField0_ |= 0x00000010;
              numberOfRows_ = input.readInt32();
              break;
            }
            case 48: {
              bitField0_ |= 0x00000020;
              closeScanner_ = input.readBool();
              break;
            }
            case 56: {
              bitField0_ |= 0x00000040;
              nextCallSeq_ = input.readInt64();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPerformScanRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPerformScanRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccPerformScanRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccPerformScanRequest>() {
      public SsccPerformScanRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccPerformScanRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccPerformScanRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required int64 scannerId = 4;
    public static final int SCANNERID_FIELD_NUMBER = 4;
    private long scannerId_;
    /**
     * <code>required int64 scannerId = 4;</code>
     */
    public boolean hasScannerId() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required int64 scannerId = 4;</code>
     */
    public long getScannerId() {
      return scannerId_;
    }

    // required int32 numberOfRows = 5;
    public static final int NUMBEROFROWS_FIELD_NUMBER = 5;
    private int numberOfRows_;
    /**
     * <code>required int32 numberOfRows = 5;</code>
     */
    public boolean hasNumberOfRows() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>required int32 numberOfRows = 5;</code>
     */
    public int getNumberOfRows() {
      return numberOfRows_;
    }

    // required bool closeScanner = 6;
    public static final int CLOSESCANNER_FIELD_NUMBER = 6;
    private boolean closeScanner_;
    /**
     * <code>required bool closeScanner = 6;</code>
     */
    public boolean hasCloseScanner() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>required bool closeScanner = 6;</code>
     */
    public boolean getCloseScanner() {
      return closeScanner_;
    }

    // required int64 nextCallSeq = 7;
    public static final int NEXTCALLSEQ_FIELD_NUMBER = 7;
    private long nextCallSeq_;
    /**
     * <code>required int64 nextCallSeq = 7;</code>
     */
    public boolean hasNextCallSeq() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    /**
     * <code>required int64 nextCallSeq = 7;</code>
     */
    public long getNextCallSeq() {
      return nextCallSeq_;
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      scannerId_ = 0L;
      numberOfRows_ = 0;
      closeScanner_ = false;
      nextCallSeq_ = 0L;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasScannerId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasNumberOfRows()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasCloseScanner()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasNextCallSeq()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt64(4, scannerId_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeInt32(5, numberOfRows_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeBool(6, closeScanner_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        output.writeInt64(7, nextCallSeq_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(4, scannerId_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(5, numberOfRows_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(6, closeScanner_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(7, nextCallSeq_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccPerformScanRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPerformScanRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPerformScanRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        scannerId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000008);
        numberOfRows_ = 0;
        bitField0_ = (bitField0_ & ~0x00000010);
        closeScanner_ = false;
        bitField0_ = (bitField0_ & ~0x00000020);
        nextCallSeq_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000040);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPerformScanRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.scannerId_ = scannerId_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.numberOfRows_ = numberOfRows_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.closeScanner_ = closeScanner_;
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000040;
        }
        result.nextCallSeq_ = nextCallSeq_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasScannerId()) {
          setScannerId(other.getScannerId());
        }
        if (other.hasNumberOfRows()) {
          setNumberOfRows(other.getNumberOfRows());
        }
        if (other.hasCloseScanner()) {
          setCloseScanner(other.getCloseScanner());
        }
        if (other.hasNextCallSeq()) {
          setNextCallSeq(other.getNextCallSeq());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasScannerId()) {
          
          return false;
        }
        if (!hasNumberOfRows()) {
          
          return false;
        }
        if (!hasCloseScanner()) {
          
          return false;
        }
        if (!hasNextCallSeq()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required int64 scannerId = 4;
      private long scannerId_ ;
      /**
       * <code>required int64 scannerId = 4;</code>
       */
      public boolean hasScannerId() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required int64 scannerId = 4;</code>
       */
      public long getScannerId() {
        return scannerId_;
      }
      /**
       * <code>required int64 scannerId = 4;</code>
       */
      public Builder setScannerId(long value) {
        bitField0_ |= 0x00000008;
        scannerId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 scannerId = 4;</code>
       */
      public Builder clearScannerId() {
        bitField0_ = (bitField0_ & ~0x00000008);
        scannerId_ = 0L;
        onChanged();
        return this;
      }

      // required int32 numberOfRows = 5;
      private int numberOfRows_ ;
      /**
       * <code>required int32 numberOfRows = 5;</code>
       */
      public boolean hasNumberOfRows() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>required int32 numberOfRows = 5;</code>
       */
      public int getNumberOfRows() {
        return numberOfRows_;
      }
      /**
       * <code>required int32 numberOfRows = 5;</code>
       */
      public Builder setNumberOfRows(int value) {
        bitField0_ |= 0x00000010;
        numberOfRows_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 numberOfRows = 5;</code>
       */
      public Builder clearNumberOfRows() {
        bitField0_ = (bitField0_ & ~0x00000010);
        numberOfRows_ = 0;
        onChanged();
        return this;
      }

      // required bool closeScanner = 6;
      private boolean closeScanner_ ;
      /**
       * <code>required bool closeScanner = 6;</code>
       */
      public boolean hasCloseScanner() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>required bool closeScanner = 6;</code>
       */
      public boolean getCloseScanner() {
        return closeScanner_;
      }
      /**
       * <code>required bool closeScanner = 6;</code>
       */
      public Builder setCloseScanner(boolean value) {
        bitField0_ |= 0x00000020;
        closeScanner_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool closeScanner = 6;</code>
       */
      public Builder clearCloseScanner() {
        bitField0_ = (bitField0_ & ~0x00000020);
        closeScanner_ = false;
        onChanged();
        return this;
      }

      // required int64 nextCallSeq = 7;
      private long nextCallSeq_ ;
      /**
       * <code>required int64 nextCallSeq = 7;</code>
       */
      public boolean hasNextCallSeq() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      /**
       * <code>required int64 nextCallSeq = 7;</code>
       */
      public long getNextCallSeq() {
        return nextCallSeq_;
      }
      /**
       * <code>required int64 nextCallSeq = 7;</code>
       */
      public Builder setNextCallSeq(long value) {
        bitField0_ |= 0x00000040;
        nextCallSeq_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 nextCallSeq = 7;</code>
       */
      public Builder clearNextCallSeq() {
        bitField0_ = (bitField0_ & ~0x00000040);
        nextCallSeq_ = 0L;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccPerformScanRequest)
    }

    static {
      defaultInstance = new SsccPerformScanRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccPerformScanRequest)
  }

  public interface SsccPerformScanResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // repeated .Result result = 1;
    /**
     * <code>repeated .Result result = 1;</code>
     */
    java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result> 
        getResultList();
    /**
     * <code>repeated .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult(int index);
    /**
     * <code>repeated .Result result = 1;</code>
     */
    int getResultCount();
    /**
     * <code>repeated .Result result = 1;</code>
     */
    java.util.List<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
        getResultOrBuilderList();
    /**
     * <code>repeated .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder(
        int index);

    // required int64 count = 2;
    /**
     * <code>required int64 count = 2;</code>
     */
    boolean hasCount();
    /**
     * <code>required int64 count = 2;</code>
     */
    long getCount();

    // required int64 nextCallSeq = 3;
    /**
     * <code>required int64 nextCallSeq = 3;</code>
     */
    boolean hasNextCallSeq();
    /**
     * <code>required int64 nextCallSeq = 3;</code>
     */
    long getNextCallSeq();

    // required bool hasMore = 4;
    /**
     * <code>required bool hasMore = 4;</code>
     */
    boolean hasHasMore();
    /**
     * <code>required bool hasMore = 4;</code>
     */
    boolean getHasMore();

    // optional string exception = 5;
    /**
     * <code>optional string exception = 5;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 5;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 5;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 6;
    /**
     * <code>optional bool hasException = 6;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 6;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccPerformScanResponse}
   */
  public static final class SsccPerformScanResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccPerformScanResponseOrBuilder {
    // Use SsccPerformScanResponse.newBuilder() to construct.
    private SsccPerformScanResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccPerformScanResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccPerformScanResponse defaultInstance;
    public static SsccPerformScanResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccPerformScanResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccPerformScanResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                result_ = new java.util.ArrayList<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result>();
                mutable_bitField0_ |= 0x00000001;
              }
              result_.add(input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.PARSER, extensionRegistry));
              break;
            }
            case 16: {
              bitField0_ |= 0x00000001;
              count_ = input.readInt64();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000002;
              nextCallSeq_ = input.readInt64();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000004;
              hasMore_ = input.readBool();
              break;
            }
            case 42: {
              bitField0_ |= 0x00000008;
              exception_ = input.readBytes();
              break;
            }
            case 48: {
              bitField0_ |= 0x00000010;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          result_ = java.util.Collections.unmodifiableList(result_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPerformScanResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPerformScanResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccPerformScanResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccPerformScanResponse>() {
      public SsccPerformScanResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccPerformScanResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccPerformScanResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // repeated .Result result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result> result_;
    /**
     * <code>repeated .Result result = 1;</code>
     */
    public java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result> getResultList() {
      return result_;
    }
    /**
     * <code>repeated .Result result = 1;</code>
     */
    public java.util.List<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
        getResultOrBuilderList() {
      return result_;
    }
    /**
     * <code>repeated .Result result = 1;</code>
     */
    public int getResultCount() {
      return result_.size();
    }
    /**
     * <code>repeated .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult(int index) {
      return result_.get(index);
    }
    /**
     * <code>repeated .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder(
        int index) {
      return result_.get(index);
    }

    // required int64 count = 2;
    public static final int COUNT_FIELD_NUMBER = 2;
    private long count_;
    /**
     * <code>required int64 count = 2;</code>
     */
    public boolean hasCount() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 count = 2;</code>
     */
    public long getCount() {
      return count_;
    }

    // required int64 nextCallSeq = 3;
    public static final int NEXTCALLSEQ_FIELD_NUMBER = 3;
    private long nextCallSeq_;
    /**
     * <code>required int64 nextCallSeq = 3;</code>
     */
    public boolean hasNextCallSeq() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 nextCallSeq = 3;</code>
     */
    public long getNextCallSeq() {
      return nextCallSeq_;
    }

    // required bool hasMore = 4;
    public static final int HASMORE_FIELD_NUMBER = 4;
    private boolean hasMore_;
    /**
     * <code>required bool hasMore = 4;</code>
     */
    public boolean hasHasMore() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bool hasMore = 4;</code>
     */
    public boolean getHasMore() {
      return hasMore_;
    }

    // optional string exception = 5;
    public static final int EXCEPTION_FIELD_NUMBER = 5;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 5;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional string exception = 5;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 5;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 6;
    public static final int HASEXCEPTION_FIELD_NUMBER = 6;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 6;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional bool hasException = 6;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      result_ = java.util.Collections.emptyList();
      count_ = 0L;
      nextCallSeq_ = 0L;
      hasMore_ = false;
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasCount()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasNextCallSeq()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasHasMore()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < result_.size(); i++) {
        output.writeMessage(1, result_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(2, count_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(3, nextCallSeq_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(4, hasMore_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBytes(5, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeBool(6, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < result_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, result_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, count_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, nextCallSeq_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(4, hasMore_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(5, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(6, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccPerformScanResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPerformScanResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPerformScanResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getResultFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (resultBuilder_ == null) {
          result_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          resultBuilder_.clear();
        }
        count_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        nextCallSeq_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000004);
        hasMore_ = false;
        bitField0_ = (bitField0_ & ~0x00000008);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000010);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000020);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPerformScanResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (resultBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            result_ = java.util.Collections.unmodifiableList(result_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.result_ = result_;
        } else {
          result.result_ = resultBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000001;
        }
        result.count_ = count_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000002;
        }
        result.nextCallSeq_ = nextCallSeq_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasMore_ = hasMore_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000008;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000010;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.getDefaultInstance()) return this;
        if (resultBuilder_ == null) {
          if (!other.result_.isEmpty()) {
            if (result_.isEmpty()) {
              result_ = other.result_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureResultIsMutable();
              result_.addAll(other.result_);
            }
            onChanged();
          }
        } else {
          if (!other.result_.isEmpty()) {
            if (resultBuilder_.isEmpty()) {
              resultBuilder_.dispose();
              resultBuilder_ = null;
              result_ = other.result_;
              bitField0_ = (bitField0_ & ~0x00000001);
              resultBuilder_ = 
                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getResultFieldBuilder() : null;
            } else {
              resultBuilder_.addAllMessages(other.result_);
            }
          }
        }
        if (other.hasCount()) {
          setCount(other.getCount());
        }
        if (other.hasNextCallSeq()) {
          setNextCallSeq(other.getNextCallSeq());
        }
        if (other.hasHasMore()) {
          setHasMore(other.getHasMore());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000010;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasCount()) {
          
          return false;
        }
        if (!hasNextCallSeq()) {
          
          return false;
        }
        if (!hasHasMore()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // repeated .Result result = 1;
      private java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result> result_ =
        java.util.Collections.emptyList();
      private void ensureResultIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          result_ = new java.util.ArrayList<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result>(result_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> resultBuilder_;

      /**
       * <code>repeated .Result result = 1;</code>
       */
      public java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result> getResultList() {
        if (resultBuilder_ == null) {
          return java.util.Collections.unmodifiableList(result_);
        } else {
          return resultBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public int getResultCount() {
        if (resultBuilder_ == null) {
          return result_.size();
        } else {
          return resultBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult(int index) {
        if (resultBuilder_ == null) {
          return result_.get(index);
        } else {
          return resultBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public Builder setResult(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureResultIsMutable();
          result_.set(index, value);
          onChanged();
        } else {
          resultBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public Builder setResult(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder builderForValue) {
        if (resultBuilder_ == null) {
          ensureResultIsMutable();
          result_.set(index, builderForValue.build());
          onChanged();
        } else {
          resultBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public Builder addResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureResultIsMutable();
          result_.add(value);
          onChanged();
        } else {
          resultBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public Builder addResult(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureResultIsMutable();
          result_.add(index, value);
          onChanged();
        } else {
          resultBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public Builder addResult(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder builderForValue) {
        if (resultBuilder_ == null) {
          ensureResultIsMutable();
          result_.add(builderForValue.build());
          onChanged();
        } else {
          resultBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public Builder addResult(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder builderForValue) {
        if (resultBuilder_ == null) {
          ensureResultIsMutable();
          result_.add(index, builderForValue.build());
          onChanged();
        } else {
          resultBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public Builder addAllResult(
          java.lang.Iterable<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result> values) {
        if (resultBuilder_ == null) {
          ensureResultIsMutable();
          super.addAll(values, result_);
          onChanged();
        } else {
          resultBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public Builder clearResult() {
        if (resultBuilder_ == null) {
          result_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          resultBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public Builder removeResult(int index) {
        if (resultBuilder_ == null) {
          ensureResultIsMutable();
          result_.remove(index);
          onChanged();
        } else {
          resultBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder getResultBuilder(
          int index) {
        return getResultFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder(
          int index) {
        if (resultBuilder_ == null) {
          return result_.get(index);  } else {
          return resultBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public java.util.List<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
           getResultOrBuilderList() {
        if (resultBuilder_ != null) {
          return resultBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(result_);
        }
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder addResultBuilder() {
        return getResultFieldBuilder().addBuilder(
            org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance());
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder addResultBuilder(
          int index) {
        return getResultFieldBuilder().addBuilder(
            index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance());
      }
      /**
       * <code>repeated .Result result = 1;</code>
       */
      public java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder> 
           getResultBuilderList() {
        return getResultFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
          getResultFieldBuilder() {
        if (resultBuilder_ == null) {
          resultBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder>(
                  result_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          result_ = null;
        }
        return resultBuilder_;
      }

      // required int64 count = 2;
      private long count_ ;
      /**
       * <code>required int64 count = 2;</code>
       */
      public boolean hasCount() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 count = 2;</code>
       */
      public long getCount() {
        return count_;
      }
      /**
       * <code>required int64 count = 2;</code>
       */
      public Builder setCount(long value) {
        bitField0_ |= 0x00000002;
        count_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 count = 2;</code>
       */
      public Builder clearCount() {
        bitField0_ = (bitField0_ & ~0x00000002);
        count_ = 0L;
        onChanged();
        return this;
      }

      // required int64 nextCallSeq = 3;
      private long nextCallSeq_ ;
      /**
       * <code>required int64 nextCallSeq = 3;</code>
       */
      public boolean hasNextCallSeq() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required int64 nextCallSeq = 3;</code>
       */
      public long getNextCallSeq() {
        return nextCallSeq_;
      }
      /**
       * <code>required int64 nextCallSeq = 3;</code>
       */
      public Builder setNextCallSeq(long value) {
        bitField0_ |= 0x00000004;
        nextCallSeq_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 nextCallSeq = 3;</code>
       */
      public Builder clearNextCallSeq() {
        bitField0_ = (bitField0_ & ~0x00000004);
        nextCallSeq_ = 0L;
        onChanged();
        return this;
      }

      // required bool hasMore = 4;
      private boolean hasMore_ ;
      /**
       * <code>required bool hasMore = 4;</code>
       */
      public boolean hasHasMore() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required bool hasMore = 4;</code>
       */
      public boolean getHasMore() {
        return hasMore_;
      }
      /**
       * <code>required bool hasMore = 4;</code>
       */
      public Builder setHasMore(boolean value) {
        bitField0_ |= 0x00000008;
        hasMore_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool hasMore = 4;</code>
       */
      public Builder clearHasMore() {
        bitField0_ = (bitField0_ & ~0x00000008);
        hasMore_ = false;
        onChanged();
        return this;
      }

      // optional string exception = 5;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 5;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional string exception = 5;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 5;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 5;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 5;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000010);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 5;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 6;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 6;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>optional bool hasException = 6;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 6;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000020;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 6;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000020);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccPerformScanResponse)
    }

    static {
      defaultInstance = new SsccPerformScanResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccPerformScanResponse)
  }

  public interface SsccPutRegionTxRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 tid = 1;
    /**
     * <code>required int64 tid = 1;</code>
     */
    boolean hasTid();
    /**
     * <code>required int64 tid = 1;</code>
     */
    long getTid();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required .MutationProto put = 4;
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    boolean hasPut();
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut();
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder();

    // optional bool isStateless = 5;
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    boolean hasIsStateless();
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    boolean getIsStateless();

    // required bool autoCommit = 6;
    /**
     * <code>required bool autoCommit = 6;</code>
     */
    boolean hasAutoCommit();
    /**
     * <code>required bool autoCommit = 6;</code>
     */
    boolean getAutoCommit();
  }
  /**
   * Protobuf type {@code SsccPutRegionTxRequest}
   */
  public static final class SsccPutRegionTxRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccPutRegionTxRequestOrBuilder {
    // Use SsccPutRegionTxRequest.newBuilder() to construct.
    private SsccPutRegionTxRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccPutRegionTxRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccPutRegionTxRequest defaultInstance;
    public static SsccPutRegionTxRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccPutRegionTxRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccPutRegionTxRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              tid_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder subBuilder = null;
              if (((bitField0_ & 0x00000008) == 0x00000008)) {
                subBuilder = put_.toBuilder();
              }
              put_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(put_);
                put_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000008;
              break;
            }
            case 40: {
              bitField0_ |= 0x00000010;
              isStateless_ = input.readBool();
              break;
            }
            case 48: {
              bitField0_ |= 0x00000020;
              autoCommit_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutRegionTxRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutRegionTxRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccPutRegionTxRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccPutRegionTxRequest>() {
      public SsccPutRegionTxRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccPutRegionTxRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccPutRegionTxRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 tid = 1;
    public static final int TID_FIELD_NUMBER = 1;
    private long tid_;
    /**
     * <code>required int64 tid = 1;</code>
     */
    public boolean hasTid() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 tid = 1;</code>
     */
    public long getTid() {
      return tid_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required .MutationProto put = 4;
    public static final int PUT_FIELD_NUMBER = 4;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto put_;
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    public boolean hasPut() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut() {
      return put_;
    }
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder() {
      return put_;
    }

    // optional bool isStateless = 5;
    public static final int ISSTATELESS_FIELD_NUMBER = 5;
    private boolean isStateless_;
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    public boolean hasIsStateless() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    public boolean getIsStateless() {
      return isStateless_;
    }

    // required bool autoCommit = 6;
    public static final int AUTOCOMMIT_FIELD_NUMBER = 6;
    private boolean autoCommit_;
    /**
     * <code>required bool autoCommit = 6;</code>
     */
    public boolean hasAutoCommit() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>required bool autoCommit = 6;</code>
     */
    public boolean getAutoCommit() {
      return autoCommit_;
    }

    private void initFields() {
      tid_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      isStateless_ = false;
      autoCommit_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTid()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasPut()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasAutoCommit()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getPut().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, tid_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeMessage(4, put_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeBool(5, isStateless_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeBool(6, autoCommit_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, tid_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, put_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(5, isStateless_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(6, autoCommit_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccPutRegionTxRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutRegionTxRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutRegionTxRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getPutFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        tid_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (putBuilder_ == null) {
          put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
        } else {
          putBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        isStateless_ = false;
        bitField0_ = (bitField0_ & ~0x00000010);
        autoCommit_ = false;
        bitField0_ = (bitField0_ & ~0x00000020);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutRegionTxRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.tid_ = tid_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        if (putBuilder_ == null) {
          result.put_ = put_;
        } else {
          result.put_ = putBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.isStateless_ = isStateless_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.autoCommit_ = autoCommit_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest.getDefaultInstance()) return this;
        if (other.hasTid()) {
          setTid(other.getTid());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasPut()) {
          mergePut(other.getPut());
        }
        if (other.hasIsStateless()) {
          setIsStateless(other.getIsStateless());
        }
        if (other.hasAutoCommit()) {
          setAutoCommit(other.getAutoCommit());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTid()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasPut()) {
          
          return false;
        }
        if (!hasAutoCommit()) {
          
          return false;
        }
        if (!getPut().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 tid = 1;
      private long tid_ ;
      /**
       * <code>required int64 tid = 1;</code>
       */
      public boolean hasTid() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public long getTid() {
        return tid_;
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public Builder setTid(long value) {
        bitField0_ |= 0x00000001;
        tid_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 tid = 1;</code>
       */
      public Builder clearTid() {
        bitField0_ = (bitField0_ & ~0x00000001);
        tid_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required .MutationProto put = 4;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> putBuilder_;
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public boolean hasPut() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut() {
        if (putBuilder_ == null) {
          return put_;
        } else {
          return putBuilder_.getMessage();
        }
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public Builder setPut(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          put_ = value;
          onChanged();
        } else {
          putBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public Builder setPut(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (putBuilder_ == null) {
          put_ = builderForValue.build();
          onChanged();
        } else {
          putBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public Builder mergePut(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              put_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance()) {
            put_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.newBuilder(put_).mergeFrom(value).buildPartial();
          } else {
            put_ = value;
          }
          onChanged();
        } else {
          putBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public Builder clearPut() {
        if (putBuilder_ == null) {
          put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
          onChanged();
        } else {
          putBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder getPutBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getPutFieldBuilder().getBuilder();
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder() {
        if (putBuilder_ != null) {
          return putBuilder_.getMessageOrBuilder();
        } else {
          return put_;
        }
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
          getPutFieldBuilder() {
        if (putBuilder_ == null) {
          putBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder>(
                  put_,
                  getParentForChildren(),
                  isClean());
          put_ = null;
        }
        return putBuilder_;
      }

      // optional bool isStateless = 5;
      private boolean isStateless_ ;
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public boolean hasIsStateless() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public boolean getIsStateless() {
        return isStateless_;
      }
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public Builder setIsStateless(boolean value) {
        bitField0_ |= 0x00000010;
        isStateless_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public Builder clearIsStateless() {
        bitField0_ = (bitField0_ & ~0x00000010);
        isStateless_ = false;
        onChanged();
        return this;
      }

      // required bool autoCommit = 6;
      private boolean autoCommit_ ;
      /**
       * <code>required bool autoCommit = 6;</code>
       */
      public boolean hasAutoCommit() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>required bool autoCommit = 6;</code>
       */
      public boolean getAutoCommit() {
        return autoCommit_;
      }
      /**
       * <code>required bool autoCommit = 6;</code>
       */
      public Builder setAutoCommit(boolean value) {
        bitField0_ |= 0x00000020;
        autoCommit_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool autoCommit = 6;</code>
       */
      public Builder clearAutoCommit() {
        bitField0_ = (bitField0_ & ~0x00000020);
        autoCommit_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccPutRegionTxRequest)
    }

    static {
      defaultInstance = new SsccPutRegionTxRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccPutRegionTxRequest)
  }

  public interface SsccPutRegionTxResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional .Result result = 1;
    /**
     * <code>optional .Result result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();

    // optional int32 status = 4;
    /**
     * <code>optional int32 status = 4;</code>
     */
    boolean hasStatus();
    /**
     * <code>optional int32 status = 4;</code>
     */
    int getStatus();
  }
  /**
   * Protobuf type {@code SsccPutRegionTxResponse}
   */
  public static final class SsccPutRegionTxResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccPutRegionTxResponseOrBuilder {
    // Use SsccPutRegionTxResponse.newBuilder() to construct.
    private SsccPutRegionTxResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccPutRegionTxResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccPutRegionTxResponse defaultInstance;
    public static SsccPutRegionTxResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccPutRegionTxResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccPutRegionTxResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = result_.toBuilder();
              }
              result_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(result_);
                result_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              status_ = input.readInt32();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutRegionTxResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutRegionTxResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccPutRegionTxResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccPutRegionTxResponse>() {
      public SsccPutRegionTxResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccPutRegionTxResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccPutRegionTxResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional .Result result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_;
    /**
     * <code>optional .Result result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
      return result_;
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    // optional int32 status = 4;
    public static final int STATUS_FIELD_NUMBER = 4;
    private int status_;
    /**
     * <code>optional int32 status = 4;</code>
     */
    public boolean hasStatus() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int32 status = 4;</code>
     */
    public int getStatus() {
      return status_;
    }

    private void initFields() {
      result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      exception_ = "";
      hasException_ = false;
      status_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt32(4, status_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, status_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccPutRegionTxResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutRegionTxResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutRegionTxResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getResultFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutRegionTxResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (resultBuilder_ == null) {
          result.result_ = result_;
        } else {
          result.result_ = resultBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.status_ = status_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          mergeResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional .Result result = 1;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> resultBuilder_;
      /**
       * <code>optional .Result result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
        if (resultBuilder_ == null) {
          return result_;
        } else {
          return resultBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          result_ = value;
          onChanged();
        } else {
          resultBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder builderForValue) {
        if (resultBuilder_ == null) {
          result_ = builderForValue.build();
          onChanged();
        } else {
          resultBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder mergeResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              result_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance()) {
            result_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.newBuilder(result_).mergeFrom(value).buildPartial();
          } else {
            result_ = value;
          }
          onChanged();
        } else {
          resultBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder clearResult() {
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
          onChanged();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder getResultBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getResultFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
        if (resultBuilder_ != null) {
          return resultBuilder_.getMessageOrBuilder();
        } else {
          return result_;
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
          getResultFieldBuilder() {
        if (resultBuilder_ == null) {
          resultBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder>(
                  result_,
                  getParentForChildren(),
                  isClean());
          result_ = null;
        }
        return resultBuilder_;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // optional int32 status = 4;
      private int status_ ;
      /**
       * <code>optional int32 status = 4;</code>
       */
      public boolean hasStatus() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public int getStatus() {
        return status_;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder setStatus(int value) {
        bitField0_ |= 0x00000008;
        status_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000008);
        status_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccPutRegionTxResponse)
    }

    static {
      defaultInstance = new SsccPutRegionTxResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccPutRegionTxResponse)
  }

  public interface SsccPutTransactionalRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required .MutationProto put = 4;
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    boolean hasPut();
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut();
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder();

    // optional bool isStateless = 5;
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    boolean hasIsStateless();
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    boolean getIsStateless();
  }
  /**
   * Protobuf type {@code SsccPutTransactionalRequest}
   */
  public static final class SsccPutTransactionalRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccPutTransactionalRequestOrBuilder {
    // Use SsccPutTransactionalRequest.newBuilder() to construct.
    private SsccPutTransactionalRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccPutTransactionalRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccPutTransactionalRequest defaultInstance;
    public static SsccPutTransactionalRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccPutTransactionalRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccPutTransactionalRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder subBuilder = null;
              if (((bitField0_ & 0x00000008) == 0x00000008)) {
                subBuilder = put_.toBuilder();
              }
              put_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(put_);
                put_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000008;
              break;
            }
            case 40: {
              bitField0_ |= 0x00000010;
              isStateless_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutTransactionalRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutTransactionalRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccPutTransactionalRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccPutTransactionalRequest>() {
      public SsccPutTransactionalRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccPutTransactionalRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccPutTransactionalRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required .MutationProto put = 4;
    public static final int PUT_FIELD_NUMBER = 4;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto put_;
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    public boolean hasPut() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut() {
      return put_;
    }
    /**
     * <code>required .MutationProto put = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder() {
      return put_;
    }

    // optional bool isStateless = 5;
    public static final int ISSTATELESS_FIELD_NUMBER = 5;
    private boolean isStateless_;
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    public boolean hasIsStateless() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    public boolean getIsStateless() {
      return isStateless_;
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      isStateless_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasPut()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getPut().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeMessage(4, put_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeBool(5, isStateless_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, put_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(5, isStateless_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccPutTransactionalRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutTransactionalRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutTransactionalRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getPutFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (putBuilder_ == null) {
          put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
        } else {
          putBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        isStateless_ = false;
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutTransactionalRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        if (putBuilder_ == null) {
          result.put_ = put_;
        } else {
          result.put_ = putBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.isStateless_ = isStateless_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasPut()) {
          mergePut(other.getPut());
        }
        if (other.hasIsStateless()) {
          setIsStateless(other.getIsStateless());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasPut()) {
          
          return false;
        }
        if (!getPut().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required .MutationProto put = 4;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> putBuilder_;
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public boolean hasPut() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut() {
        if (putBuilder_ == null) {
          return put_;
        } else {
          return putBuilder_.getMessage();
        }
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public Builder setPut(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          put_ = value;
          onChanged();
        } else {
          putBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public Builder setPut(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (putBuilder_ == null) {
          put_ = builderForValue.build();
          onChanged();
        } else {
          putBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public Builder mergePut(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              put_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance()) {
            put_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.newBuilder(put_).mergeFrom(value).buildPartial();
          } else {
            put_ = value;
          }
          onChanged();
        } else {
          putBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public Builder clearPut() {
        if (putBuilder_ == null) {
          put_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance();
          onChanged();
        } else {
          putBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder getPutBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getPutFieldBuilder().getBuilder();
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder() {
        if (putBuilder_ != null) {
          return putBuilder_.getMessageOrBuilder();
        } else {
          return put_;
        }
      }
      /**
       * <code>required .MutationProto put = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
          getPutFieldBuilder() {
        if (putBuilder_ == null) {
          putBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder>(
                  put_,
                  getParentForChildren(),
                  isClean());
          put_ = null;
        }
        return putBuilder_;
      }

      // optional bool isStateless = 5;
      private boolean isStateless_ ;
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public boolean hasIsStateless() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public boolean getIsStateless() {
        return isStateless_;
      }
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public Builder setIsStateless(boolean value) {
        bitField0_ |= 0x00000010;
        isStateless_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public Builder clearIsStateless() {
        bitField0_ = (bitField0_ & ~0x00000010);
        isStateless_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccPutTransactionalRequest)
    }

    static {
      defaultInstance = new SsccPutTransactionalRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccPutTransactionalRequest)
  }

  public interface SsccPutTransactionalResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional .Result result = 1;
    /**
     * <code>optional .Result result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();

    // optional int32 status = 4;
    /**
     * <code>optional int32 status = 4;</code>
     */
    boolean hasStatus();
    /**
     * <code>optional int32 status = 4;</code>
     */
    int getStatus();
  }
  /**
   * Protobuf type {@code SsccPutTransactionalResponse}
   */
  public static final class SsccPutTransactionalResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccPutTransactionalResponseOrBuilder {
    // Use SsccPutTransactionalResponse.newBuilder() to construct.
    private SsccPutTransactionalResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccPutTransactionalResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccPutTransactionalResponse defaultInstance;
    public static SsccPutTransactionalResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccPutTransactionalResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccPutTransactionalResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = result_.toBuilder();
              }
              result_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(result_);
                result_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              status_ = input.readInt32();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutTransactionalResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutTransactionalResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccPutTransactionalResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccPutTransactionalResponse>() {
      public SsccPutTransactionalResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccPutTransactionalResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccPutTransactionalResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional .Result result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_;
    /**
     * <code>optional .Result result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
      return result_;
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    // optional int32 status = 4;
    public static final int STATUS_FIELD_NUMBER = 4;
    private int status_;
    /**
     * <code>optional int32 status = 4;</code>
     */
    public boolean hasStatus() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int32 status = 4;</code>
     */
    public int getStatus() {
      return status_;
    }

    private void initFields() {
      result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      exception_ = "";
      hasException_ = false;
      status_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt32(4, status_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, status_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccPutTransactionalResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutTransactionalResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutTransactionalResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getResultFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutTransactionalResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (resultBuilder_ == null) {
          result.result_ = result_;
        } else {
          result.result_ = resultBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.status_ = status_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          mergeResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional .Result result = 1;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> resultBuilder_;
      /**
       * <code>optional .Result result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
        if (resultBuilder_ == null) {
          return result_;
        } else {
          return resultBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          result_ = value;
          onChanged();
        } else {
          resultBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder builderForValue) {
        if (resultBuilder_ == null) {
          result_ = builderForValue.build();
          onChanged();
        } else {
          resultBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder mergeResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              result_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance()) {
            result_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.newBuilder(result_).mergeFrom(value).buildPartial();
          } else {
            result_ = value;
          }
          onChanged();
        } else {
          resultBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder clearResult() {
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
          onChanged();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder getResultBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getResultFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
        if (resultBuilder_ != null) {
          return resultBuilder_.getMessageOrBuilder();
        } else {
          return result_;
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
          getResultFieldBuilder() {
        if (resultBuilder_ == null) {
          resultBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder>(
                  result_,
                  getParentForChildren(),
                  isClean());
          result_ = null;
        }
        return resultBuilder_;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // optional int32 status = 4;
      private int status_ ;
      /**
       * <code>optional int32 status = 4;</code>
       */
      public boolean hasStatus() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public int getStatus() {
        return status_;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder setStatus(int value) {
        bitField0_ |= 0x00000008;
        status_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000008);
        status_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccPutTransactionalResponse)
    }

    static {
      defaultInstance = new SsccPutTransactionalResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccPutTransactionalResponse)
  }

  public interface SsccPutMultipleTransactionalRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // repeated .MutationProto put = 4;
    /**
     * <code>repeated .MutationProto put = 4;</code>
     */
    java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> 
        getPutList();
    /**
     * <code>repeated .MutationProto put = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut(int index);
    /**
     * <code>repeated .MutationProto put = 4;</code>
     */
    int getPutCount();
    /**
     * <code>repeated .MutationProto put = 4;</code>
     */
    java.util.List<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
        getPutOrBuilderList();
    /**
     * <code>repeated .MutationProto put = 4;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder(
        int index);

    // optional bool isStateless = 5;
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    boolean hasIsStateless();
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    boolean getIsStateless();
  }
  /**
   * Protobuf type {@code SsccPutMultipleTransactionalRequest}
   */
  public static final class SsccPutMultipleTransactionalRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccPutMultipleTransactionalRequestOrBuilder {
    // Use SsccPutMultipleTransactionalRequest.newBuilder() to construct.
    private SsccPutMultipleTransactionalRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccPutMultipleTransactionalRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccPutMultipleTransactionalRequest defaultInstance;
    public static SsccPutMultipleTransactionalRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccPutMultipleTransactionalRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccPutMultipleTransactionalRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 34: {
              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
                put_ = new java.util.ArrayList<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto>();
                mutable_bitField0_ |= 0x00000008;
              }
              put_.add(input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.PARSER, extensionRegistry));
              break;
            }
            case 40: {
              bitField0_ |= 0x00000008;
              isStateless_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
          put_ = java.util.Collections.unmodifiableList(put_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutMultipleTransactionalRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutMultipleTransactionalRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccPutMultipleTransactionalRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccPutMultipleTransactionalRequest>() {
      public SsccPutMultipleTransactionalRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccPutMultipleTransactionalRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccPutMultipleTransactionalRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // repeated .MutationProto put = 4;
    public static final int PUT_FIELD_NUMBER = 4;
    private java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> put_;
    /**
     * <code>repeated .MutationProto put = 4;</code>
     */
    public java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> getPutList() {
      return put_;
    }
    /**
     * <code>repeated .MutationProto put = 4;</code>
     */
    public java.util.List<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
        getPutOrBuilderList() {
      return put_;
    }
    /**
     * <code>repeated .MutationProto put = 4;</code>
     */
    public int getPutCount() {
      return put_.size();
    }
    /**
     * <code>repeated .MutationProto put = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut(int index) {
      return put_.get(index);
    }
    /**
     * <code>repeated .MutationProto put = 4;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder(
        int index) {
      return put_.get(index);
    }

    // optional bool isStateless = 5;
    public static final int ISSTATELESS_FIELD_NUMBER = 5;
    private boolean isStateless_;
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    public boolean hasIsStateless() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional bool isStateless = 5;</code>
     */
    public boolean getIsStateless() {
      return isStateless_;
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      put_ = java.util.Collections.emptyList();
      isStateless_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      for (int i = 0; i < getPutCount(); i++) {
        if (!getPut(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      for (int i = 0; i < put_.size(); i++) {
        output.writeMessage(4, put_.get(i));
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBool(5, isStateless_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      for (int i = 0; i < put_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, put_.get(i));
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(5, isStateless_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccPutMultipleTransactionalRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutMultipleTransactionalRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutMultipleTransactionalRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getPutFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (putBuilder_ == null) {
          put_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000008);
        } else {
          putBuilder_.clear();
        }
        isStateless_ = false;
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutMultipleTransactionalRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (putBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008)) {
            put_ = java.util.Collections.unmodifiableList(put_);
            bitField0_ = (bitField0_ & ~0x00000008);
          }
          result.put_ = put_;
        } else {
          result.put_ = putBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000008;
        }
        result.isStateless_ = isStateless_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (putBuilder_ == null) {
          if (!other.put_.isEmpty()) {
            if (put_.isEmpty()) {
              put_ = other.put_;
              bitField0_ = (bitField0_ & ~0x00000008);
            } else {
              ensurePutIsMutable();
              put_.addAll(other.put_);
            }
            onChanged();
          }
        } else {
          if (!other.put_.isEmpty()) {
            if (putBuilder_.isEmpty()) {
              putBuilder_.dispose();
              putBuilder_ = null;
              put_ = other.put_;
              bitField0_ = (bitField0_ & ~0x00000008);
              putBuilder_ = 
                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getPutFieldBuilder() : null;
            } else {
              putBuilder_.addAllMessages(other.put_);
            }
          }
        }
        if (other.hasIsStateless()) {
          setIsStateless(other.getIsStateless());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        for (int i = 0; i < getPutCount(); i++) {
          if (!getPut(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // repeated .MutationProto put = 4;
      private java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> put_ =
        java.util.Collections.emptyList();
      private void ensurePutIsMutable() {
        if (!((bitField0_ & 0x00000008) == 0x00000008)) {
          put_ = new java.util.ArrayList<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto>(put_);
          bitField0_ |= 0x00000008;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> putBuilder_;

      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> getPutList() {
        if (putBuilder_ == null) {
          return java.util.Collections.unmodifiableList(put_);
        } else {
          return putBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public int getPutCount() {
        if (putBuilder_ == null) {
          return put_.size();
        } else {
          return putBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto getPut(int index) {
        if (putBuilder_ == null) {
          return put_.get(index);
        } else {
          return putBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public Builder setPut(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensurePutIsMutable();
          put_.set(index, value);
          onChanged();
        } else {
          putBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public Builder setPut(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (putBuilder_ == null) {
          ensurePutIsMutable();
          put_.set(index, builderForValue.build());
          onChanged();
        } else {
          putBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public Builder addPut(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensurePutIsMutable();
          put_.add(value);
          onChanged();
        } else {
          putBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public Builder addPut(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto value) {
        if (putBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensurePutIsMutable();
          put_.add(index, value);
          onChanged();
        } else {
          putBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public Builder addPut(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (putBuilder_ == null) {
          ensurePutIsMutable();
          put_.add(builderForValue.build());
          onChanged();
        } else {
          putBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public Builder addPut(
          int index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder builderForValue) {
        if (putBuilder_ == null) {
          ensurePutIsMutable();
          put_.add(index, builderForValue.build());
          onChanged();
        } else {
          putBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public Builder addAllPut(
          java.lang.Iterable<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto> values) {
        if (putBuilder_ == null) {
          ensurePutIsMutable();
          super.addAll(values, put_);
          onChanged();
        } else {
          putBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public Builder clearPut() {
        if (putBuilder_ == null) {
          put_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000008);
          onChanged();
        } else {
          putBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public Builder removePut(int index) {
        if (putBuilder_ == null) {
          ensurePutIsMutable();
          put_.remove(index);
          onChanged();
        } else {
          putBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder getPutBuilder(
          int index) {
        return getPutFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder getPutOrBuilder(
          int index) {
        if (putBuilder_ == null) {
          return put_.get(index);  } else {
          return putBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public java.util.List<? extends org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
           getPutOrBuilderList() {
        if (putBuilder_ != null) {
          return putBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(put_);
        }
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder addPutBuilder() {
        return getPutFieldBuilder().addBuilder(
            org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance());
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder addPutBuilder(
          int index) {
        return getPutFieldBuilder().addBuilder(
            index, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.getDefaultInstance());
      }
      /**
       * <code>repeated .MutationProto put = 4;</code>
       */
      public java.util.List<org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder> 
           getPutBuilderList() {
        return getPutFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder> 
          getPutFieldBuilder() {
        if (putBuilder_ == null) {
          putBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProtoOrBuilder>(
                  put_,
                  ((bitField0_ & 0x00000008) == 0x00000008),
                  getParentForChildren(),
                  isClean());
          put_ = null;
        }
        return putBuilder_;
      }

      // optional bool isStateless = 5;
      private boolean isStateless_ ;
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public boolean hasIsStateless() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public boolean getIsStateless() {
        return isStateless_;
      }
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public Builder setIsStateless(boolean value) {
        bitField0_ |= 0x00000010;
        isStateless_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool isStateless = 5;</code>
       */
      public Builder clearIsStateless() {
        bitField0_ = (bitField0_ & ~0x00000010);
        isStateless_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccPutMultipleTransactionalRequest)
    }

    static {
      defaultInstance = new SsccPutMultipleTransactionalRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccPutMultipleTransactionalRequest)
  }

  public interface SsccPutMultipleTransactionalResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // optional .Result result = 1;
    /**
     * <code>optional .Result result = 1;</code>
     */
    boolean hasResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult();
    /**
     * <code>optional .Result result = 1;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder();

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();

    // optional int32 status = 4;
    /**
     * <code>optional int32 status = 4;</code>
     */
    boolean hasStatus();
    /**
     * <code>optional int32 status = 4;</code>
     */
    int getStatus();
  }
  /**
   * Protobuf type {@code SsccPutMultipleTransactionalResponse}
   */
  public static final class SsccPutMultipleTransactionalResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccPutMultipleTransactionalResponseOrBuilder {
    // Use SsccPutMultipleTransactionalResponse.newBuilder() to construct.
    private SsccPutMultipleTransactionalResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccPutMultipleTransactionalResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccPutMultipleTransactionalResponse defaultInstance;
    public static SsccPutMultipleTransactionalResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccPutMultipleTransactionalResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccPutMultipleTransactionalResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = result_.toBuilder();
              }
              result_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(result_);
                result_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              hasException_ = input.readBool();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              status_ = input.readInt32();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutMultipleTransactionalResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutMultipleTransactionalResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccPutMultipleTransactionalResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccPutMultipleTransactionalResponse>() {
      public SsccPutMultipleTransactionalResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccPutMultipleTransactionalResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccPutMultipleTransactionalResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // optional .Result result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_;
    /**
     * <code>optional .Result result = 1;</code>
     */
    public boolean hasResult() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
      return result_;
    }
    /**
     * <code>optional .Result result = 1;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
      return result_;
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    // optional int32 status = 4;
    public static final int STATUS_FIELD_NUMBER = 4;
    private int status_;
    /**
     * <code>optional int32 status = 4;</code>
     */
    public boolean hasStatus() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int32 status = 4;</code>
     */
    public int getStatus() {
      return status_;
    }

    private void initFields() {
      result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      exception_ = "";
      hasException_ = false;
      status_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt32(4, status_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, result_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, status_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccPutMultipleTransactionalResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutMultipleTransactionalResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutMultipleTransactionalResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getResultFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccPutMultipleTransactionalResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (resultBuilder_ == null) {
          result.result_ = result_;
        } else {
          result.result_ = resultBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.hasException_ = hasException_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.status_ = status_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.getDefaultInstance()) return this;
        if (other.hasResult()) {
          mergeResult(other.getResult());
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // optional .Result result = 1;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> resultBuilder_;
      /**
       * <code>optional .Result result = 1;</code>
       */
      public boolean hasResult() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result getResult() {
        if (resultBuilder_ == null) {
          return result_;
        } else {
          return resultBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          result_ = value;
          onChanged();
        } else {
          resultBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder setResult(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder builderForValue) {
        if (resultBuilder_ == null) {
          result_ = builderForValue.build();
          onChanged();
        } else {
          resultBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder mergeResult(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result value) {
        if (resultBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              result_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance()) {
            result_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.newBuilder(result_).mergeFrom(value).buildPartial();
          } else {
            result_ = value;
          }
          onChanged();
        } else {
          resultBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public Builder clearResult() {
        if (resultBuilder_ == null) {
          result_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.getDefaultInstance();
          onChanged();
        } else {
          resultBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder getResultBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getResultFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder getResultOrBuilder() {
        if (resultBuilder_ != null) {
          return resultBuilder_.getMessageOrBuilder();
        } else {
          return result_;
        }
      }
      /**
       * <code>optional .Result result = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder> 
          getResultFieldBuilder() {
        if (resultBuilder_ == null) {
          resultBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Result.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrBuilder>(
                  result_,
                  getParentForChildren(),
                  isClean());
          result_ = null;
        }
        return resultBuilder_;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // optional int32 status = 4;
      private int status_ ;
      /**
       * <code>optional int32 status = 4;</code>
       */
      public boolean hasStatus() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public int getStatus() {
        return status_;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder setStatus(int value) {
        bitField0_ |= 0x00000008;
        status_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 status = 4;</code>
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000008);
        status_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccPutMultipleTransactionalResponse)
    }

    static {
      defaultInstance = new SsccPutMultipleTransactionalResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccPutMultipleTransactionalResponse)
  }

  public interface SsccRecoveryRequestRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 transactionId = 1;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    long getTransactionId();

    // required int64 startId = 2;
    /**
     * <code>required int64 startId = 2;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 2;</code>
     */
    long getStartId();

    // required bytes regionName = 3;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 3;</code>
     */
    com.google.protobuf.ByteString getRegionName();

    // required int32 tmId = 4;
    /**
     * <code>required int32 tmId = 4;</code>
     */
    boolean hasTmId();
    /**
     * <code>required int32 tmId = 4;</code>
     */
    int getTmId();
  }
  /**
   * Protobuf type {@code SsccRecoveryRequestRequest}
   */
  public static final class SsccRecoveryRequestRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccRecoveryRequestRequestOrBuilder {
    // Use SsccRecoveryRequestRequest.newBuilder() to construct.
    private SsccRecoveryRequestRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccRecoveryRequestRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccRecoveryRequestRequest defaultInstance;
    public static SsccRecoveryRequestRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccRecoveryRequestRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccRecoveryRequestRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              transactionId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startId_ = input.readInt64();
              break;
            }
            case 26: {
              bitField0_ |= 0x00000004;
              regionName_ = input.readBytes();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              tmId_ = input.readInt32();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccRecoveryRequestRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccRecoveryRequestRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccRecoveryRequestRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccRecoveryRequestRequest>() {
      public SsccRecoveryRequestRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccRecoveryRequestRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccRecoveryRequestRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required int64 transactionId = 1;
    public static final int TRANSACTIONID_FIELD_NUMBER = 1;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 transactionId = 1;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 2;
    public static final int STARTID_FIELD_NUMBER = 2;
    private long startId_;
    /**
     * <code>required int64 startId = 2;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 startId = 2;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required bytes regionName = 3;
    public static final int REGIONNAME_FIELD_NUMBER = 3;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bytes regionName = 3;</code>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required int32 tmId = 4;
    public static final int TMID_FIELD_NUMBER = 4;
    private int tmId_;
    /**
     * <code>required int32 tmId = 4;</code>
     */
    public boolean hasTmId() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required int32 tmId = 4;</code>
     */
    public int getTmId() {
      return tmId_;
    }

    private void initFields() {
      transactionId_ = 0L;
      startId_ = 0L;
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      tmId_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasTmId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBytes(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt32(4, tmId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, transactionId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, startId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(3, regionName_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, tmId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccRecoveryRequestRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccRecoveryRequestRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccRecoveryRequestRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000004);
        tmId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccRecoveryRequestRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.tmId_ = tmId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest.getDefaultInstance()) return this;
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasTmId()) {
          setTmId(other.getTmId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasTmId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 transactionId = 1;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000001;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 1;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 2;
      private long startId_ ;
      /**
       * <code>required int64 startId = 2;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000002;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 2;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required bytes regionName = 3;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 3;</code>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required int32 tmId = 4;
      private int tmId_ ;
      /**
       * <code>required int32 tmId = 4;</code>
       */
      public boolean hasTmId() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required int32 tmId = 4;</code>
       */
      public int getTmId() {
        return tmId_;
      }
      /**
       * <code>required int32 tmId = 4;</code>
       */
      public Builder setTmId(int value) {
        bitField0_ |= 0x00000008;
        tmId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 tmId = 4;</code>
       */
      public Builder clearTmId() {
        bitField0_ = (bitField0_ & ~0x00000008);
        tmId_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccRecoveryRequestRequest)
    }

    static {
      defaultInstance = new SsccRecoveryRequestRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccRecoveryRequestRequest)
  }

  public interface SsccRecoveryRequestResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // repeated int64 result = 1;
    /**
     * <code>repeated int64 result = 1;</code>
     */
    java.util.List<java.lang.Long> getResultList();
    /**
     * <code>repeated int64 result = 1;</code>
     */
    int getResultCount();
    /**
     * <code>repeated int64 result = 1;</code>
     */
    long getResult(int index);

    // optional string exception = 2;
    /**
     * <code>optional string exception = 2;</code>
     */
    boolean hasException();
    /**
     * <code>optional string exception = 2;</code>
     */
    java.lang.String getException();
    /**
     * <code>optional string exception = 2;</code>
     */
    com.google.protobuf.ByteString
        getExceptionBytes();

    // optional bool hasException = 3;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean hasHasException();
    /**
     * <code>optional bool hasException = 3;</code>
     */
    boolean getHasException();
  }
  /**
   * Protobuf type {@code SsccRecoveryRequestResponse}
   */
  public static final class SsccRecoveryRequestResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccRecoveryRequestResponseOrBuilder {
    // Use SsccRecoveryRequestResponse.newBuilder() to construct.
    private SsccRecoveryRequestResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccRecoveryRequestResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccRecoveryRequestResponse defaultInstance;
    public static SsccRecoveryRequestResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccRecoveryRequestResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccRecoveryRequestResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                result_ = new java.util.ArrayList<java.lang.Long>();
                mutable_bitField0_ |= 0x00000001;
              }
              result_.add(input.readInt64());
              break;
            }
            case 10: {
              int length = input.readRawVarint32();
              int limit = input.pushLimit(length);
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001) && input.getBytesUntilLimit() > 0) {
                result_ = new java.util.ArrayList<java.lang.Long>();
                mutable_bitField0_ |= 0x00000001;
              }
              while (input.getBytesUntilLimit() > 0) {
                result_.add(input.readInt64());
              }
              input.popLimit(limit);
              break;
            }
            case 18: {
              bitField0_ |= 0x00000001;
              exception_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000002;
              hasException_ = input.readBool();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          result_ = java.util.Collections.unmodifiableList(result_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccRecoveryRequestResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccRecoveryRequestResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccRecoveryRequestResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccRecoveryRequestResponse>() {
      public SsccRecoveryRequestResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccRecoveryRequestResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccRecoveryRequestResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // repeated int64 result = 1;
    public static final int RESULT_FIELD_NUMBER = 1;
    private java.util.List<java.lang.Long> result_;
    /**
     * <code>repeated int64 result = 1;</code>
     */
    public java.util.List<java.lang.Long>
        getResultList() {
      return result_;
    }
    /**
     * <code>repeated int64 result = 1;</code>
     */
    public int getResultCount() {
      return result_.size();
    }
    /**
     * <code>repeated int64 result = 1;</code>
     */
    public long getResult(int index) {
      return result_.get(index);
    }

    // optional string exception = 2;
    public static final int EXCEPTION_FIELD_NUMBER = 2;
    private java.lang.Object exception_;
    /**
     * <code>optional string exception = 2;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public java.lang.String getException() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          exception_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception = 2;</code>
     */
    public com.google.protobuf.ByteString
        getExceptionBytes() {
      java.lang.Object ref = exception_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exception_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional bool hasException = 3;
    public static final int HASEXCEPTION_FIELD_NUMBER = 3;
    private boolean hasException_;
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean hasHasException() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional bool hasException = 3;</code>
     */
    public boolean getHasException() {
      return hasException_;
    }

    private void initFields() {
      result_ = java.util.Collections.emptyList();
      exception_ = "";
      hasException_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < result_.size(); i++) {
        output.writeInt64(1, result_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBool(3, hasException_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      {
        int dataSize = 0;
        for (int i = 0; i < result_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeInt64SizeNoTag(result_.get(i));
        }
        size += dataSize;
        size += 1 * getResultList().size();
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getExceptionBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, hasException_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccRecoveryRequestResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccRecoveryRequestResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccRecoveryRequestResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        result_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000001);
        exception_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        hasException_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccRecoveryRequestResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((bitField0_ & 0x00000001) == 0x00000001)) {
          result_ = java.util.Collections.unmodifiableList(result_);
          bitField0_ = (bitField0_ & ~0x00000001);
        }
        result.result_ = result_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000001;
        }
        result.exception_ = exception_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000002;
        }
        result.hasException_ = hasException_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.getDefaultInstance()) return this;
        if (!other.result_.isEmpty()) {
          if (result_.isEmpty()) {
            result_ = other.result_;
            bitField0_ = (bitField0_ & ~0x00000001);
          } else {
            ensureResultIsMutable();
            result_.addAll(other.result_);
          }
          onChanged();
        }
        if (other.hasException()) {
          bitField0_ |= 0x00000002;
          exception_ = other.exception_;
          onChanged();
        }
        if (other.hasHasException()) {
          setHasException(other.getHasException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // repeated int64 result = 1;
      private java.util.List<java.lang.Long> result_ = java.util.Collections.emptyList();
      private void ensureResultIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          result_ = new java.util.ArrayList<java.lang.Long>(result_);
          bitField0_ |= 0x00000001;
         }
      }
      /**
       * <code>repeated int64 result = 1;</code>
       */
      public java.util.List<java.lang.Long>
          getResultList() {
        return java.util.Collections.unmodifiableList(result_);
      }
      /**
       * <code>repeated int64 result = 1;</code>
       */
      public int getResultCount() {
        return result_.size();
      }
      /**
       * <code>repeated int64 result = 1;</code>
       */
      public long getResult(int index) {
        return result_.get(index);
      }
      /**
       * <code>repeated int64 result = 1;</code>
       */
      public Builder setResult(
          int index, long value) {
        ensureResultIsMutable();
        result_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int64 result = 1;</code>
       */
      public Builder addResult(long value) {
        ensureResultIsMutable();
        result_.add(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int64 result = 1;</code>
       */
      public Builder addAllResult(
          java.lang.Iterable<? extends java.lang.Long> values) {
        ensureResultIsMutable();
        super.addAll(values, result_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int64 result = 1;</code>
       */
      public Builder clearResult() {
        result_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000001);
        onChanged();
        return this;
      }

      // optional string exception = 2;
      private java.lang.Object exception_ = "";
      /**
       * <code>optional string exception = 2;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public java.lang.String getException() {
        java.lang.Object ref = exception_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          exception_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public com.google.protobuf.ByteString
          getExceptionBytes() {
        java.lang.Object ref = exception_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exception_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setException(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder clearException() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exception_ = getDefaultInstance().getException();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception = 2;</code>
       */
      public Builder setExceptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        exception_ = value;
        onChanged();
        return this;
      }

      // optional bool hasException = 3;
      private boolean hasException_ ;
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean hasHasException() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public boolean getHasException() {
        return hasException_;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder setHasException(boolean value) {
        bitField0_ |= 0x00000004;
        hasException_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool hasException = 3;</code>
       */
      public Builder clearHasException() {
        bitField0_ = (bitField0_ & ~0x00000004);
        hasException_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccRecoveryRequestResponse)
    }

    static {
      defaultInstance = new SsccRecoveryRequestResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccRecoveryRequestResponse)
  }

  public interface SsccTransactionalAggregateRequestOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required bytes regionName = 1;
    /**
     * <code>required bytes regionName = 1;</code>
     *
     * <pre>
     ** The request passed to the TransactionalAggregateService consists of three parts
     *  (1) the (canonical) classname of the ColumnInterpreter implementation
     *  (2) the Scan query
     *  (3) any bytes required to construct the ColumnInterpreter object
     *      properly
     * </pre>
     */
    boolean hasRegionName();
    /**
     * <code>required bytes regionName = 1;</code>
     *
     * <pre>
     ** The request passed to the TransactionalAggregateService consists of three parts
     *  (1) the (canonical) classname of the ColumnInterpreter implementation
     *  (2) the Scan query
     *  (3) any bytes required to construct the ColumnInterpreter object
     *      properly
     * </pre>
     */
    com.google.protobuf.ByteString getRegionName();

    // required int64 transactionId = 2;
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    boolean hasTransactionId();
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    long getTransactionId();

    // required int64 startId = 3;
    /**
     * <code>required int64 startId = 3;</code>
     */
    boolean hasStartId();
    /**
     * <code>required int64 startId = 3;</code>
     */
    long getStartId();

    // required string interpreter_class_name = 4;
    /**
     * <code>required string interpreter_class_name = 4;</code>
     */
    boolean hasInterpreterClassName();
    /**
     * <code>required string interpreter_class_name = 4;</code>
     */
    java.lang.String getInterpreterClassName();
    /**
     * <code>required string interpreter_class_name = 4;</code>
     */
    com.google.protobuf.ByteString
        getInterpreterClassNameBytes();

    // required .Scan scan = 5;
    /**
     * <code>required .Scan scan = 5;</code>
     */
    boolean hasScan();
    /**
     * <code>required .Scan scan = 5;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan getScan();
    /**
     * <code>required .Scan scan = 5;</code>
     */
    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder getScanOrBuilder();

    // optional bytes interpreter_specific_bytes = 6;
    /**
     * <code>optional bytes interpreter_specific_bytes = 6;</code>
     */
    boolean hasInterpreterSpecificBytes();
    /**
     * <code>optional bytes interpreter_specific_bytes = 6;</code>
     */
    com.google.protobuf.ByteString getInterpreterSpecificBytes();
  }
  /**
   * Protobuf type {@code SsccTransactionalAggregateRequest}
   */
  public static final class SsccTransactionalAggregateRequest extends
      com.google.protobuf.GeneratedMessage
      implements SsccTransactionalAggregateRequestOrBuilder {
    // Use SsccTransactionalAggregateRequest.newBuilder() to construct.
    private SsccTransactionalAggregateRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccTransactionalAggregateRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccTransactionalAggregateRequest defaultInstance;
    public static SsccTransactionalAggregateRequest getDefaultInstance() {
      return defaultInstance;
    }

    public SsccTransactionalAggregateRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccTransactionalAggregateRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              regionName_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              transactionId_ = input.readInt64();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              startId_ = input.readInt64();
              break;
            }
            case 34: {
              bitField0_ |= 0x00000008;
              interpreterClassName_ = input.readBytes();
              break;
            }
            case 42: {
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder subBuilder = null;
              if (((bitField0_ & 0x00000010) == 0x00000010)) {
                subBuilder = scan_.toBuilder();
              }
              scan_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(scan_);
                scan_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000010;
              break;
            }
            case 50: {
              bitField0_ |= 0x00000020;
              interpreterSpecificBytes_ = input.readBytes();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccTransactionalAggregateRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccTransactionalAggregateRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccTransactionalAggregateRequest> PARSER =
        new com.google.protobuf.AbstractParser<SsccTransactionalAggregateRequest>() {
      public SsccTransactionalAggregateRequest parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccTransactionalAggregateRequest(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccTransactionalAggregateRequest> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // required bytes regionName = 1;
    public static final int REGIONNAME_FIELD_NUMBER = 1;
    private com.google.protobuf.ByteString regionName_;
    /**
     * <code>required bytes regionName = 1;</code>
     *
     * <pre>
     ** The request passed to the TransactionalAggregateService consists of three parts
     *  (1) the (canonical) classname of the ColumnInterpreter implementation
     *  (2) the Scan query
     *  (3) any bytes required to construct the ColumnInterpreter object
     *      properly
     * </pre>
     */
    public boolean hasRegionName() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required bytes regionName = 1;</code>
     *
     * <pre>
     ** The request passed to the TransactionalAggregateService consists of three parts
     *  (1) the (canonical) classname of the ColumnInterpreter implementation
     *  (2) the Scan query
     *  (3) any bytes required to construct the ColumnInterpreter object
     *      properly
     * </pre>
     */
    public com.google.protobuf.ByteString getRegionName() {
      return regionName_;
    }

    // required int64 transactionId = 2;
    public static final int TRANSACTIONID_FIELD_NUMBER = 2;
    private long transactionId_;
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    public boolean hasTransactionId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 transactionId = 2;</code>
     */
    public long getTransactionId() {
      return transactionId_;
    }

    // required int64 startId = 3;
    public static final int STARTID_FIELD_NUMBER = 3;
    private long startId_;
    /**
     * <code>required int64 startId = 3;</code>
     */
    public boolean hasStartId() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required int64 startId = 3;</code>
     */
    public long getStartId() {
      return startId_;
    }

    // required string interpreter_class_name = 4;
    public static final int INTERPRETER_CLASS_NAME_FIELD_NUMBER = 4;
    private java.lang.Object interpreterClassName_;
    /**
     * <code>required string interpreter_class_name = 4;</code>
     */
    public boolean hasInterpreterClassName() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required string interpreter_class_name = 4;</code>
     */
    public java.lang.String getInterpreterClassName() {
      java.lang.Object ref = interpreterClassName_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          interpreterClassName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>required string interpreter_class_name = 4;</code>
     */
    public com.google.protobuf.ByteString
        getInterpreterClassNameBytes() {
      java.lang.Object ref = interpreterClassName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        interpreterClassName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // required .Scan scan = 5;
    public static final int SCAN_FIELD_NUMBER = 5;
    private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan scan_;
    /**
     * <code>required .Scan scan = 5;</code>
     */
    public boolean hasScan() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>required .Scan scan = 5;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan getScan() {
      return scan_;
    }
    /**
     * <code>required .Scan scan = 5;</code>
     */
    public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder getScanOrBuilder() {
      return scan_;
    }

    // optional bytes interpreter_specific_bytes = 6;
    public static final int INTERPRETER_SPECIFIC_BYTES_FIELD_NUMBER = 6;
    private com.google.protobuf.ByteString interpreterSpecificBytes_;
    /**
     * <code>optional bytes interpreter_specific_bytes = 6;</code>
     */
    public boolean hasInterpreterSpecificBytes() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>optional bytes interpreter_specific_bytes = 6;</code>
     */
    public com.google.protobuf.ByteString getInterpreterSpecificBytes() {
      return interpreterSpecificBytes_;
    }

    private void initFields() {
      regionName_ = com.google.protobuf.ByteString.EMPTY;
      transactionId_ = 0L;
      startId_ = 0L;
      interpreterClassName_ = "";
      scan_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.getDefaultInstance();
      interpreterSpecificBytes_ = com.google.protobuf.ByteString.EMPTY;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasRegionName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasTransactionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasInterpreterClassName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasScan()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getScan().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, regionName_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, transactionId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt64(3, startId_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBytes(4, getInterpreterClassNameBytes());
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeMessage(5, scan_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeBytes(6, interpreterSpecificBytes_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, regionName_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, transactionId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, startId_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(4, getInterpreterClassNameBytes());
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, scan_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(6, interpreterSpecificBytes_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccTransactionalAggregateRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccTransactionalAggregateRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccTransactionalAggregateRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getScanFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        regionName_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000001);
        transactionId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        startId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000004);
        interpreterClassName_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        if (scanBuilder_ == null) {
          scan_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.getDefaultInstance();
        } else {
          scanBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        interpreterSpecificBytes_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000020);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccTransactionalAggregateRequest_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.regionName_ = regionName_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.transactionId_ = transactionId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.startId_ = startId_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.interpreterClassName_ = interpreterClassName_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        if (scanBuilder_ == null) {
          result.scan_ = scan_;
        } else {
          result.scan_ = scanBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.interpreterSpecificBytes_ = interpreterSpecificBytes_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance()) return this;
        if (other.hasRegionName()) {
          setRegionName(other.getRegionName());
        }
        if (other.hasTransactionId()) {
          setTransactionId(other.getTransactionId());
        }
        if (other.hasStartId()) {
          setStartId(other.getStartId());
        }
        if (other.hasInterpreterClassName()) {
          bitField0_ |= 0x00000008;
          interpreterClassName_ = other.interpreterClassName_;
          onChanged();
        }
        if (other.hasScan()) {
          mergeScan(other.getScan());
        }
        if (other.hasInterpreterSpecificBytes()) {
          setInterpreterSpecificBytes(other.getInterpreterSpecificBytes());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasRegionName()) {
          
          return false;
        }
        if (!hasTransactionId()) {
          
          return false;
        }
        if (!hasStartId()) {
          
          return false;
        }
        if (!hasInterpreterClassName()) {
          
          return false;
        }
        if (!hasScan()) {
          
          return false;
        }
        if (!getScan().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required bytes regionName = 1;
      private com.google.protobuf.ByteString regionName_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>required bytes regionName = 1;</code>
       *
       * <pre>
       ** The request passed to the TransactionalAggregateService consists of three parts
       *  (1) the (canonical) classname of the ColumnInterpreter implementation
       *  (2) the Scan query
       *  (3) any bytes required to construct the ColumnInterpreter object
       *      properly
       * </pre>
       */
      public boolean hasRegionName() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required bytes regionName = 1;</code>
       *
       * <pre>
       ** The request passed to the TransactionalAggregateService consists of three parts
       *  (1) the (canonical) classname of the ColumnInterpreter implementation
       *  (2) the Scan query
       *  (3) any bytes required to construct the ColumnInterpreter object
       *      properly
       * </pre>
       */
      public com.google.protobuf.ByteString getRegionName() {
        return regionName_;
      }
      /**
       * <code>required bytes regionName = 1;</code>
       *
       * <pre>
       ** The request passed to the TransactionalAggregateService consists of three parts
       *  (1) the (canonical) classname of the ColumnInterpreter implementation
       *  (2) the Scan query
       *  (3) any bytes required to construct the ColumnInterpreter object
       *      properly
       * </pre>
       */
      public Builder setRegionName(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        regionName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bytes regionName = 1;</code>
       *
       * <pre>
       ** The request passed to the TransactionalAggregateService consists of three parts
       *  (1) the (canonical) classname of the ColumnInterpreter implementation
       *  (2) the Scan query
       *  (3) any bytes required to construct the ColumnInterpreter object
       *      properly
       * </pre>
       */
      public Builder clearRegionName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        regionName_ = getDefaultInstance().getRegionName();
        onChanged();
        return this;
      }

      // required int64 transactionId = 2;
      private long transactionId_ ;
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public boolean hasTransactionId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public long getTransactionId() {
        return transactionId_;
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public Builder setTransactionId(long value) {
        bitField0_ |= 0x00000002;
        transactionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 transactionId = 2;</code>
       */
      public Builder clearTransactionId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        transactionId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 startId = 3;
      private long startId_ ;
      /**
       * <code>required int64 startId = 3;</code>
       */
      public boolean hasStartId() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required int64 startId = 3;</code>
       */
      public long getStartId() {
        return startId_;
      }
      /**
       * <code>required int64 startId = 3;</code>
       */
      public Builder setStartId(long value) {
        bitField0_ |= 0x00000004;
        startId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 startId = 3;</code>
       */
      public Builder clearStartId() {
        bitField0_ = (bitField0_ & ~0x00000004);
        startId_ = 0L;
        onChanged();
        return this;
      }

      // required string interpreter_class_name = 4;
      private java.lang.Object interpreterClassName_ = "";
      /**
       * <code>required string interpreter_class_name = 4;</code>
       */
      public boolean hasInterpreterClassName() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required string interpreter_class_name = 4;</code>
       */
      public java.lang.String getInterpreterClassName() {
        java.lang.Object ref = interpreterClassName_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          interpreterClassName_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>required string interpreter_class_name = 4;</code>
       */
      public com.google.protobuf.ByteString
          getInterpreterClassNameBytes() {
        java.lang.Object ref = interpreterClassName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          interpreterClassName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>required string interpreter_class_name = 4;</code>
       */
      public Builder setInterpreterClassName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        interpreterClassName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required string interpreter_class_name = 4;</code>
       */
      public Builder clearInterpreterClassName() {
        bitField0_ = (bitField0_ & ~0x00000008);
        interpreterClassName_ = getDefaultInstance().getInterpreterClassName();
        onChanged();
        return this;
      }
      /**
       * <code>required string interpreter_class_name = 4;</code>
       */
      public Builder setInterpreterClassNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        interpreterClassName_ = value;
        onChanged();
        return this;
      }

      // required .Scan scan = 5;
      private org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan scan_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder> scanBuilder_;
      /**
       * <code>required .Scan scan = 5;</code>
       */
      public boolean hasScan() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>required .Scan scan = 5;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan getScan() {
        if (scanBuilder_ == null) {
          return scan_;
        } else {
          return scanBuilder_.getMessage();
        }
      }
      /**
       * <code>required .Scan scan = 5;</code>
       */
      public Builder setScan(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan value) {
        if (scanBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          scan_ = value;
          onChanged();
        } else {
          scanBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>required .Scan scan = 5;</code>
       */
      public Builder setScan(
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder builderForValue) {
        if (scanBuilder_ == null) {
          scan_ = builderForValue.build();
          onChanged();
        } else {
          scanBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>required .Scan scan = 5;</code>
       */
      public Builder mergeScan(org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan value) {
        if (scanBuilder_ == null) {
          if (((bitField0_ & 0x00000010) == 0x00000010) &&
              scan_ != org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.getDefaultInstance()) {
            scan_ =
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.newBuilder(scan_).mergeFrom(value).buildPartial();
          } else {
            scan_ = value;
          }
          onChanged();
        } else {
          scanBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>required .Scan scan = 5;</code>
       */
      public Builder clearScan() {
        if (scanBuilder_ == null) {
          scan_ = org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.getDefaultInstance();
          onChanged();
        } else {
          scanBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }
      /**
       * <code>required .Scan scan = 5;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder getScanBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getScanFieldBuilder().getBuilder();
      }
      /**
       * <code>required .Scan scan = 5;</code>
       */
      public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder getScanOrBuilder() {
        if (scanBuilder_ != null) {
          return scanBuilder_.getMessageOrBuilder();
        } else {
          return scan_;
        }
      }
      /**
       * <code>required .Scan scan = 5;</code>
       */
      private com.google.protobuf.SingleFieldBuilder<
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder> 
          getScanFieldBuilder() {
        if (scanBuilder_ == null) {
          scanBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.Scan.Builder, org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanOrBuilder>(
                  scan_,
                  getParentForChildren(),
                  isClean());
          scan_ = null;
        }
        return scanBuilder_;
      }

      // optional bytes interpreter_specific_bytes = 6;
      private com.google.protobuf.ByteString interpreterSpecificBytes_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>optional bytes interpreter_specific_bytes = 6;</code>
       */
      public boolean hasInterpreterSpecificBytes() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>optional bytes interpreter_specific_bytes = 6;</code>
       */
      public com.google.protobuf.ByteString getInterpreterSpecificBytes() {
        return interpreterSpecificBytes_;
      }
      /**
       * <code>optional bytes interpreter_specific_bytes = 6;</code>
       */
      public Builder setInterpreterSpecificBytes(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        interpreterSpecificBytes_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bytes interpreter_specific_bytes = 6;</code>
       */
      public Builder clearInterpreterSpecificBytes() {
        bitField0_ = (bitField0_ & ~0x00000020);
        interpreterSpecificBytes_ = getDefaultInstance().getInterpreterSpecificBytes();
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccTransactionalAggregateRequest)
    }

    static {
      defaultInstance = new SsccTransactionalAggregateRequest(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccTransactionalAggregateRequest)
  }

  public interface SsccTransactionalAggregateResponseOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // repeated bytes first_part = 3;
    /**
     * <code>repeated bytes first_part = 3;</code>
     *
     * <pre>
     **
     * The TransactionalAggregateService methods all have a response that either is a Pair
     * or a simple object. When it is a Pair both first_part and second_part
     * have defined values (and the second_part is not present in the response
     * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
     * class for an overview of the TransactionalAggregateResponse object constructions. 
     * </pre>
     */
    java.util.List<com.google.protobuf.ByteString> getFirstPartList();
    /**
     * <code>repeated bytes first_part = 3;</code>
     *
     * <pre>
     **
     * The TransactionalAggregateService methods all have a response that either is a Pair
     * or a simple object. When it is a Pair both first_part and second_part
     * have defined values (and the second_part is not present in the response
     * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
     * class for an overview of the TransactionalAggregateResponse object constructions. 
     * </pre>
     */
    int getFirstPartCount();
    /**
     * <code>repeated bytes first_part = 3;</code>
     *
     * <pre>
     **
     * The TransactionalAggregateService methods all have a response that either is a Pair
     * or a simple object. When it is a Pair both first_part and second_part
     * have defined values (and the second_part is not present in the response
     * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
     * class for an overview of the TransactionalAggregateResponse object constructions. 
     * </pre>
     */
    com.google.protobuf.ByteString getFirstPart(int index);

    // optional bytes second_part = 4;
    /**
     * <code>optional bytes second_part = 4;</code>
     */
    boolean hasSecondPart();
    /**
     * <code>optional bytes second_part = 4;</code>
     */
    com.google.protobuf.ByteString getSecondPart();
  }
  /**
   * Protobuf type {@code SsccTransactionalAggregateResponse}
   */
  public static final class SsccTransactionalAggregateResponse extends
      com.google.protobuf.GeneratedMessage
      implements SsccTransactionalAggregateResponseOrBuilder {
    // Use SsccTransactionalAggregateResponse.newBuilder() to construct.
    private SsccTransactionalAggregateResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SsccTransactionalAggregateResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SsccTransactionalAggregateResponse defaultInstance;
    public static SsccTransactionalAggregateResponse getDefaultInstance() {
      return defaultInstance;
    }

    public SsccTransactionalAggregateResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SsccTransactionalAggregateResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 26: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                firstPart_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
                mutable_bitField0_ |= 0x00000001;
              }
              firstPart_.add(input.readBytes());
              break;
            }
            case 34: {
              bitField0_ |= 0x00000001;
              secondPart_ = input.readBytes();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          firstPart_ = java.util.Collections.unmodifiableList(firstPart_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccTransactionalAggregateResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccTransactionalAggregateResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.Builder.class);
    }

    public static com.google.protobuf.Parser<SsccTransactionalAggregateResponse> PARSER =
        new com.google.protobuf.AbstractParser<SsccTransactionalAggregateResponse>() {
      public SsccTransactionalAggregateResponse parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new SsccTransactionalAggregateResponse(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public com.google.protobuf.Parser<SsccTransactionalAggregateResponse> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    // repeated bytes first_part = 3;
    public static final int FIRST_PART_FIELD_NUMBER = 3;
    private java.util.List<com.google.protobuf.ByteString> firstPart_;
    /**
     * <code>repeated bytes first_part = 3;</code>
     *
     * <pre>
     **
     * The TransactionalAggregateService methods all have a response that either is a Pair
     * or a simple object. When it is a Pair both first_part and second_part
     * have defined values (and the second_part is not present in the response
     * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
     * class for an overview of the TransactionalAggregateResponse object constructions. 
     * </pre>
     */
    public java.util.List<com.google.protobuf.ByteString>
        getFirstPartList() {
      return firstPart_;
    }
    /**
     * <code>repeated bytes first_part = 3;</code>
     *
     * <pre>
     **
     * The TransactionalAggregateService methods all have a response that either is a Pair
     * or a simple object. When it is a Pair both first_part and second_part
     * have defined values (and the second_part is not present in the response
     * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
     * class for an overview of the TransactionalAggregateResponse object constructions. 
     * </pre>
     */
    public int getFirstPartCount() {
      return firstPart_.size();
    }
    /**
     * <code>repeated bytes first_part = 3;</code>
     *
     * <pre>
     **
     * The TransactionalAggregateService methods all have a response that either is a Pair
     * or a simple object. When it is a Pair both first_part and second_part
     * have defined values (and the second_part is not present in the response
     * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
     * class for an overview of the TransactionalAggregateResponse object constructions. 
     * </pre>
     */
    public com.google.protobuf.ByteString getFirstPart(int index) {
      return firstPart_.get(index);
    }

    // optional bytes second_part = 4;
    public static final int SECOND_PART_FIELD_NUMBER = 4;
    private com.google.protobuf.ByteString secondPart_;
    /**
     * <code>optional bytes second_part = 4;</code>
     */
    public boolean hasSecondPart() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional bytes second_part = 4;</code>
     */
    public com.google.protobuf.ByteString getSecondPart() {
      return secondPart_;
    }

    private void initFields() {
      firstPart_ = java.util.Collections.emptyList();
      secondPart_ = com.google.protobuf.ByteString.EMPTY;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < firstPart_.size(); i++) {
        output.writeBytes(3, firstPart_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(4, secondPart_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      {
        int dataSize = 0;
        for (int i = 0; i < firstPart_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeBytesSizeNoTag(firstPart_.get(i));
        }
        size += dataSize;
        size += 1 * getFirstPartList().size();
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(4, secondPart_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code SsccTransactionalAggregateResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccTransactionalAggregateResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccTransactionalAggregateResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.class, org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.Builder.class);
      }

      // Construct using org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        firstPart_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000001);
        secondPart_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.internal_static_SsccTransactionalAggregateResponse_descriptor;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getDefaultInstanceForType() {
        return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse build() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse buildPartial() {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse result = new org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((bitField0_ & 0x00000001) == 0x00000001)) {
          firstPart_ = java.util.Collections.unmodifiableList(firstPart_);
          bitField0_ = (bitField0_ & ~0x00000001);
        }
        result.firstPart_ = firstPart_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000001;
        }
        result.secondPart_ = secondPart_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse) {
          return mergeFrom((org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse other) {
        if (other == org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance()) return this;
        if (!other.firstPart_.isEmpty()) {
          if (firstPart_.isEmpty()) {
            firstPart_ = other.firstPart_;
            bitField0_ = (bitField0_ & ~0x00000001);
          } else {
            ensureFirstPartIsMutable();
            firstPart_.addAll(other.firstPart_);
          }
          onChanged();
        }
        if (other.hasSecondPart()) {
          setSecondPart(other.getSecondPart());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // repeated bytes first_part = 3;
      private java.util.List<com.google.protobuf.ByteString> firstPart_ = java.util.Collections.emptyList();
      private void ensureFirstPartIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          firstPart_ = new java.util.ArrayList<com.google.protobuf.ByteString>(firstPart_);
          bitField0_ |= 0x00000001;
         }
      }
      /**
       * <code>repeated bytes first_part = 3;</code>
       *
       * <pre>
       **
       * The TransactionalAggregateService methods all have a response that either is a Pair
       * or a simple object. When it is a Pair both first_part and second_part
       * have defined values (and the second_part is not present in the response
       * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
       * class for an overview of the TransactionalAggregateResponse object constructions. 
       * </pre>
       */
      public java.util.List<com.google.protobuf.ByteString>
          getFirstPartList() {
        return java.util.Collections.unmodifiableList(firstPart_);
      }
      /**
       * <code>repeated bytes first_part = 3;</code>
       *
       * <pre>
       **
       * The TransactionalAggregateService methods all have a response that either is a Pair
       * or a simple object. When it is a Pair both first_part and second_part
       * have defined values (and the second_part is not present in the response
       * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
       * class for an overview of the TransactionalAggregateResponse object constructions. 
       * </pre>
       */
      public int getFirstPartCount() {
        return firstPart_.size();
      }
      /**
       * <code>repeated bytes first_part = 3;</code>
       *
       * <pre>
       **
       * The TransactionalAggregateService methods all have a response that either is a Pair
       * or a simple object. When it is a Pair both first_part and second_part
       * have defined values (and the second_part is not present in the response
       * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
       * class for an overview of the TransactionalAggregateResponse object constructions. 
       * </pre>
       */
      public com.google.protobuf.ByteString getFirstPart(int index) {
        return firstPart_.get(index);
      }
      /**
       * <code>repeated bytes first_part = 3;</code>
       *
       * <pre>
       **
       * The TransactionalAggregateService methods all have a response that either is a Pair
       * or a simple object. When it is a Pair both first_part and second_part
       * have defined values (and the second_part is not present in the response
       * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
       * class for an overview of the TransactionalAggregateResponse object constructions. 
       * </pre>
       */
      public Builder setFirstPart(
          int index, com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureFirstPartIsMutable();
        firstPart_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated bytes first_part = 3;</code>
       *
       * <pre>
       **
       * The TransactionalAggregateService methods all have a response that either is a Pair
       * or a simple object. When it is a Pair both first_part and second_part
       * have defined values (and the second_part is not present in the response
       * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
       * class for an overview of the TransactionalAggregateResponse object constructions. 
       * </pre>
       */
      public Builder addFirstPart(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureFirstPartIsMutable();
        firstPart_.add(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated bytes first_part = 3;</code>
       *
       * <pre>
       **
       * The TransactionalAggregateService methods all have a response that either is a Pair
       * or a simple object. When it is a Pair both first_part and second_part
       * have defined values (and the second_part is not present in the response
       * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
       * class for an overview of the TransactionalAggregateResponse object constructions. 
       * </pre>
       */
      public Builder addAllFirstPart(
          java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
        ensureFirstPartIsMutable();
        super.addAll(values, firstPart_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated bytes first_part = 3;</code>
       *
       * <pre>
       **
       * The TransactionalAggregateService methods all have a response that either is a Pair
       * or a simple object. When it is a Pair both first_part and second_part
       * have defined values (and the second_part is not present in the response
       * when the response is not a pair). Refer to the TransactionalAggregateImplementation 
       * class for an overview of the TransactionalAggregateResponse object constructions. 
       * </pre>
       */
      public Builder clearFirstPart() {
        firstPart_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000001);
        onChanged();
        return this;
      }

      // optional bytes second_part = 4;
      private com.google.protobuf.ByteString secondPart_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>optional bytes second_part = 4;</code>
       */
      public boolean hasSecondPart() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional bytes second_part = 4;</code>
       */
      public com.google.protobuf.ByteString getSecondPart() {
        return secondPart_;
      }
      /**
       * <code>optional bytes second_part = 4;</code>
       */
      public Builder setSecondPart(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        secondPart_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bytes second_part = 4;</code>
       */
      public Builder clearSecondPart() {
        bitField0_ = (bitField0_ & ~0x00000002);
        secondPart_ = getDefaultInstance().getSecondPart();
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:SsccTransactionalAggregateResponse)
    }

    static {
      defaultInstance = new SsccTransactionalAggregateResponse(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:SsccTransactionalAggregateResponse)
  }

  /**
   * Protobuf service {@code SsccRegionService}
   */
  public static abstract class SsccRegionService
      implements com.google.protobuf.Service {
    protected SsccRegionService() {}

    public interface Interface {
      /**
       * <code>rpc abortTransaction(.SsccAbortTransactionRequest) returns (.SsccAbortTransactionResponse);</code>
       */
      public abstract void abortTransaction(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse> done);

      /**
       * <code>rpc beginTransaction(.SsccBeginTransactionRequest) returns (.SsccBeginTransactionResponse);</code>
       */
      public abstract void beginTransaction(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse> done);

      /**
       * <code>rpc checkAndDelete(.SsccCheckAndDeleteRequest) returns (.SsccCheckAndDeleteResponse);</code>
       */
      public abstract void checkAndDelete(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse> done);

      /**
       * <code>rpc checkAndDeleteRegionTx(.SsccCheckAndDeleteRegionTxRequest) returns (.SsccCheckAndDeleteRegionTxResponse);</code>
       */
      public abstract void checkAndDeleteRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse> done);

      /**
       * <code>rpc checkAndPut(.SsccCheckAndPutRequest) returns (.SsccCheckAndPutResponse);</code>
       */
      public abstract void checkAndPut(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse> done);

      /**
       * <code>rpc checkAndPutRegionTx(.SsccCheckAndPutRegionTxRequest) returns (.SsccCheckAndPutRegionTxResponse);</code>
       */
      public abstract void checkAndPutRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse> done);

      /**
       * <code>rpc closeScanner(.SsccCloseScannerRequest) returns (.SsccCloseScannerResponse);</code>
       */
      public abstract void closeScanner(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse> done);

      /**
       * <code>rpc commit(.SsccCommitRequest) returns (.SsccCommitResponse);</code>
       */
      public abstract void commit(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse> done);

      /**
       * <code>rpc commitIfPossible(.SsccCommitIfPossibleRequest) returns (.SsccCommitIfPossibleResponse);</code>
       */
      public abstract void commitIfPossible(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse> done);

      /**
       * <code>rpc commitRequest(.SsccCommitRequestRequest) returns (.SsccCommitRequestResponse);</code>
       */
      public abstract void commitRequest(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse> done);

      /**
       * <code>rpc deleteRegionTx(.SsccDeleteRegionTxRequest) returns (.SsccDeleteRegionTxResponse);</code>
       */
      public abstract void deleteRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse> done);

      /**
       * <code>rpc delete(.SsccDeleteTransactionalRequest) returns (.SsccDeleteTransactionalResponse);</code>
       */
      public abstract void delete(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse> done);

      /**
       * <code>rpc deleteMultiple(.SsccDeleteMultipleTransactionalRequest) returns (.SsccDeleteMultipleTransactionalResponse);</code>
       */
      public abstract void deleteMultiple(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse> done);

      /**
       * <code>rpc get(.SsccGetTransactionalRequest) returns (.SsccGetTransactionalResponse);</code>
       */
      public abstract void get(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse> done);

      /**
       * <code>rpc performScan(.SsccPerformScanRequest) returns (.SsccPerformScanResponse);</code>
       */
      public abstract void performScan(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse> done);

      /**
       * <code>rpc openScanner(.SsccOpenScannerRequest) returns (.SsccOpenScannerResponse);</code>
       */
      public abstract void openScanner(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse> done);

      /**
       * <code>rpc putRegionTx(.SsccPutRegionTxRequest) returns (.SsccPutRegionTxResponse);</code>
       */
      public abstract void putRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse> done);

      /**
       * <code>rpc put(.SsccPutTransactionalRequest) returns (.SsccPutTransactionalResponse);</code>
       */
      public abstract void put(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse> done);

      /**
       * <code>rpc putMultiple(.SsccPutMultipleTransactionalRequest) returns (.SsccPutMultipleTransactionalResponse);</code>
       */
      public abstract void putMultiple(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse> done);

      /**
       * <code>rpc recoveryRequest(.SsccRecoveryRequestRequest) returns (.SsccRecoveryRequestResponse);</code>
       */
      public abstract void recoveryRequest(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse> done);

      /**
       * <code>rpc GetMax(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
       */
      public abstract void getMax(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

      /**
       * <code>rpc GetMin(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
       */
      public abstract void getMin(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

      /**
       * <code>rpc GetSum(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
       */
      public abstract void getSum(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

      /**
       * <code>rpc GetRowNum(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
       */
      public abstract void getRowNum(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

      /**
       * <code>rpc GetAvg(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
       */
      public abstract void getAvg(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

      /**
       * <code>rpc GetStd(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
       */
      public abstract void getStd(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

      /**
       * <code>rpc GetMedian(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
       */
      public abstract void getMedian(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

    }

    public static com.google.protobuf.Service newReflectiveService(
        final Interface impl) {
      return new SsccRegionService() {
        @java.lang.Override
        public  void abortTransaction(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse> done) {
          impl.abortTransaction(controller, request, done);
        }

        @java.lang.Override
        public  void beginTransaction(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse> done) {
          impl.beginTransaction(controller, request, done);
        }

        @java.lang.Override
        public  void checkAndDelete(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse> done) {
          impl.checkAndDelete(controller, request, done);
        }

        @java.lang.Override
        public  void checkAndDeleteRegionTx(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse> done) {
          impl.checkAndDeleteRegionTx(controller, request, done);
        }

        @java.lang.Override
        public  void checkAndPut(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse> done) {
          impl.checkAndPut(controller, request, done);
        }

        @java.lang.Override
        public  void checkAndPutRegionTx(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse> done) {
          impl.checkAndPutRegionTx(controller, request, done);
        }

        @java.lang.Override
        public  void closeScanner(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse> done) {
          impl.closeScanner(controller, request, done);
        }

        @java.lang.Override
        public  void commit(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse> done) {
          impl.commit(controller, request, done);
        }

        @java.lang.Override
        public  void commitIfPossible(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse> done) {
          impl.commitIfPossible(controller, request, done);
        }

        @java.lang.Override
        public  void commitRequest(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse> done) {
          impl.commitRequest(controller, request, done);
        }

        @java.lang.Override
        public  void deleteRegionTx(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse> done) {
          impl.deleteRegionTx(controller, request, done);
        }

        @java.lang.Override
        public  void delete(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse> done) {
          impl.delete(controller, request, done);
        }

        @java.lang.Override
        public  void deleteMultiple(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse> done) {
          impl.deleteMultiple(controller, request, done);
        }

        @java.lang.Override
        public  void get(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse> done) {
          impl.get(controller, request, done);
        }

        @java.lang.Override
        public  void performScan(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse> done) {
          impl.performScan(controller, request, done);
        }

        @java.lang.Override
        public  void openScanner(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse> done) {
          impl.openScanner(controller, request, done);
        }

        @java.lang.Override
        public  void putRegionTx(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse> done) {
          impl.putRegionTx(controller, request, done);
        }

        @java.lang.Override
        public  void put(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse> done) {
          impl.put(controller, request, done);
        }

        @java.lang.Override
        public  void putMultiple(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse> done) {
          impl.putMultiple(controller, request, done);
        }

        @java.lang.Override
        public  void recoveryRequest(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse> done) {
          impl.recoveryRequest(controller, request, done);
        }

        @java.lang.Override
        public  void getMax(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
          impl.getMax(controller, request, done);
        }

        @java.lang.Override
        public  void getMin(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
          impl.getMin(controller, request, done);
        }

        @java.lang.Override
        public  void getSum(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
          impl.getSum(controller, request, done);
        }

        @java.lang.Override
        public  void getRowNum(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
          impl.getRowNum(controller, request, done);
        }

        @java.lang.Override
        public  void getAvg(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
          impl.getAvg(controller, request, done);
        }

        @java.lang.Override
        public  void getStd(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
          impl.getStd(controller, request, done);
        }

        @java.lang.Override
        public  void getMedian(
            com.google.protobuf.RpcController controller,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
            com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
          impl.getMedian(controller, request, done);
        }

      };
    }

    public static com.google.protobuf.BlockingService
        newReflectiveBlockingService(final BlockingInterface impl) {
      return new com.google.protobuf.BlockingService() {
        public final com.google.protobuf.Descriptors.ServiceDescriptor
            getDescriptorForType() {
          return getDescriptor();
        }

        public final com.google.protobuf.Message callBlockingMethod(
            com.google.protobuf.Descriptors.MethodDescriptor method,
            com.google.protobuf.RpcController controller,
            com.google.protobuf.Message request)
            throws com.google.protobuf.ServiceException {
          if (method.getService() != getDescriptor()) {
            throw new java.lang.IllegalArgumentException(
              "Service.callBlockingMethod() given method descriptor for " +
              "wrong service type.");
          }
          switch(method.getIndex()) {
            case 0:
              return impl.abortTransaction(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest)request);
            case 1:
              return impl.beginTransaction(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest)request);
            case 2:
              return impl.checkAndDelete(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest)request);
            case 3:
              return impl.checkAndDeleteRegionTx(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest)request);
            case 4:
              return impl.checkAndPut(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest)request);
            case 5:
              return impl.checkAndPutRegionTx(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest)request);
            case 6:
              return impl.closeScanner(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest)request);
            case 7:
              return impl.commit(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest)request);
            case 8:
              return impl.commitIfPossible(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest)request);
            case 9:
              return impl.commitRequest(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest)request);
            case 10:
              return impl.deleteRegionTx(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest)request);
            case 11:
              return impl.delete(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest)request);
            case 12:
              return impl.deleteMultiple(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest)request);
            case 13:
              return impl.get(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest)request);
            case 14:
              return impl.performScan(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest)request);
            case 15:
              return impl.openScanner(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest)request);
            case 16:
              return impl.putRegionTx(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest)request);
            case 17:
              return impl.put(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest)request);
            case 18:
              return impl.putMultiple(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest)request);
            case 19:
              return impl.recoveryRequest(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest)request);
            case 20:
              return impl.getMax(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request);
            case 21:
              return impl.getMin(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request);
            case 22:
              return impl.getSum(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request);
            case 23:
              return impl.getRowNum(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request);
            case 24:
              return impl.getAvg(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request);
            case 25:
              return impl.getStd(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request);
            case 26:
              return impl.getMedian(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request);
            default:
              throw new java.lang.AssertionError("Can't get here.");
          }
        }

        public final com.google.protobuf.Message
            getRequestPrototype(
            com.google.protobuf.Descriptors.MethodDescriptor method) {
          if (method.getService() != getDescriptor()) {
            throw new java.lang.IllegalArgumentException(
              "Service.getRequestPrototype() given method " +
              "descriptor for wrong service type.");
          }
          switch(method.getIndex()) {
            case 0:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest.getDefaultInstance();
            case 1:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest.getDefaultInstance();
            case 2:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest.getDefaultInstance();
            case 3:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest.getDefaultInstance();
            case 4:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest.getDefaultInstance();
            case 5:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest.getDefaultInstance();
            case 6:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest.getDefaultInstance();
            case 7:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest.getDefaultInstance();
            case 8:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest.getDefaultInstance();
            case 9:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest.getDefaultInstance();
            case 10:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest.getDefaultInstance();
            case 11:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest.getDefaultInstance();
            case 12:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest.getDefaultInstance();
            case 13:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest.getDefaultInstance();
            case 14:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest.getDefaultInstance();
            case 15:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest.getDefaultInstance();
            case 16:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest.getDefaultInstance();
            case 17:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest.getDefaultInstance();
            case 18:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest.getDefaultInstance();
            case 19:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest.getDefaultInstance();
            case 20:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
            case 21:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
            case 22:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
            case 23:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
            case 24:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
            case 25:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
            case 26:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
            default:
              throw new java.lang.AssertionError("Can't get here.");
          }
        }

        public final com.google.protobuf.Message
            getResponsePrototype(
            com.google.protobuf.Descriptors.MethodDescriptor method) {
          if (method.getService() != getDescriptor()) {
            throw new java.lang.IllegalArgumentException(
              "Service.getResponsePrototype() given method " +
              "descriptor for wrong service type.");
          }
          switch(method.getIndex()) {
            case 0:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.getDefaultInstance();
            case 1:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.getDefaultInstance();
            case 2:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.getDefaultInstance();
            case 3:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.getDefaultInstance();
            case 4:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.getDefaultInstance();
            case 5:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.getDefaultInstance();
            case 6:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.getDefaultInstance();
            case 7:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.getDefaultInstance();
            case 8:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.getDefaultInstance();
            case 9:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.getDefaultInstance();
            case 10:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.getDefaultInstance();
            case 11:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.getDefaultInstance();
            case 12:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.getDefaultInstance();
            case 13:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.getDefaultInstance();
            case 14:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.getDefaultInstance();
            case 15:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.getDefaultInstance();
            case 16:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.getDefaultInstance();
            case 17:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.getDefaultInstance();
            case 18:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.getDefaultInstance();
            case 19:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.getDefaultInstance();
            case 20:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
            case 21:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
            case 22:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
            case 23:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
            case 24:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
            case 25:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
            case 26:
              return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
            default:
              throw new java.lang.AssertionError("Can't get here.");
          }
        }

      };
    }

    /**
     * <code>rpc abortTransaction(.SsccAbortTransactionRequest) returns (.SsccAbortTransactionResponse);</code>
     */
    public abstract void abortTransaction(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse> done);

    /**
     * <code>rpc beginTransaction(.SsccBeginTransactionRequest) returns (.SsccBeginTransactionResponse);</code>
     */
    public abstract void beginTransaction(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse> done);

    /**
     * <code>rpc checkAndDelete(.SsccCheckAndDeleteRequest) returns (.SsccCheckAndDeleteResponse);</code>
     */
    public abstract void checkAndDelete(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse> done);

    /**
     * <code>rpc checkAndDeleteRegionTx(.SsccCheckAndDeleteRegionTxRequest) returns (.SsccCheckAndDeleteRegionTxResponse);</code>
     */
    public abstract void checkAndDeleteRegionTx(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse> done);

    /**
     * <code>rpc checkAndPut(.SsccCheckAndPutRequest) returns (.SsccCheckAndPutResponse);</code>
     */
    public abstract void checkAndPut(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse> done);

    /**
     * <code>rpc checkAndPutRegionTx(.SsccCheckAndPutRegionTxRequest) returns (.SsccCheckAndPutRegionTxResponse);</code>
     */
    public abstract void checkAndPutRegionTx(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse> done);

    /**
     * <code>rpc closeScanner(.SsccCloseScannerRequest) returns (.SsccCloseScannerResponse);</code>
     */
    public abstract void closeScanner(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse> done);

    /**
     * <code>rpc commit(.SsccCommitRequest) returns (.SsccCommitResponse);</code>
     */
    public abstract void commit(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse> done);

    /**
     * <code>rpc commitIfPossible(.SsccCommitIfPossibleRequest) returns (.SsccCommitIfPossibleResponse);</code>
     */
    public abstract void commitIfPossible(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse> done);

    /**
     * <code>rpc commitRequest(.SsccCommitRequestRequest) returns (.SsccCommitRequestResponse);</code>
     */
    public abstract void commitRequest(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse> done);

    /**
     * <code>rpc deleteRegionTx(.SsccDeleteRegionTxRequest) returns (.SsccDeleteRegionTxResponse);</code>
     */
    public abstract void deleteRegionTx(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse> done);

    /**
     * <code>rpc delete(.SsccDeleteTransactionalRequest) returns (.SsccDeleteTransactionalResponse);</code>
     */
    public abstract void delete(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse> done);

    /**
     * <code>rpc deleteMultiple(.SsccDeleteMultipleTransactionalRequest) returns (.SsccDeleteMultipleTransactionalResponse);</code>
     */
    public abstract void deleteMultiple(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse> done);

    /**
     * <code>rpc get(.SsccGetTransactionalRequest) returns (.SsccGetTransactionalResponse);</code>
     */
    public abstract void get(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse> done);

    /**
     * <code>rpc performScan(.SsccPerformScanRequest) returns (.SsccPerformScanResponse);</code>
     */
    public abstract void performScan(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse> done);

    /**
     * <code>rpc openScanner(.SsccOpenScannerRequest) returns (.SsccOpenScannerResponse);</code>
     */
    public abstract void openScanner(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse> done);

    /**
     * <code>rpc putRegionTx(.SsccPutRegionTxRequest) returns (.SsccPutRegionTxResponse);</code>
     */
    public abstract void putRegionTx(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse> done);

    /**
     * <code>rpc put(.SsccPutTransactionalRequest) returns (.SsccPutTransactionalResponse);</code>
     */
    public abstract void put(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse> done);

    /**
     * <code>rpc putMultiple(.SsccPutMultipleTransactionalRequest) returns (.SsccPutMultipleTransactionalResponse);</code>
     */
    public abstract void putMultiple(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse> done);

    /**
     * <code>rpc recoveryRequest(.SsccRecoveryRequestRequest) returns (.SsccRecoveryRequestResponse);</code>
     */
    public abstract void recoveryRequest(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse> done);

    /**
     * <code>rpc GetMax(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
     */
    public abstract void getMax(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

    /**
     * <code>rpc GetMin(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
     */
    public abstract void getMin(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

    /**
     * <code>rpc GetSum(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
     */
    public abstract void getSum(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

    /**
     * <code>rpc GetRowNum(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
     */
    public abstract void getRowNum(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

    /**
     * <code>rpc GetAvg(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
     */
    public abstract void getAvg(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

    /**
     * <code>rpc GetStd(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
     */
    public abstract void getStd(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

    /**
     * <code>rpc GetMedian(.SsccTransactionalAggregateRequest) returns (.SsccTransactionalAggregateResponse);</code>
     */
    public abstract void getMedian(
        com.google.protobuf.RpcController controller,
        org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
        com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done);

    public static final
        com.google.protobuf.Descriptors.ServiceDescriptor
        getDescriptor() {
      return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.getDescriptor().getServices().get(0);
    }
    public final com.google.protobuf.Descriptors.ServiceDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }

    public final void callMethod(
        com.google.protobuf.Descriptors.MethodDescriptor method,
        com.google.protobuf.RpcController controller,
        com.google.protobuf.Message request,
        com.google.protobuf.RpcCallback<
          com.google.protobuf.Message> done) {
      if (method.getService() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "Service.callMethod() given method descriptor for wrong " +
          "service type.");
      }
      switch(method.getIndex()) {
        case 0:
          this.abortTransaction(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse>specializeCallback(
              done));
          return;
        case 1:
          this.beginTransaction(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse>specializeCallback(
              done));
          return;
        case 2:
          this.checkAndDelete(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse>specializeCallback(
              done));
          return;
        case 3:
          this.checkAndDeleteRegionTx(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse>specializeCallback(
              done));
          return;
        case 4:
          this.checkAndPut(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse>specializeCallback(
              done));
          return;
        case 5:
          this.checkAndPutRegionTx(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse>specializeCallback(
              done));
          return;
        case 6:
          this.closeScanner(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse>specializeCallback(
              done));
          return;
        case 7:
          this.commit(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse>specializeCallback(
              done));
          return;
        case 8:
          this.commitIfPossible(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse>specializeCallback(
              done));
          return;
        case 9:
          this.commitRequest(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse>specializeCallback(
              done));
          return;
        case 10:
          this.deleteRegionTx(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse>specializeCallback(
              done));
          return;
        case 11:
          this.delete(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse>specializeCallback(
              done));
          return;
        case 12:
          this.deleteMultiple(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse>specializeCallback(
              done));
          return;
        case 13:
          this.get(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse>specializeCallback(
              done));
          return;
        case 14:
          this.performScan(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse>specializeCallback(
              done));
          return;
        case 15:
          this.openScanner(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse>specializeCallback(
              done));
          return;
        case 16:
          this.putRegionTx(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse>specializeCallback(
              done));
          return;
        case 17:
          this.put(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse>specializeCallback(
              done));
          return;
        case 18:
          this.putMultiple(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse>specializeCallback(
              done));
          return;
        case 19:
          this.recoveryRequest(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse>specializeCallback(
              done));
          return;
        case 20:
          this.getMax(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse>specializeCallback(
              done));
          return;
        case 21:
          this.getMin(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse>specializeCallback(
              done));
          return;
        case 22:
          this.getSum(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse>specializeCallback(
              done));
          return;
        case 23:
          this.getRowNum(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse>specializeCallback(
              done));
          return;
        case 24:
          this.getAvg(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse>specializeCallback(
              done));
          return;
        case 25:
          this.getStd(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse>specializeCallback(
              done));
          return;
        case 26:
          this.getMedian(controller, (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest)request,
            com.google.protobuf.RpcUtil.<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse>specializeCallback(
              done));
          return;
        default:
          throw new java.lang.AssertionError("Can't get here.");
      }
    }

    public final com.google.protobuf.Message
        getRequestPrototype(
        com.google.protobuf.Descriptors.MethodDescriptor method) {
      if (method.getService() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "Service.getRequestPrototype() given method " +
          "descriptor for wrong service type.");
      }
      switch(method.getIndex()) {
        case 0:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest.getDefaultInstance();
        case 1:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest.getDefaultInstance();
        case 2:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest.getDefaultInstance();
        case 3:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest.getDefaultInstance();
        case 4:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest.getDefaultInstance();
        case 5:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest.getDefaultInstance();
        case 6:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest.getDefaultInstance();
        case 7:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest.getDefaultInstance();
        case 8:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest.getDefaultInstance();
        case 9:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest.getDefaultInstance();
        case 10:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest.getDefaultInstance();
        case 11:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest.getDefaultInstance();
        case 12:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest.getDefaultInstance();
        case 13:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest.getDefaultInstance();
        case 14:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest.getDefaultInstance();
        case 15:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest.getDefaultInstance();
        case 16:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest.getDefaultInstance();
        case 17:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest.getDefaultInstance();
        case 18:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest.getDefaultInstance();
        case 19:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest.getDefaultInstance();
        case 20:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
        case 21:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
        case 22:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
        case 23:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
        case 24:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
        case 25:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
        case 26:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest.getDefaultInstance();
        default:
          throw new java.lang.AssertionError("Can't get here.");
      }
    }

    public final com.google.protobuf.Message
        getResponsePrototype(
        com.google.protobuf.Descriptors.MethodDescriptor method) {
      if (method.getService() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "Service.getResponsePrototype() given method " +
          "descriptor for wrong service type.");
      }
      switch(method.getIndex()) {
        case 0:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.getDefaultInstance();
        case 1:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.getDefaultInstance();
        case 2:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.getDefaultInstance();
        case 3:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.getDefaultInstance();
        case 4:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.getDefaultInstance();
        case 5:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.getDefaultInstance();
        case 6:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.getDefaultInstance();
        case 7:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.getDefaultInstance();
        case 8:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.getDefaultInstance();
        case 9:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.getDefaultInstance();
        case 10:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.getDefaultInstance();
        case 11:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.getDefaultInstance();
        case 12:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.getDefaultInstance();
        case 13:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.getDefaultInstance();
        case 14:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.getDefaultInstance();
        case 15:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.getDefaultInstance();
        case 16:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.getDefaultInstance();
        case 17:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.getDefaultInstance();
        case 18:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.getDefaultInstance();
        case 19:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.getDefaultInstance();
        case 20:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
        case 21:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
        case 22:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
        case 23:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
        case 24:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
        case 25:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
        case 26:
          return org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance();
        default:
          throw new java.lang.AssertionError("Can't get here.");
      }
    }

    public static Stub newStub(
        com.google.protobuf.RpcChannel channel) {
      return new Stub(channel);
    }

    public static final class Stub extends org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRegionService implements Interface {
      private Stub(com.google.protobuf.RpcChannel channel) {
        this.channel = channel;
      }

      private final com.google.protobuf.RpcChannel channel;

      public com.google.protobuf.RpcChannel getChannel() {
        return channel;
      }

      public  void abortTransaction(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(0),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.getDefaultInstance()));
      }

      public  void beginTransaction(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(1),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.getDefaultInstance()));
      }

      public  void checkAndDelete(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(2),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.getDefaultInstance()));
      }

      public  void checkAndDeleteRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(3),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.getDefaultInstance()));
      }

      public  void checkAndPut(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(4),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.getDefaultInstance()));
      }

      public  void checkAndPutRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(5),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.getDefaultInstance()));
      }

      public  void closeScanner(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(6),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.getDefaultInstance()));
      }

      public  void commit(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(7),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.getDefaultInstance()));
      }

      public  void commitIfPossible(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(8),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.getDefaultInstance()));
      }

      public  void commitRequest(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(9),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.getDefaultInstance()));
      }

      public  void deleteRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(10),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.getDefaultInstance()));
      }

      public  void delete(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(11),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.getDefaultInstance()));
      }

      public  void deleteMultiple(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(12),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.getDefaultInstance()));
      }

      public  void get(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(13),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.getDefaultInstance()));
      }

      public  void performScan(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(14),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.getDefaultInstance()));
      }

      public  void openScanner(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(15),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.getDefaultInstance()));
      }

      public  void putRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(16),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.getDefaultInstance()));
      }

      public  void put(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(17),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.getDefaultInstance()));
      }

      public  void putMultiple(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(18),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.getDefaultInstance()));
      }

      public  void recoveryRequest(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(19),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.getDefaultInstance()));
      }

      public  void getMax(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(20),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance()));
      }

      public  void getMin(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(21),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance()));
      }

      public  void getSum(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(22),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance()));
      }

      public  void getRowNum(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(23),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance()));
      }

      public  void getAvg(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(24),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance()));
      }

      public  void getStd(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(25),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance()));
      }

      public  void getMedian(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request,
          com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse> done) {
        channel.callMethod(
          getDescriptor().getMethods().get(26),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance(),
          com.google.protobuf.RpcUtil.generalizeCallback(
            done,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.class,
            org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance()));
      }
    }

    public static BlockingInterface newBlockingStub(
        com.google.protobuf.BlockingRpcChannel channel) {
      return new BlockingStub(channel);
    }

    public interface BlockingInterface {
      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse abortTransaction(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse beginTransaction(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse checkAndDelete(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse checkAndDeleteRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse checkAndPut(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse checkAndPutRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse closeScanner(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse commit(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse commitIfPossible(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse commitRequest(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse deleteRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse delete(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse deleteMultiple(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse get(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse performScan(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse openScanner(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse putRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse put(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse putMultiple(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse recoveryRequest(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getMax(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getMin(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getSum(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getRowNum(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getAvg(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getStd(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getMedian(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException;
    }

    private static final class BlockingStub implements BlockingInterface {
      private BlockingStub(com.google.protobuf.BlockingRpcChannel channel) {
        this.channel = channel;
      }

      private final com.google.protobuf.BlockingRpcChannel channel;

      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse abortTransaction(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(0),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccAbortTransactionResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse beginTransaction(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(1),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccBeginTransactionResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse checkAndDelete(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(2),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse checkAndDeleteRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(3),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndDeleteRegionTxResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse checkAndPut(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(4),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse checkAndPutRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(5),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCheckAndPutRegionTxResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse closeScanner(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(6),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCloseScannerResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse commit(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(7),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse commitIfPossible(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(8),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitIfPossibleResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse commitRequest(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(9),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccCommitRequestResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse deleteRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(10),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteRegionTxResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse delete(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(11),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteTransactionalResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse deleteMultiple(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(12),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccDeleteMultipleTransactionalResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse get(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(13),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccGetTransactionalResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse performScan(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(14),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPerformScanResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse openScanner(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(15),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccOpenScannerResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse putRegionTx(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(16),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutRegionTxResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse put(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(17),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutTransactionalResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse putMultiple(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(18),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccPutMultipleTransactionalResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse recoveryRequest(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(19),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccRecoveryRequestResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getMax(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(20),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getMin(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(21),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getSum(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(22),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getRowNum(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(23),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getAvg(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(24),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getStd(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(25),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance());
      }


      public org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse getMedian(
          com.google.protobuf.RpcController controller,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateRequest request)
          throws com.google.protobuf.ServiceException {
        return (org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse) channel.callBlockingMethod(
          getDescriptor().getMethods().get(26),
          controller,
          request,
          org.apache.hadoop.hbase.coprocessor.transactional.generated.SsccRegionProtos.SsccTransactionalAggregateResponse.getDefaultInstance());
      }

    }

    // @@protoc_insertion_point(class_scope:SsccRegionService)
  }

  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccAbortTransactionRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccAbortTransactionRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccAbortTransactionResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccAbortTransactionResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccBeginTransactionRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccBeginTransactionRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccBeginTransactionResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccBeginTransactionResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCommitRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCommitRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCommitResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCommitResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCommitRequestRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCommitRequestRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCommitRequestResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCommitRequestResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCommitIfPossibleRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCommitIfPossibleRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCommitIfPossibleResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCommitIfPossibleResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCheckAndDeleteRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCheckAndDeleteRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCheckAndDeleteResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCheckAndDeleteResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCheckAndDeleteRegionTxRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCheckAndDeleteRegionTxRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCheckAndDeleteRegionTxResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCheckAndDeleteRegionTxResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCheckAndPutRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCheckAndPutRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCheckAndPutResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCheckAndPutResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCheckAndPutRegionTxRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCheckAndPutRegionTxRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCheckAndPutRegionTxResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCheckAndPutRegionTxResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCloseScannerRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCloseScannerRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccCloseScannerResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccCloseScannerResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccDeleteMultipleTransactionalRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccDeleteMultipleTransactionalRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccDeleteMultipleTransactionalResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccDeleteMultipleTransactionalResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccDeleteRegionTxRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccDeleteRegionTxRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccDeleteRegionTxResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccDeleteRegionTxResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccDeleteTransactionalRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccDeleteTransactionalRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccDeleteTransactionalResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccDeleteTransactionalResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccGetTransactionalRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccGetTransactionalRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccGetTransactionalResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccGetTransactionalResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccOpenScannerRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccOpenScannerRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccOpenScannerResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccOpenScannerResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccPerformScanRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccPerformScanRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccPerformScanResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccPerformScanResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccPutRegionTxRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccPutRegionTxRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccPutRegionTxResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccPutRegionTxResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccPutTransactionalRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccPutTransactionalRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccPutTransactionalResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccPutTransactionalResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccPutMultipleTransactionalRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccPutMultipleTransactionalRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccPutMultipleTransactionalResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccPutMultipleTransactionalResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccRecoveryRequestRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccRecoveryRequestRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccRecoveryRequestResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccRecoveryRequestResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccTransactionalAggregateRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccTransactionalAggregateRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_SsccTransactionalAggregateResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_SsccTransactionalAggregateResponse_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\020SsccRegion.proto\032\013HBase.proto\032\023Cluster" +
      "Status.proto\032\014Client.proto\"H\n\033SsccAbortT" +
      "ransactionRequest\022\022\n\nregionName\030\001 \002(\014\022\025\n" +
      "\rtransactionId\030\002 \002(\003\"G\n\034SsccAbortTransac" +
      "tionResponse\022\021\n\texception\030\001 \001(\t\022\024\n\014hasEx" +
      "ception\030\002 \001(\010\"Y\n\033SsccBeginTransactionReq" +
      "uest\022\025\n\rtransactionId\030\001 \002(\003\022\017\n\007startId\030\002" +
      " \002(\003\022\022\n\nregionName\030\003 \002(\014\"G\n\034SsccBeginTra" +
      "nsactionResponse\022\021\n\texception\030\001 \001(\t\022\024\n\014h" +
      "asException\030\002 \001(\010\"{\n\021SsccCommitRequest\022\022",
      "\n\nregionName\030\001 \002(\014\022\025\n\rtransactionId\030\002 \002(" +
      "\003\022\020\n\010commitId\030\003 \002(\003\022)\n!ignoreUnknownTran" +
      "sactionException\030\004 \001(\010\"=\n\022SsccCommitResp" +
      "onse\022\021\n\texception\030\001 \001(\t\022\024\n\014hasException\030" +
      "\002 \001(\010\"E\n\030SsccCommitRequestRequest\022\022\n\nreg" +
      "ionName\030\001 \002(\014\022\025\n\rtransactionId\030\002 \002(\003\"T\n\031" +
      "SsccCommitRequestResponse\022\016\n\006result\030\001 \002(" +
      "\005\022\021\n\texception\030\002 \001(\t\022\024\n\014hasException\030\003 \001" +
      "(\010\"H\n\033SsccCommitIfPossibleRequest\022\022\n\nreg" +
      "ionName\030\001 \002(\014\022\025\n\rtransactionId\030\002 \002(\003\"^\n\034",
      "SsccCommitIfPossibleResponse\022\021\n\texceptio" +
      "n\030\001 \001(\t\022\024\n\014hasException\030\002 \001(\010\022\025\n\rwasSucc" +
      "essful\030\003 \001(\010\"\266\001\n\031SsccCheckAndDeleteReque" +
      "st\022\025\n\rtransactionId\030\001 \002(\003\022\017\n\007startId\030\002 \002" +
      "(\003\022\022\n\nregionName\030\003 \002(\014\022\013\n\003row\030\004 \002(\014\022\016\n\006f" +
      "amily\030\005 \002(\014\022\021\n\tqualifier\030\006 \002(\014\022\r\n\005value\030" +
      "\007 \002(\014\022\036\n\006delete\030\010 \002(\0132\016.MutationProto\"U\n" +
      "\032SsccCheckAndDeleteResponse\022\016\n\006result\030\001 " +
      "\002(\010\022\021\n\texception\030\002 \001(\t\022\024\n\014hasException\030\003" +
      " \001(\010\"\310\001\n!SsccCheckAndDeleteRegionTxReque",
      "st\022\013\n\003tid\030\001 \002(\003\022\017\n\007startId\030\002 \002(\003\022\022\n\nregi" +
      "onName\030\003 \002(\014\022\013\n\003row\030\004 \002(\014\022\016\n\006family\030\005 \002(" +
      "\014\022\021\n\tqualifier\030\006 \002(\014\022\r\n\005value\030\007 \002(\014\022\036\n\006d" +
      "elete\030\010 \002(\0132\016.MutationProto\022\022\n\nautoCommi" +
      "t\030\t \002(\010\"]\n\"SsccCheckAndDeleteRegionTxRes" +
      "ponse\022\016\n\006result\030\001 \002(\010\022\021\n\texception\030\002 \001(\t" +
      "\022\024\n\014hasException\030\003 \001(\010\"\260\001\n\026SsccCheckAndP" +
      "utRequest\022\025\n\rtransactionId\030\001 \002(\003\022\017\n\007star" +
      "tId\030\002 \002(\003\022\022\n\nregionName\030\003 \002(\014\022\013\n\003row\030\004 \002" +
      "(\014\022\016\n\006family\030\005 \002(\014\022\021\n\tqualifier\030\006 \002(\014\022\r\n",
      "\005value\030\007 \002(\014\022\033\n\003put\030\010 \002(\0132\016.MutationProt" +
      "o\"R\n\027SsccCheckAndPutResponse\022\016\n\006result\030\001" +
      " \002(\010\022\021\n\texception\030\002 \001(\t\022\024\n\014hasException\030" +
      "\003 \001(\010\"\302\001\n\036SsccCheckAndPutRegionTxRequest" +
      "\022\013\n\003tid\030\001 \002(\003\022\017\n\007startId\030\002 \002(\003\022\022\n\nregion" +
      "Name\030\003 \002(\014\022\013\n\003row\030\004 \002(\014\022\016\n\006family\030\005 \002(\014\022" +
      "\021\n\tqualifier\030\006 \002(\014\022\r\n\005value\030\007 \002(\014\022\033\n\003put" +
      "\030\010 \002(\0132\016.MutationProto\022\022\n\nautoCommit\030\t \002" +
      "(\010\"Z\n\037SsccCheckAndPutRegionTxResponse\022\016\n" +
      "\006result\030\001 \002(\010\022\021\n\texception\030\002 \001(\t\022\024\n\014hasE",
      "xception\030\003 \001(\010\"W\n\027SsccCloseScannerReques" +
      "t\022\025\n\rtransactionId\030\001 \002(\003\022\022\n\nregionName\030\002" +
      " \002(\014\022\021\n\tscannerId\030\003 \002(\003\"C\n\030SsccCloseScan" +
      "nerResponse\022\021\n\texception\030\001 \001(\t\022\024\n\014hasExc" +
      "eption\030\002 \001(\010\"\204\001\n&SsccDeleteMultipleTrans" +
      "actionalRequest\022\025\n\rtransactionId\030\001 \002(\003\022\017" +
      "\n\007startId\030\002 \002(\003\022\022\n\nregionName\030\003 \002(\014\022\036\n\006d" +
      "elete\030\004 \003(\0132\016.MutationProto\"{\n\'SsccDelet" +
      "eMultipleTransactionalResponse\022\027\n\006result" +
      "\030\001 \001(\0132\007.Result\022\021\n\texception\030\002 \001(\t\022\024\n\014ha",
      "sException\030\003 \001(\010\022\016\n\006status\030\004 \001(\005\"\201\001\n\031Ssc" +
      "cDeleteRegionTxRequest\022\013\n\003tid\030\001 \002(\003\022\017\n\007s" +
      "tartId\030\002 \002(\003\022\022\n\nregionName\030\003 \002(\014\022\036\n\006dele" +
      "te\030\004 \002(\0132\016.MutationProto\022\022\n\nautoCommit\030\005" +
      " \002(\010\"n\n\032SsccDeleteRegionTxResponse\022\027\n\006re" +
      "sult\030\001 \001(\0132\007.Result\022\021\n\texception\030\002 \001(\t\022\024" +
      "\n\014hasException\030\003 \001(\010\022\016\n\006status\030\004 \001(\005\"|\n\036" +
      "SsccDeleteTransactionalRequest\022\025\n\rtransa" +
      "ctionId\030\001 \002(\003\022\017\n\007startId\030\002 \002(\003\022\022\n\nregion" +
      "Name\030\003 \002(\014\022\036\n\006delete\030\004 \002(\0132\016.MutationPro",
      "to\"s\n\037SsccDeleteTransactionalResponse\022\027\n" +
      "\006result\030\001 \001(\0132\007.Result\022\021\n\texception\030\002 \001(" +
      "\t\022\024\n\014hasException\030\003 \001(\010\022\016\n\006status\030\004 \001(\005\"" +
      "l\n\033SsccGetTransactionalRequest\022\025\n\rtransa" +
      "ctionId\030\001 \002(\003\022\017\n\007startId\030\002 \002(\003\022\022\n\nregion" +
      "Name\030\003 \002(\014\022\021\n\003get\030\004 \002(\0132\004.Get\"`\n\034SsccGet" +
      "TransactionalResponse\022\027\n\006result\030\001 \001(\0132\007." +
      "Result\022\021\n\texception\030\002 \001(\t\022\024\n\014hasExceptio" +
      "n\030\003 \001(\010\"i\n\026SsccOpenScannerRequest\022\025\n\rtra" +
      "nsactionId\030\001 \002(\003\022\017\n\007startId\030\002 \002(\003\022\022\n\nreg",
      "ionName\030\003 \002(\014\022\023\n\004scan\030\004 \002(\0132\005.Scan\"U\n\027Ss" +
      "ccOpenScannerResponse\022\021\n\tscannerId\030\001 \002(\003" +
      "\022\021\n\texception\030\002 \001(\t\022\024\n\014hasException\030\003 \001(" +
      "\010\"\250\001\n\026SsccPerformScanRequest\022\025\n\rtransact" +
      "ionId\030\001 \002(\003\022\017\n\007startId\030\002 \002(\003\022\022\n\nregionNa" +
      "me\030\003 \002(\014\022\021\n\tscannerId\030\004 \002(\003\022\024\n\014numberOfR" +
      "ows\030\005 \002(\005\022\024\n\014closeScanner\030\006 \002(\010\022\023\n\013nextC" +
      "allSeq\030\007 \002(\003\"\220\001\n\027SsccPerformScanResponse" +
      "\022\027\n\006result\030\001 \003(\0132\007.Result\022\r\n\005count\030\002 \002(\003" +
      "\022\023\n\013nextCallSeq\030\003 \002(\003\022\017\n\007hasMore\030\004 \002(\010\022\021",
      "\n\texception\030\005 \001(\t\022\024\n\014hasException\030\006 \001(\010\"" +
      "\220\001\n\026SsccPutRegionTxRequest\022\013\n\003tid\030\001 \002(\003\022" +
      "\017\n\007startId\030\002 \002(\003\022\022\n\nregionName\030\003 \002(\014\022\033\n\003" +
      "put\030\004 \002(\0132\016.MutationProto\022\023\n\013isStateless" +
      "\030\005 \001(\010\022\022\n\nautoCommit\030\006 \002(\010\"k\n\027SsccPutReg" +
      "ionTxResponse\022\027\n\006result\030\001 \001(\0132\007.Result\022\021" +
      "\n\texception\030\002 \001(\t\022\024\n\014hasException\030\003 \001(\010\022" +
      "\016\n\006status\030\004 \001(\005\"\213\001\n\033SsccPutTransactional" +
      "Request\022\025\n\rtransactionId\030\001 \002(\003\022\017\n\007startI" +
      "d\030\002 \002(\003\022\022\n\nregionName\030\003 \002(\014\022\033\n\003put\030\004 \002(\013",
      "2\016.MutationProto\022\023\n\013isStateless\030\005 \001(\010\"p\n" +
      "\034SsccPutTransactionalResponse\022\027\n\006result\030" +
      "\001 \001(\0132\007.Result\022\021\n\texception\030\002 \001(\t\022\024\n\014has" +
      "Exception\030\003 \001(\010\022\016\n\006status\030\004 \001(\005\"\223\001\n#Sscc" +
      "PutMultipleTransactionalRequest\022\025\n\rtrans" +
      "actionId\030\001 \002(\003\022\017\n\007startId\030\002 \002(\003\022\022\n\nregio" +
      "nName\030\003 \002(\014\022\033\n\003put\030\004 \003(\0132\016.MutationProto" +
      "\022\023\n\013isStateless\030\005 \001(\010\"x\n$SsccPutMultiple" +
      "TransactionalResponse\022\027\n\006result\030\001 \001(\0132\007." +
      "Result\022\021\n\texception\030\002 \001(\t\022\024\n\014hasExceptio",
      "n\030\003 \001(\010\022\016\n\006status\030\004 \001(\005\"f\n\032SsccRecoveryR" +
      "equestRequest\022\025\n\rtransactionId\030\001 \002(\003\022\017\n\007" +
      "startId\030\002 \002(\003\022\022\n\nregionName\030\003 \002(\014\022\014\n\004tmI" +
      "d\030\004 \002(\005\"V\n\033SsccRecoveryRequestResponse\022\016" +
      "\n\006result\030\001 \003(\003\022\021\n\texception\030\002 \001(\t\022\024\n\014has" +
      "Exception\030\003 \001(\010\"\270\001\n!SsccTransactionalAgg" +
      "regateRequest\022\022\n\nregionName\030\001 \002(\014\022\025\n\rtra" +
      "nsactionId\030\002 \002(\003\022\017\n\007startId\030\003 \002(\003\022\036\n\026int" +
      "erpreter_class_name\030\004 \002(\t\022\023\n\004scan\030\005 \002(\0132" +
      "\005.Scan\022\"\n\032interpreter_specific_bytes\030\006 \001",
      "(\014\"M\n\"SsccTransactionalAggregateResponse" +
      "\022\022\n\nfirst_part\030\003 \003(\014\022\023\n\013second_part\030\004 \001(" +
      "\0142\320\020\n\021SsccRegionService\022O\n\020abortTransact" +
      "ion\022\034.SsccAbortTransactionRequest\032\035.Sscc" +
      "AbortTransactionResponse\022O\n\020beginTransac" +
      "tion\022\034.SsccBeginTransactionRequest\032\035.Ssc" +
      "cBeginTransactionResponse\022I\n\016checkAndDel" +
      "ete\022\032.SsccCheckAndDeleteRequest\032\033.SsccCh" +
      "eckAndDeleteResponse\022a\n\026checkAndDeleteRe" +
      "gionTx\022\".SsccCheckAndDeleteRegionTxReque",
      "st\032#.SsccCheckAndDeleteRegionTxResponse\022" +
      "@\n\013checkAndPut\022\027.SsccCheckAndPutRequest\032" +
      "\030.SsccCheckAndPutResponse\022X\n\023checkAndPut" +
      "RegionTx\022\037.SsccCheckAndPutRegionTxReques" +
      "t\032 .SsccCheckAndPutRegionTxResponse\022C\n\014c" +
      "loseScanner\022\030.SsccCloseScannerRequest\032\031." +
      "SsccCloseScannerResponse\0221\n\006commit\022\022.Ssc" +
      "cCommitRequest\032\023.SsccCommitResponse\022O\n\020c" +
      "ommitIfPossible\022\034.SsccCommitIfPossibleRe" +
      "quest\032\035.SsccCommitIfPossibleResponse\022F\n\r",
      "commitRequest\022\031.SsccCommitRequestRequest" +
      "\032\032.SsccCommitRequestResponse\022I\n\016deleteRe" +
      "gionTx\022\032.SsccDeleteRegionTxRequest\032\033.Ssc" +
      "cDeleteRegionTxResponse\022K\n\006delete\022\037.Sscc" +
      "DeleteTransactionalRequest\032 .SsccDeleteT" +
      "ransactionalResponse\022c\n\016deleteMultiple\022\'" +
      ".SsccDeleteMultipleTransactionalRequest\032" +
      "(.SsccDeleteMultipleTransactionalRespons" +
      "e\022B\n\003get\022\034.SsccGetTransactionalRequest\032\035" +
      ".SsccGetTransactionalResponse\022@\n\013perform",
      "Scan\022\027.SsccPerformScanRequest\032\030.SsccPerf" +
      "ormScanResponse\022@\n\013openScanner\022\027.SsccOpe" +
      "nScannerRequest\032\030.SsccOpenScannerRespons" +
      "e\022@\n\013putRegionTx\022\027.SsccPutRegionTxReques" +
      "t\032\030.SsccPutRegionTxResponse\022B\n\003put\022\034.Ssc" +
      "cPutTransactionalRequest\032\035.SsccPutTransa" +
      "ctionalResponse\022Z\n\013putMultiple\022$.SsccPut" +
      "MultipleTransactionalRequest\032%.SsccPutMu" +
      "ltipleTransactionalResponse\022L\n\017recoveryR" +
      "equest\022\033.SsccRecoveryRequestRequest\032\034.Ss",
      "ccRecoveryRequestResponse\022Q\n\006GetMax\022\".Ss" +
      "ccTransactionalAggregateRequest\032#.SsccTr" +
      "ansactionalAggregateResponse\022Q\n\006GetMin\022\"" +
      ".SsccTransactionalAggregateRequest\032#.Ssc" +
      "cTransactionalAggregateResponse\022Q\n\006GetSu" +
      "m\022\".SsccTransactionalAggregateRequest\032#." +
      "SsccTransactionalAggregateResponse\022T\n\tGe" +
      "tRowNum\022\".SsccTransactionalAggregateRequ" +
      "est\032#.SsccTransactionalAggregateResponse" +
      "\022Q\n\006GetAvg\022\".SsccTransactionalAggregateR",
      "equest\032#.SsccTransactionalAggregateRespo" +
      "nse\022Q\n\006GetStd\022\".SsccTransactionalAggrega" +
      "teRequest\032#.SsccTransactionalAggregateRe" +
      "sponse\022T\n\tGetMedian\022\".SsccTransactionalA" +
      "ggregateRequest\032#.SsccTransactionalAggre" +
      "gateResponseBT\n;org.apache.hadoop.hbase." +
      "coprocessor.transactional.generatedB\020Ssc" +
      "cRegionProtosH\001\210\001\001"
    };
    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
        public com.google.protobuf.ExtensionRegistry assignDescriptors(
            com.google.protobuf.Descriptors.FileDescriptor root) {
          descriptor = root;
          internal_static_SsccAbortTransactionRequest_descriptor =
            getDescriptor().getMessageTypes().get(0);
          internal_static_SsccAbortTransactionRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccAbortTransactionRequest_descriptor,
              new java.lang.String[] { "RegionName", "TransactionId", });
          internal_static_SsccAbortTransactionResponse_descriptor =
            getDescriptor().getMessageTypes().get(1);
          internal_static_SsccAbortTransactionResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccAbortTransactionResponse_descriptor,
              new java.lang.String[] { "Exception", "HasException", });
          internal_static_SsccBeginTransactionRequest_descriptor =
            getDescriptor().getMessageTypes().get(2);
          internal_static_SsccBeginTransactionRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccBeginTransactionRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", });
          internal_static_SsccBeginTransactionResponse_descriptor =
            getDescriptor().getMessageTypes().get(3);
          internal_static_SsccBeginTransactionResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccBeginTransactionResponse_descriptor,
              new java.lang.String[] { "Exception", "HasException", });
          internal_static_SsccCommitRequest_descriptor =
            getDescriptor().getMessageTypes().get(4);
          internal_static_SsccCommitRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCommitRequest_descriptor,
              new java.lang.String[] { "RegionName", "TransactionId", "CommitId", "IgnoreUnknownTransactionException", });
          internal_static_SsccCommitResponse_descriptor =
            getDescriptor().getMessageTypes().get(5);
          internal_static_SsccCommitResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCommitResponse_descriptor,
              new java.lang.String[] { "Exception", "HasException", });
          internal_static_SsccCommitRequestRequest_descriptor =
            getDescriptor().getMessageTypes().get(6);
          internal_static_SsccCommitRequestRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCommitRequestRequest_descriptor,
              new java.lang.String[] { "RegionName", "TransactionId", });
          internal_static_SsccCommitRequestResponse_descriptor =
            getDescriptor().getMessageTypes().get(7);
          internal_static_SsccCommitRequestResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCommitRequestResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", });
          internal_static_SsccCommitIfPossibleRequest_descriptor =
            getDescriptor().getMessageTypes().get(8);
          internal_static_SsccCommitIfPossibleRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCommitIfPossibleRequest_descriptor,
              new java.lang.String[] { "RegionName", "TransactionId", });
          internal_static_SsccCommitIfPossibleResponse_descriptor =
            getDescriptor().getMessageTypes().get(9);
          internal_static_SsccCommitIfPossibleResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCommitIfPossibleResponse_descriptor,
              new java.lang.String[] { "Exception", "HasException", "WasSuccessful", });
          internal_static_SsccCheckAndDeleteRequest_descriptor =
            getDescriptor().getMessageTypes().get(10);
          internal_static_SsccCheckAndDeleteRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCheckAndDeleteRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", "Row", "Family", "Qualifier", "Value", "Delete", });
          internal_static_SsccCheckAndDeleteResponse_descriptor =
            getDescriptor().getMessageTypes().get(11);
          internal_static_SsccCheckAndDeleteResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCheckAndDeleteResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", });
          internal_static_SsccCheckAndDeleteRegionTxRequest_descriptor =
            getDescriptor().getMessageTypes().get(12);
          internal_static_SsccCheckAndDeleteRegionTxRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCheckAndDeleteRegionTxRequest_descriptor,
              new java.lang.String[] { "Tid", "StartId", "RegionName", "Row", "Family", "Qualifier", "Value", "Delete", "AutoCommit", });
          internal_static_SsccCheckAndDeleteRegionTxResponse_descriptor =
            getDescriptor().getMessageTypes().get(13);
          internal_static_SsccCheckAndDeleteRegionTxResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCheckAndDeleteRegionTxResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", });
          internal_static_SsccCheckAndPutRequest_descriptor =
            getDescriptor().getMessageTypes().get(14);
          internal_static_SsccCheckAndPutRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCheckAndPutRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", "Row", "Family", "Qualifier", "Value", "Put", });
          internal_static_SsccCheckAndPutResponse_descriptor =
            getDescriptor().getMessageTypes().get(15);
          internal_static_SsccCheckAndPutResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCheckAndPutResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", });
          internal_static_SsccCheckAndPutRegionTxRequest_descriptor =
            getDescriptor().getMessageTypes().get(16);
          internal_static_SsccCheckAndPutRegionTxRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCheckAndPutRegionTxRequest_descriptor,
              new java.lang.String[] { "Tid", "StartId", "RegionName", "Row", "Family", "Qualifier", "Value", "Put", "AutoCommit", });
          internal_static_SsccCheckAndPutRegionTxResponse_descriptor =
            getDescriptor().getMessageTypes().get(17);
          internal_static_SsccCheckAndPutRegionTxResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCheckAndPutRegionTxResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", });
          internal_static_SsccCloseScannerRequest_descriptor =
            getDescriptor().getMessageTypes().get(18);
          internal_static_SsccCloseScannerRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCloseScannerRequest_descriptor,
              new java.lang.String[] { "TransactionId", "RegionName", "ScannerId", });
          internal_static_SsccCloseScannerResponse_descriptor =
            getDescriptor().getMessageTypes().get(19);
          internal_static_SsccCloseScannerResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccCloseScannerResponse_descriptor,
              new java.lang.String[] { "Exception", "HasException", });
          internal_static_SsccDeleteMultipleTransactionalRequest_descriptor =
            getDescriptor().getMessageTypes().get(20);
          internal_static_SsccDeleteMultipleTransactionalRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccDeleteMultipleTransactionalRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", "Delete", });
          internal_static_SsccDeleteMultipleTransactionalResponse_descriptor =
            getDescriptor().getMessageTypes().get(21);
          internal_static_SsccDeleteMultipleTransactionalResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccDeleteMultipleTransactionalResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", "Status", });
          internal_static_SsccDeleteRegionTxRequest_descriptor =
            getDescriptor().getMessageTypes().get(22);
          internal_static_SsccDeleteRegionTxRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccDeleteRegionTxRequest_descriptor,
              new java.lang.String[] { "Tid", "StartId", "RegionName", "Delete", "AutoCommit", });
          internal_static_SsccDeleteRegionTxResponse_descriptor =
            getDescriptor().getMessageTypes().get(23);
          internal_static_SsccDeleteRegionTxResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccDeleteRegionTxResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", "Status", });
          internal_static_SsccDeleteTransactionalRequest_descriptor =
            getDescriptor().getMessageTypes().get(24);
          internal_static_SsccDeleteTransactionalRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccDeleteTransactionalRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", "Delete", });
          internal_static_SsccDeleteTransactionalResponse_descriptor =
            getDescriptor().getMessageTypes().get(25);
          internal_static_SsccDeleteTransactionalResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccDeleteTransactionalResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", "Status", });
          internal_static_SsccGetTransactionalRequest_descriptor =
            getDescriptor().getMessageTypes().get(26);
          internal_static_SsccGetTransactionalRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccGetTransactionalRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", "Get", });
          internal_static_SsccGetTransactionalResponse_descriptor =
            getDescriptor().getMessageTypes().get(27);
          internal_static_SsccGetTransactionalResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccGetTransactionalResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", });
          internal_static_SsccOpenScannerRequest_descriptor =
            getDescriptor().getMessageTypes().get(28);
          internal_static_SsccOpenScannerRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccOpenScannerRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", "Scan", });
          internal_static_SsccOpenScannerResponse_descriptor =
            getDescriptor().getMessageTypes().get(29);
          internal_static_SsccOpenScannerResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccOpenScannerResponse_descriptor,
              new java.lang.String[] { "ScannerId", "Exception", "HasException", });
          internal_static_SsccPerformScanRequest_descriptor =
            getDescriptor().getMessageTypes().get(30);
          internal_static_SsccPerformScanRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccPerformScanRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", "ScannerId", "NumberOfRows", "CloseScanner", "NextCallSeq", });
          internal_static_SsccPerformScanResponse_descriptor =
            getDescriptor().getMessageTypes().get(31);
          internal_static_SsccPerformScanResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccPerformScanResponse_descriptor,
              new java.lang.String[] { "Result", "Count", "NextCallSeq", "HasMore", "Exception", "HasException", });
          internal_static_SsccPutRegionTxRequest_descriptor =
            getDescriptor().getMessageTypes().get(32);
          internal_static_SsccPutRegionTxRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccPutRegionTxRequest_descriptor,
              new java.lang.String[] { "Tid", "StartId", "RegionName", "Put", "IsStateless", "AutoCommit", });
          internal_static_SsccPutRegionTxResponse_descriptor =
            getDescriptor().getMessageTypes().get(33);
          internal_static_SsccPutRegionTxResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccPutRegionTxResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", "Status", });
          internal_static_SsccPutTransactionalRequest_descriptor =
            getDescriptor().getMessageTypes().get(34);
          internal_static_SsccPutTransactionalRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccPutTransactionalRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", "Put", "IsStateless", });
          internal_static_SsccPutTransactionalResponse_descriptor =
            getDescriptor().getMessageTypes().get(35);
          internal_static_SsccPutTransactionalResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccPutTransactionalResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", "Status", });
          internal_static_SsccPutMultipleTransactionalRequest_descriptor =
            getDescriptor().getMessageTypes().get(36);
          internal_static_SsccPutMultipleTransactionalRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccPutMultipleTransactionalRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", "Put", "IsStateless", });
          internal_static_SsccPutMultipleTransactionalResponse_descriptor =
            getDescriptor().getMessageTypes().get(37);
          internal_static_SsccPutMultipleTransactionalResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccPutMultipleTransactionalResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", "Status", });
          internal_static_SsccRecoveryRequestRequest_descriptor =
            getDescriptor().getMessageTypes().get(38);
          internal_static_SsccRecoveryRequestRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccRecoveryRequestRequest_descriptor,
              new java.lang.String[] { "TransactionId", "StartId", "RegionName", "TmId", });
          internal_static_SsccRecoveryRequestResponse_descriptor =
            getDescriptor().getMessageTypes().get(39);
          internal_static_SsccRecoveryRequestResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccRecoveryRequestResponse_descriptor,
              new java.lang.String[] { "Result", "Exception", "HasException", });
          internal_static_SsccTransactionalAggregateRequest_descriptor =
            getDescriptor().getMessageTypes().get(40);
          internal_static_SsccTransactionalAggregateRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccTransactionalAggregateRequest_descriptor,
              new java.lang.String[] { "RegionName", "TransactionId", "StartId", "InterpreterClassName", "Scan", "InterpreterSpecificBytes", });
          internal_static_SsccTransactionalAggregateResponse_descriptor =
            getDescriptor().getMessageTypes().get(41);
          internal_static_SsccTransactionalAggregateResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_SsccTransactionalAggregateResponse_descriptor,
              new java.lang.String[] { "FirstPart", "SecondPart", });
          return null;
        }
      };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.getDescriptor(),
          org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos.getDescriptor(),
          org.apache.hadoop.hbase.protobuf.generated.ClientProtos.getDescriptor(),
        }, assigner);
  }

  // @@protoc_insertion_point(outer_class_scope)
}
