/**
 * * @@@ 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)
}
