// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: org/eclipse/jgit/storage/dht/git_store.proto

package org.eclipse.jgit.generated.storage.dht.proto;

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

    // required uint32 sequence = 5 [default = 0];
    boolean hasSequence();
    int getSequence();

    // optional string symref = 1;
    boolean hasSymref();
    String getSymref();

    // optional .org.eclipse.jgit.storage.dht.RefData.Id target = 2;
    boolean hasTarget();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id getTarget();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder getTargetOrBuilder();

    // optional bool is_peeled = 3;
    boolean hasIsPeeled();
    boolean getIsPeeled();

    // optional .org.eclipse.jgit.storage.dht.RefData.Id peeled = 4;
    boolean hasPeeled();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id getPeeled();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder getPeeledOrBuilder();
  }
  public static final class RefData extends
      com.google.protobuf.GeneratedMessage
      implements RefDataOrBuilder {
    // Use RefData.newBuilder() to construct.
    private RefData(Builder builder) {
      super(builder);
    }
    private RefData(boolean noInit) {}

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

    public RefData getDefaultInstanceForType() {
      return defaultInstance;
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_RefData_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_RefData_fieldAccessorTable;
    }

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

      // required string object_name = 1;
      boolean hasObjectName();
      String getObjectName();

      // optional string chunk_key = 2;
      boolean hasChunkKey();
      String getChunkKey();
    }
    public static final class Id extends
        com.google.protobuf.GeneratedMessage
        implements IdOrBuilder {
      // Use Id.newBuilder() to construct.
      private Id(Builder builder) {
        super(builder);
      }
      private Id(boolean noInit) {}

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

      public Id getDefaultInstanceForType() {
        return defaultInstance;
      }

      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_RefData_Id_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_RefData_Id_fieldAccessorTable;
      }

      private int bitField0_;
      // required string object_name = 1;
      public static final int OBJECT_NAME_FIELD_NUMBER = 1;
      private Object objectName_;
      public boolean hasObjectName() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      public String getObjectName() {
        Object ref = objectName_;
        if (ref instanceof String) {
          return (String) ref;
        } else {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          String s = bs.toStringUtf8();
          if (com.google.protobuf.Internal.isValidUtf8(bs)) {
            objectName_ = s;
          }
          return s;
        }
      }
      private com.google.protobuf.ByteString getObjectNameBytes() {
        Object ref = objectName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b =
              com.google.protobuf.ByteString.copyFromUtf8((String) ref);
          objectName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }

      // optional string chunk_key = 2;
      public static final int CHUNK_KEY_FIELD_NUMBER = 2;
      private Object chunkKey_;
      public boolean hasChunkKey() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      public String getChunkKey() {
        Object ref = chunkKey_;
        if (ref instanceof String) {
          return (String) ref;
        } else {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          String s = bs.toStringUtf8();
          if (com.google.protobuf.Internal.isValidUtf8(bs)) {
            chunkKey_ = s;
          }
          return s;
        }
      }
      private com.google.protobuf.ByteString getChunkKeyBytes() {
        Object ref = chunkKey_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b =
              com.google.protobuf.ByteString.copyFromUtf8((String) ref);
          chunkKey_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }

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

        if (!hasObjectName()) {
          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, getObjectNameBytes());
        }
        if (((bitField0_ & 0x00000002) == 0x00000002)) {
          output.writeBytes(2, getChunkKeyBytes());
        }
        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, getObjectNameBytes());
        }
        if (((bitField0_ & 0x00000002) == 0x00000002)) {
          size += com.google.protobuf.CodedOutputStream
            .computeBytesSize(2, getChunkKeyBytes());
        }
        size += getUnknownFields().getSerializedSize();
        memoizedSerializedSize = size;
        return size;
      }

      @java.lang.Override
      protected Object writeReplace() throws java.io.ObjectStreamException {
        return super.writeReplace();
      }

      @java.lang.Override
      public boolean equals(final Object obj) {
        if (obj == this) {
         return true;
        }
        if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id)) {
          return super.equals(obj);
        }
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id) obj;

        boolean result = true;
        result = result && (hasObjectName() == other.hasObjectName());
        if (hasObjectName()) {
          result = result && getObjectName()
              .equals(other.getObjectName());
        }
        result = result && (hasChunkKey() == other.hasChunkKey());
        if (hasChunkKey()) {
          result = result && getChunkKey()
              .equals(other.getChunkKey());
        }
        result = result &&
            getUnknownFields().equals(other.getUnknownFields());
        return result;
      }

      @java.lang.Override
      public int hashCode() {
        int hash = 41;
        hash = (19 * hash) + getDescriptorForType().hashCode();
        if (hasObjectName()) {
          hash = (37 * hash) + OBJECT_NAME_FIELD_NUMBER;
          hash = (53 * hash) + getObjectName().hashCode();
        }
        if (hasChunkKey()) {
          hash = (37 * hash) + CHUNK_KEY_FIELD_NUMBER;
          hash = (53 * hash) + getChunkKey().hashCode();
        }
        hash = (29 * hash) + getUnknownFields().hashCode();
        return hash;
      }

      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id parseFrom(
          com.google.protobuf.ByteString data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id parseFrom(
          com.google.protobuf.ByteString data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id parseFrom(byte[] data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id parseFrom(
          byte[] data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id parseFrom(java.io.InputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id parseFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id parseDelimitedFrom(java.io.InputStream input)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id parseDelimitedFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id parseFrom(
          com.google.protobuf.CodedInputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id parseFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }

      public static Builder newBuilder() { return Builder.create(); }
      public Builder newBuilderForType() { return newBuilder(); }
      public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id 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;
      }
      public static final class Builder extends
          com.google.protobuf.GeneratedMessage.Builder<Builder>
         implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder {
        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_RefData_Id_descriptor;
        }

        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_RefData_Id_fieldAccessorTable;
        }

        // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.newBuilder()
        private Builder() {
          maybeForceBuilderInitialization();
        }

        private Builder(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();
          objectName_ = "";
          bitField0_ = (bitField0_ & ~0x00000001);
          chunkKey_ = "";
          bitField0_ = (bitField0_ & ~0x00000002);
          return this;
        }

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

        public com.google.protobuf.Descriptors.Descriptor
            getDescriptorForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDescriptor();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id getDefaultInstanceForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id build() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(result);
          }
          return result;
        }

        private org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id buildParsed()
            throws com.google.protobuf.InvalidProtocolBufferException {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(
              result).asInvalidProtocolBufferException();
          }
          return result;
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id buildPartial() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id(this);
          int from_bitField0_ = bitField0_;
          int to_bitField0_ = 0;
          if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
            to_bitField0_ |= 0x00000001;
          }
          result.objectName_ = objectName_;
          if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
            to_bitField0_ |= 0x00000002;
          }
          result.chunkKey_ = chunkKey_;
          result.bitField0_ = to_bitField0_;
          onBuilt();
          return result;
        }

        public Builder mergeFrom(com.google.protobuf.Message other) {
          if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id) {
            return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id)other);
          } else {
            super.mergeFrom(other);
            return this;
          }
        }

        public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id other) {
          if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance()) return this;
          if (other.hasObjectName()) {
            setObjectName(other.getObjectName());
          }
          if (other.hasChunkKey()) {
            setChunkKey(other.getChunkKey());
          }
          this.mergeUnknownFields(other.getUnknownFields());
          return this;
        }

        public final boolean isInitialized() {
          if (!hasObjectName()) {

            return false;
          }
          return true;
        }

        public Builder mergeFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
            com.google.protobuf.UnknownFieldSet.newBuilder(
              this.getUnknownFields());
          while (true) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              default: {
                if (!parseUnknownField(input, unknownFields,
                                       extensionRegistry, tag)) {
                  this.setUnknownFields(unknownFields.build());
                  onChanged();
                  return this;
                }
                break;
              }
              case 10: {
                bitField0_ |= 0x00000001;
                objectName_ = input.readBytes();
                break;
              }
              case 18: {
                bitField0_ |= 0x00000002;
                chunkKey_ = input.readBytes();
                break;
              }
            }
          }
        }

        private int bitField0_;

        // required string object_name = 1;
        private Object objectName_ = "";
        public boolean hasObjectName() {
          return ((bitField0_ & 0x00000001) == 0x00000001);
        }
        public String getObjectName() {
          Object ref = objectName_;
          if (!(ref instanceof String)) {
            String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
            objectName_ = s;
            return s;
          } else {
            return (String) ref;
          }
        }
        public Builder setObjectName(String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
          objectName_ = value;
          onChanged();
          return this;
        }
        public Builder clearObjectName() {
          bitField0_ = (bitField0_ & ~0x00000001);
          objectName_ = getDefaultInstance().getObjectName();
          onChanged();
          return this;
        }
        void setObjectName(com.google.protobuf.ByteString value) {
          bitField0_ |= 0x00000001;
          objectName_ = value;
          onChanged();
        }

        // optional string chunk_key = 2;
        private Object chunkKey_ = "";
        public boolean hasChunkKey() {
          return ((bitField0_ & 0x00000002) == 0x00000002);
        }
        public String getChunkKey() {
          Object ref = chunkKey_;
          if (!(ref instanceof String)) {
            String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
            chunkKey_ = s;
            return s;
          } else {
            return (String) ref;
          }
        }
        public Builder setChunkKey(String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
          chunkKey_ = value;
          onChanged();
          return this;
        }
        public Builder clearChunkKey() {
          bitField0_ = (bitField0_ & ~0x00000002);
          chunkKey_ = getDefaultInstance().getChunkKey();
          onChanged();
          return this;
        }
        void setChunkKey(com.google.protobuf.ByteString value) {
          bitField0_ |= 0x00000002;
          chunkKey_ = value;
          onChanged();
        }

        // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.RefData.Id)
      }

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

      // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.RefData.Id)
    }

    private int bitField0_;
    // required uint32 sequence = 5 [default = 0];
    public static final int SEQUENCE_FIELD_NUMBER = 5;
    private int sequence_;
    public boolean hasSequence() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    public int getSequence() {
      return sequence_;
    }

    // optional string symref = 1;
    public static final int SYMREF_FIELD_NUMBER = 1;
    private Object symref_;
    public boolean hasSymref() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    public String getSymref() {
      Object ref = symref_;
      if (ref instanceof String) {
        return (String) ref;
      } else {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        String s = bs.toStringUtf8();
        if (com.google.protobuf.Internal.isValidUtf8(bs)) {
          symref_ = s;
        }
        return s;
      }
    }
    private com.google.protobuf.ByteString getSymrefBytes() {
      Object ref = symref_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8((String) ref);
        symref_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional .org.eclipse.jgit.storage.dht.RefData.Id target = 2;
    public static final int TARGET_FIELD_NUMBER = 2;
    private org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id target_;
    public boolean hasTarget() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id getTarget() {
      return target_;
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder getTargetOrBuilder() {
      return target_;
    }

    // optional bool is_peeled = 3;
    public static final int IS_PEELED_FIELD_NUMBER = 3;
    private boolean isPeeled_;
    public boolean hasIsPeeled() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    public boolean getIsPeeled() {
      return isPeeled_;
    }

    // optional .org.eclipse.jgit.storage.dht.RefData.Id peeled = 4;
    public static final int PEELED_FIELD_NUMBER = 4;
    private org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id peeled_;
    public boolean hasPeeled() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id getPeeled() {
      return peeled_;
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder getPeeledOrBuilder() {
      return peeled_;
    }

    private void initFields() {
      sequence_ = 0;
      symref_ = "";
      target_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance();
      isPeeled_ = false;
      peeled_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasSequence()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasTarget()) {
        if (!getTarget().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasPeeled()) {
        if (!getPeeled().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(1, getSymrefBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(2, target_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBool(3, isPeeled_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeMessage(4, peeled_);
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeUInt32(5, sequence_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, getSymrefBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, target_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, isPeeled_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, peeled_);
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(5, sequence_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    @java.lang.Override
    protected Object writeReplace() throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    @java.lang.Override
    public boolean equals(final Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData)) {
        return super.equals(obj);
      }
      org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData) obj;

      boolean result = true;
      result = result && (hasSequence() == other.hasSequence());
      if (hasSequence()) {
        result = result && (getSequence()
            == other.getSequence());
      }
      result = result && (hasSymref() == other.hasSymref());
      if (hasSymref()) {
        result = result && getSymref()
            .equals(other.getSymref());
      }
      result = result && (hasTarget() == other.hasTarget());
      if (hasTarget()) {
        result = result && getTarget()
            .equals(other.getTarget());
      }
      result = result && (hasIsPeeled() == other.hasIsPeeled());
      if (hasIsPeeled()) {
        result = result && (getIsPeeled()
            == other.getIsPeeled());
      }
      result = result && (hasPeeled() == other.hasPeeled());
      if (hasPeeled()) {
        result = result && getPeeled()
            .equals(other.getPeeled());
      }
      result = result &&
          getUnknownFields().equals(other.getUnknownFields());
      return result;
    }

    @java.lang.Override
    public int hashCode() {
      int hash = 41;
      hash = (19 * hash) + getDescriptorForType().hashCode();
      if (hasSequence()) {
        hash = (37 * hash) + SEQUENCE_FIELD_NUMBER;
        hash = (53 * hash) + getSequence();
      }
      if (hasSymref()) {
        hash = (37 * hash) + SYMREF_FIELD_NUMBER;
        hash = (53 * hash) + getSymref().hashCode();
      }
      if (hasTarget()) {
        hash = (37 * hash) + TARGET_FIELD_NUMBER;
        hash = (53 * hash) + getTarget().hashCode();
      }
      if (hasIsPeeled()) {
        hash = (37 * hash) + IS_PEELED_FIELD_NUMBER;
        hash = (53 * hash) + hashBoolean(getIsPeeled());
      }
      if (hasPeeled()) {
        hash = (37 * hash) + PEELED_FIELD_NUMBER;
        hash = (53 * hash) + getPeeled().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      return hash;
    }

    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData 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;
    }
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefDataOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_RefData_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_RefData_fieldAccessorTable;
      }

      // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

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

      public Builder clear() {
        super.clear();
        sequence_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        symref_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        if (targetBuilder_ == null) {
          target_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance();
        } else {
          targetBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        isPeeled_ = false;
        bitField0_ = (bitField0_ & ~0x00000008);
        if (peeledBuilder_ == null) {
          peeled_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance();
        } else {
          peeledBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }

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

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.getDescriptor();
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData getDefaultInstanceForType() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.getDefaultInstance();
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData build() {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData buildParsed()
          throws com.google.protobuf.InvalidProtocolBufferException {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(
            result).asInvalidProtocolBufferException();
        }
        return result;
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData buildPartial() {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.sequence_ = sequence_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.symref_ = symref_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        if (targetBuilder_ == null) {
          result.target_ = target_;
        } else {
          result.target_ = targetBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.isPeeled_ = isPeeled_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        if (peeledBuilder_ == null) {
          result.peeled_ = peeled_;
        } else {
          result.peeled_ = peeledBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData) {
          return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData other) {
        if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.getDefaultInstance()) return this;
        if (other.hasSequence()) {
          setSequence(other.getSequence());
        }
        if (other.hasSymref()) {
          setSymref(other.getSymref());
        }
        if (other.hasTarget()) {
          mergeTarget(other.getTarget());
        }
        if (other.hasIsPeeled()) {
          setIsPeeled(other.getIsPeeled());
        }
        if (other.hasPeeled()) {
          mergePeeled(other.getPeeled());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasSequence()) {

          return false;
        }
        if (hasTarget()) {
          if (!getTarget().isInitialized()) {

            return false;
          }
        }
        if (hasPeeled()) {
          if (!getPeeled().isInitialized()) {

            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder(
            this.getUnknownFields());
        while (true) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              this.setUnknownFields(unknownFields.build());
              onChanged();
              return this;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000002;
              symref_ = input.readBytes();
              break;
            }
            case 18: {
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder subBuilder = org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.newBuilder();
              if (hasTarget()) {
                subBuilder.mergeFrom(getTarget());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setTarget(subBuilder.buildPartial());
              break;
            }
            case 24: {
              bitField0_ |= 0x00000008;
              isPeeled_ = input.readBool();
              break;
            }
            case 34: {
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder subBuilder = org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.newBuilder();
              if (hasPeeled()) {
                subBuilder.mergeFrom(getPeeled());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setPeeled(subBuilder.buildPartial());
              break;
            }
            case 40: {
              bitField0_ |= 0x00000001;
              sequence_ = input.readUInt32();
              break;
            }
          }
        }
      }

      private int bitField0_;

      // required uint32 sequence = 5 [default = 0];
      private int sequence_ ;
      public boolean hasSequence() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      public int getSequence() {
        return sequence_;
      }
      public Builder setSequence(int value) {
        bitField0_ |= 0x00000001;
        sequence_ = value;
        onChanged();
        return this;
      }
      public Builder clearSequence() {
        bitField0_ = (bitField0_ & ~0x00000001);
        sequence_ = 0;
        onChanged();
        return this;
      }

      // optional string symref = 1;
      private Object symref_ = "";
      public boolean hasSymref() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      public String getSymref() {
        Object ref = symref_;
        if (!(ref instanceof String)) {
          String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
          symref_ = s;
          return s;
        } else {
          return (String) ref;
        }
      }
      public Builder setSymref(String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        symref_ = value;
        onChanged();
        return this;
      }
      public Builder clearSymref() {
        bitField0_ = (bitField0_ & ~0x00000002);
        symref_ = getDefaultInstance().getSymref();
        onChanged();
        return this;
      }
      void setSymref(com.google.protobuf.ByteString value) {
        bitField0_ |= 0x00000002;
        symref_ = value;
        onChanged();
      }

      // optional .org.eclipse.jgit.storage.dht.RefData.Id target = 2;
      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id target_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder> targetBuilder_;
      public boolean hasTarget() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id getTarget() {
        if (targetBuilder_ == null) {
          return target_;
        } else {
          return targetBuilder_.getMessage();
        }
      }
      public Builder setTarget(org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id value) {
        if (targetBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          target_ = value;
          onChanged();
        } else {
          targetBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      public Builder setTarget(
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder builderForValue) {
        if (targetBuilder_ == null) {
          target_ = builderForValue.build();
          onChanged();
        } else {
          targetBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      public Builder mergeTarget(org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id value) {
        if (targetBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004) &&
              target_ != org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance()) {
            target_ =
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.newBuilder(target_).mergeFrom(value).buildPartial();
          } else {
            target_ = value;
          }
          onChanged();
        } else {
          targetBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      public Builder clearTarget() {
        if (targetBuilder_ == null) {
          target_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance();
          onChanged();
        } else {
          targetBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder getTargetBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getTargetFieldBuilder().getBuilder();
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder getTargetOrBuilder() {
        if (targetBuilder_ != null) {
          return targetBuilder_.getMessageOrBuilder();
        } else {
          return target_;
        }
      }
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder>
          getTargetFieldBuilder() {
        if (targetBuilder_ == null) {
          targetBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder>(
                  target_,
                  getParentForChildren(),
                  isClean());
          target_ = null;
        }
        return targetBuilder_;
      }

      // optional bool is_peeled = 3;
      private boolean isPeeled_ ;
      public boolean hasIsPeeled() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      public boolean getIsPeeled() {
        return isPeeled_;
      }
      public Builder setIsPeeled(boolean value) {
        bitField0_ |= 0x00000008;
        isPeeled_ = value;
        onChanged();
        return this;
      }
      public Builder clearIsPeeled() {
        bitField0_ = (bitField0_ & ~0x00000008);
        isPeeled_ = false;
        onChanged();
        return this;
      }

      // optional .org.eclipse.jgit.storage.dht.RefData.Id peeled = 4;
      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id peeled_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder> peeledBuilder_;
      public boolean hasPeeled() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id getPeeled() {
        if (peeledBuilder_ == null) {
          return peeled_;
        } else {
          return peeledBuilder_.getMessage();
        }
      }
      public Builder setPeeled(org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id value) {
        if (peeledBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          peeled_ = value;
          onChanged();
        } else {
          peeledBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      public Builder setPeeled(
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder builderForValue) {
        if (peeledBuilder_ == null) {
          peeled_ = builderForValue.build();
          onChanged();
        } else {
          peeledBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      public Builder mergePeeled(org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id value) {
        if (peeledBuilder_ == null) {
          if (((bitField0_ & 0x00000010) == 0x00000010) &&
              peeled_ != org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance()) {
            peeled_ =
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.newBuilder(peeled_).mergeFrom(value).buildPartial();
          } else {
            peeled_ = value;
          }
          onChanged();
        } else {
          peeledBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      public Builder clearPeeled() {
        if (peeledBuilder_ == null) {
          peeled_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.getDefaultInstance();
          onChanged();
        } else {
          peeledBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder getPeeledBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getPeeledFieldBuilder().getBuilder();
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder getPeeledOrBuilder() {
        if (peeledBuilder_ != null) {
          return peeledBuilder_.getMessageOrBuilder();
        } else {
          return peeled_;
        }
      }
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder>
          getPeeledFieldBuilder() {
        if (peeledBuilder_ == null) {
          peeledBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.IdOrBuilder>(
                  peeled_,
                  getParentForChildren(),
                  isClean());
          peeled_ = null;
        }
        return peeledBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.RefData)
    }

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

    // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.RefData)
  }

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

    // optional .org.eclipse.jgit.storage.dht.ObjectInfo.ObjectType object_type = 1;
    boolean hasObjectType();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType getObjectType();

    // required int32 offset = 2;
    boolean hasOffset();
    int getOffset();

    // required int64 packed_size = 3;
    boolean hasPackedSize();
    long getPackedSize();

    // required int64 inflated_size = 4;
    boolean hasInflatedSize();
    long getInflatedSize();

    // optional bytes delta_base = 5;
    boolean hasDeltaBase();
    com.google.protobuf.ByteString getDeltaBase();

    // optional bool is_fragmented = 6;
    boolean hasIsFragmented();
    boolean getIsFragmented();
  }
  public static final class ObjectInfo extends
      com.google.protobuf.GeneratedMessage
      implements ObjectInfoOrBuilder {
    // Use ObjectInfo.newBuilder() to construct.
    private ObjectInfo(Builder builder) {
      super(builder);
    }
    private ObjectInfo(boolean noInit) {}

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

    public ObjectInfo getDefaultInstanceForType() {
      return defaultInstance;
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ObjectInfo_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ObjectInfo_fieldAccessorTable;
    }

    public enum ObjectType
        implements com.google.protobuf.ProtocolMessageEnum {
      COMMIT(0, 1),
      TREE(1, 2),
      BLOB(2, 3),
      TAG(3, 4),
      ;

      public static final int COMMIT_VALUE = 1;
      public static final int TREE_VALUE = 2;
      public static final int BLOB_VALUE = 3;
      public static final int TAG_VALUE = 4;


      public final int getNumber() { return value; }

      public static ObjectType valueOf(int value) {
        switch (value) {
          case 1: return COMMIT;
          case 2: return TREE;
          case 3: return BLOB;
          case 4: return TAG;
          default: return null;
        }
      }

      public static com.google.protobuf.Internal.EnumLiteMap<ObjectType>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static com.google.protobuf.Internal.EnumLiteMap<ObjectType>
          internalValueMap =
            new com.google.protobuf.Internal.EnumLiteMap<ObjectType>() {
              public ObjectType findValueByNumber(int number) {
                return ObjectType.valueOf(number);
              }
            };

      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(index);
      }
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.getDescriptor().getEnumTypes().get(0);
      }

      private static final ObjectType[] VALUES = {
        COMMIT, TREE, BLOB, TAG,
      };

      public static ObjectType valueOf(
          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        return VALUES[desc.getIndex()];
      }

      private final int index;
      private final int value;

      private ObjectType(int index, int value) {
        this.index = index;
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:org.eclipse.jgit.storage.dht.ObjectInfo.ObjectType)
    }

    private int bitField0_;
    // optional .org.eclipse.jgit.storage.dht.ObjectInfo.ObjectType object_type = 1;
    public static final int OBJECT_TYPE_FIELD_NUMBER = 1;
    private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType objectType_;
    public boolean hasObjectType() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType getObjectType() {
      return objectType_;
    }

    // required int32 offset = 2;
    public static final int OFFSET_FIELD_NUMBER = 2;
    private int offset_;
    public boolean hasOffset() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    public int getOffset() {
      return offset_;
    }

    // required int64 packed_size = 3;
    public static final int PACKED_SIZE_FIELD_NUMBER = 3;
    private long packedSize_;
    public boolean hasPackedSize() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    public long getPackedSize() {
      return packedSize_;
    }

    // required int64 inflated_size = 4;
    public static final int INFLATED_SIZE_FIELD_NUMBER = 4;
    private long inflatedSize_;
    public boolean hasInflatedSize() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    public long getInflatedSize() {
      return inflatedSize_;
    }

    // optional bytes delta_base = 5;
    public static final int DELTA_BASE_FIELD_NUMBER = 5;
    private com.google.protobuf.ByteString deltaBase_;
    public boolean hasDeltaBase() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    public com.google.protobuf.ByteString getDeltaBase() {
      return deltaBase_;
    }

    // optional bool is_fragmented = 6;
    public static final int IS_FRAGMENTED_FIELD_NUMBER = 6;
    private boolean isFragmented_;
    public boolean hasIsFragmented() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    public boolean getIsFragmented() {
      return isFragmented_;
    }

    private void initFields() {
      objectType_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType.COMMIT;
      offset_ = 0;
      packedSize_ = 0L;
      inflatedSize_ = 0L;
      deltaBase_ = com.google.protobuf.ByteString.EMPTY;
      isFragmented_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasOffset()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasPackedSize()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasInflatedSize()) {
        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.writeEnum(1, objectType_.getNumber());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, offset_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt64(3, packedSize_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt64(4, inflatedSize_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeBytes(5, deltaBase_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeBool(6, isFragmented_);
      }
      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
          .computeEnumSize(1, objectType_.getNumber());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, offset_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, packedSize_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(4, inflatedSize_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(5, deltaBase_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(6, isFragmented_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    @java.lang.Override
    protected Object writeReplace() throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    @java.lang.Override
    public boolean equals(final Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo)) {
        return super.equals(obj);
      }
      org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo) obj;

      boolean result = true;
      result = result && (hasObjectType() == other.hasObjectType());
      if (hasObjectType()) {
        result = result &&
            (getObjectType() == other.getObjectType());
      }
      result = result && (hasOffset() == other.hasOffset());
      if (hasOffset()) {
        result = result && (getOffset()
            == other.getOffset());
      }
      result = result && (hasPackedSize() == other.hasPackedSize());
      if (hasPackedSize()) {
        result = result && (getPackedSize()
            == other.getPackedSize());
      }
      result = result && (hasInflatedSize() == other.hasInflatedSize());
      if (hasInflatedSize()) {
        result = result && (getInflatedSize()
            == other.getInflatedSize());
      }
      result = result && (hasDeltaBase() == other.hasDeltaBase());
      if (hasDeltaBase()) {
        result = result && getDeltaBase()
            .equals(other.getDeltaBase());
      }
      result = result && (hasIsFragmented() == other.hasIsFragmented());
      if (hasIsFragmented()) {
        result = result && (getIsFragmented()
            == other.getIsFragmented());
      }
      result = result &&
          getUnknownFields().equals(other.getUnknownFields());
      return result;
    }

    @java.lang.Override
    public int hashCode() {
      int hash = 41;
      hash = (19 * hash) + getDescriptorForType().hashCode();
      if (hasObjectType()) {
        hash = (37 * hash) + OBJECT_TYPE_FIELD_NUMBER;
        hash = (53 * hash) + hashEnum(getObjectType());
      }
      if (hasOffset()) {
        hash = (37 * hash) + OFFSET_FIELD_NUMBER;
        hash = (53 * hash) + getOffset();
      }
      if (hasPackedSize()) {
        hash = (37 * hash) + PACKED_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getPackedSize());
      }
      if (hasInflatedSize()) {
        hash = (37 * hash) + INFLATED_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getInflatedSize());
      }
      if (hasDeltaBase()) {
        hash = (37 * hash) + DELTA_BASE_FIELD_NUMBER;
        hash = (53 * hash) + getDeltaBase().hashCode();
      }
      if (hasIsFragmented()) {
        hash = (37 * hash) + IS_FRAGMENTED_FIELD_NUMBER;
        hash = (53 * hash) + hashBoolean(getIsFragmented());
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      return hash;
    }

    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo 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;
    }
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfoOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ObjectInfo_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ObjectInfo_fieldAccessorTable;
      }

      // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(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();
        objectType_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType.COMMIT;
        bitField0_ = (bitField0_ & ~0x00000001);
        offset_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        packedSize_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000004);
        inflatedSize_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000008);
        deltaBase_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000010);
        isFragmented_ = false;
        bitField0_ = (bitField0_ & ~0x00000020);
        return this;
      }

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

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.getDescriptor();
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo getDefaultInstanceForType() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.getDefaultInstance();
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo build() {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo buildParsed()
          throws com.google.protobuf.InvalidProtocolBufferException {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(
            result).asInvalidProtocolBufferException();
        }
        return result;
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo buildPartial() {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.objectType_ = objectType_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.offset_ = offset_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.packedSize_ = packedSize_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.inflatedSize_ = inflatedSize_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.deltaBase_ = deltaBase_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.isFragmented_ = isFragmented_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo) {
          return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo other) {
        if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.getDefaultInstance()) return this;
        if (other.hasObjectType()) {
          setObjectType(other.getObjectType());
        }
        if (other.hasOffset()) {
          setOffset(other.getOffset());
        }
        if (other.hasPackedSize()) {
          setPackedSize(other.getPackedSize());
        }
        if (other.hasInflatedSize()) {
          setInflatedSize(other.getInflatedSize());
        }
        if (other.hasDeltaBase()) {
          setDeltaBase(other.getDeltaBase());
        }
        if (other.hasIsFragmented()) {
          setIsFragmented(other.getIsFragmented());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasOffset()) {

          return false;
        }
        if (!hasPackedSize()) {

          return false;
        }
        if (!hasInflatedSize()) {

          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder(
            this.getUnknownFields());
        while (true) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              this.setUnknownFields(unknownFields.build());
              onChanged();
              return this;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              }
              break;
            }
            case 8: {
              int rawValue = input.readEnum();
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType value = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(1, rawValue);
              } else {
                bitField0_ |= 0x00000001;
                objectType_ = value;
              }
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              offset_ = input.readInt32();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              packedSize_ = input.readInt64();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              inflatedSize_ = input.readInt64();
              break;
            }
            case 42: {
              bitField0_ |= 0x00000010;
              deltaBase_ = input.readBytes();
              break;
            }
            case 48: {
              bitField0_ |= 0x00000020;
              isFragmented_ = input.readBool();
              break;
            }
          }
        }
      }

      private int bitField0_;

      // optional .org.eclipse.jgit.storage.dht.ObjectInfo.ObjectType object_type = 1;
      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType objectType_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType.COMMIT;
      public boolean hasObjectType() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType getObjectType() {
        return objectType_;
      }
      public Builder setObjectType(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        objectType_ = value;
        onChanged();
        return this;
      }
      public Builder clearObjectType() {
        bitField0_ = (bitField0_ & ~0x00000001);
        objectType_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.ObjectType.COMMIT;
        onChanged();
        return this;
      }

      // required int32 offset = 2;
      private int offset_ ;
      public boolean hasOffset() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      public int getOffset() {
        return offset_;
      }
      public Builder setOffset(int value) {
        bitField0_ |= 0x00000002;
        offset_ = value;
        onChanged();
        return this;
      }
      public Builder clearOffset() {
        bitField0_ = (bitField0_ & ~0x00000002);
        offset_ = 0;
        onChanged();
        return this;
      }

      // required int64 packed_size = 3;
      private long packedSize_ ;
      public boolean hasPackedSize() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      public long getPackedSize() {
        return packedSize_;
      }
      public Builder setPackedSize(long value) {
        bitField0_ |= 0x00000004;
        packedSize_ = value;
        onChanged();
        return this;
      }
      public Builder clearPackedSize() {
        bitField0_ = (bitField0_ & ~0x00000004);
        packedSize_ = 0L;
        onChanged();
        return this;
      }

      // required int64 inflated_size = 4;
      private long inflatedSize_ ;
      public boolean hasInflatedSize() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      public long getInflatedSize() {
        return inflatedSize_;
      }
      public Builder setInflatedSize(long value) {
        bitField0_ |= 0x00000008;
        inflatedSize_ = value;
        onChanged();
        return this;
      }
      public Builder clearInflatedSize() {
        bitField0_ = (bitField0_ & ~0x00000008);
        inflatedSize_ = 0L;
        onChanged();
        return this;
      }

      // optional bytes delta_base = 5;
      private com.google.protobuf.ByteString deltaBase_ = com.google.protobuf.ByteString.EMPTY;
      public boolean hasDeltaBase() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      public com.google.protobuf.ByteString getDeltaBase() {
        return deltaBase_;
      }
      public Builder setDeltaBase(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        deltaBase_ = value;
        onChanged();
        return this;
      }
      public Builder clearDeltaBase() {
        bitField0_ = (bitField0_ & ~0x00000010);
        deltaBase_ = getDefaultInstance().getDeltaBase();
        onChanged();
        return this;
      }

      // optional bool is_fragmented = 6;
      private boolean isFragmented_ ;
      public boolean hasIsFragmented() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      public boolean getIsFragmented() {
        return isFragmented_;
      }
      public Builder setIsFragmented(boolean value) {
        bitField0_ |= 0x00000020;
        isFragmented_ = value;
        onChanged();
        return this;
      }
      public Builder clearIsFragmented() {
        bitField0_ = (bitField0_ & ~0x00000020);
        isFragmented_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.ObjectInfo)
    }

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

    // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.ObjectInfo)
  }

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

    // optional .org.eclipse.jgit.storage.dht.ChunkInfo.Source source = 1;
    boolean hasSource();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source getSource();

    // optional .org.eclipse.jgit.storage.dht.ChunkInfo.ObjectType object_type = 2;
    boolean hasObjectType();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType getObjectType();

    // optional bool is_fragment = 3;
    boolean hasIsFragment();
    boolean getIsFragment();

    // optional string cached_pack_key = 4;
    boolean hasCachedPackKey();
    String getCachedPackKey();

    // optional .org.eclipse.jgit.storage.dht.ChunkInfo.ObjectCounts object_counts = 5;
    boolean hasObjectCounts();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts getObjectCounts();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCountsOrBuilder getObjectCountsOrBuilder();

    // optional int32 chunk_size = 6;
    boolean hasChunkSize();
    int getChunkSize();

    // optional int32 index_size = 7;
    boolean hasIndexSize();
    int getIndexSize();

    // optional int32 meta_size = 8;
    boolean hasMetaSize();
    int getMetaSize();
  }
  public static final class ChunkInfo extends
      com.google.protobuf.GeneratedMessage
      implements ChunkInfoOrBuilder {
    // Use ChunkInfo.newBuilder() to construct.
    private ChunkInfo(Builder builder) {
      super(builder);
    }
    private ChunkInfo(boolean noInit) {}

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

    public ChunkInfo getDefaultInstanceForType() {
      return defaultInstance;
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_fieldAccessorTable;
    }

    public enum Source
        implements com.google.protobuf.ProtocolMessageEnum {
      RECEIVE(0, 1),
      INSERT(1, 2),
      REPACK(2, 3),
      ;

      public static final int RECEIVE_VALUE = 1;
      public static final int INSERT_VALUE = 2;
      public static final int REPACK_VALUE = 3;


      public final int getNumber() { return value; }

      public static Source valueOf(int value) {
        switch (value) {
          case 1: return RECEIVE;
          case 2: return INSERT;
          case 3: return REPACK;
          default: return null;
        }
      }

      public static com.google.protobuf.Internal.EnumLiteMap<Source>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static com.google.protobuf.Internal.EnumLiteMap<Source>
          internalValueMap =
            new com.google.protobuf.Internal.EnumLiteMap<Source>() {
              public Source findValueByNumber(int number) {
                return Source.valueOf(number);
              }
            };

      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(index);
      }
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.getDescriptor().getEnumTypes().get(0);
      }

      private static final Source[] VALUES = {
        RECEIVE, INSERT, REPACK,
      };

      public static Source valueOf(
          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        return VALUES[desc.getIndex()];
      }

      private final int index;
      private final int value;

      private Source(int index, int value) {
        this.index = index;
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:org.eclipse.jgit.storage.dht.ChunkInfo.Source)
    }

    public enum ObjectType
        implements com.google.protobuf.ProtocolMessageEnum {
      MIXED(0, 0),
      COMMIT(1, 1),
      TREE(2, 2),
      BLOB(3, 3),
      TAG(4, 4),
      ;

      public static final int MIXED_VALUE = 0;
      public static final int COMMIT_VALUE = 1;
      public static final int TREE_VALUE = 2;
      public static final int BLOB_VALUE = 3;
      public static final int TAG_VALUE = 4;


      public final int getNumber() { return value; }

      public static ObjectType valueOf(int value) {
        switch (value) {
          case 0: return MIXED;
          case 1: return COMMIT;
          case 2: return TREE;
          case 3: return BLOB;
          case 4: return TAG;
          default: return null;
        }
      }

      public static com.google.protobuf.Internal.EnumLiteMap<ObjectType>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static com.google.protobuf.Internal.EnumLiteMap<ObjectType>
          internalValueMap =
            new com.google.protobuf.Internal.EnumLiteMap<ObjectType>() {
              public ObjectType findValueByNumber(int number) {
                return ObjectType.valueOf(number);
              }
            };

      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(index);
      }
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.getDescriptor().getEnumTypes().get(1);
      }

      private static final ObjectType[] VALUES = {
        MIXED, COMMIT, TREE, BLOB, TAG,
      };

      public static ObjectType valueOf(
          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        return VALUES[desc.getIndex()];
      }

      private final int index;
      private final int value;

      private ObjectType(int index, int value) {
        this.index = index;
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:org.eclipse.jgit.storage.dht.ChunkInfo.ObjectType)
    }

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

      // optional int32 total = 1;
      boolean hasTotal();
      int getTotal();

      // optional int32 whole = 2;
      boolean hasWhole();
      int getWhole();

      // optional int32 ofs_delta = 3;
      boolean hasOfsDelta();
      int getOfsDelta();

      // optional int32 ref_delta = 4;
      boolean hasRefDelta();
      int getRefDelta();
    }
    public static final class ObjectCounts extends
        com.google.protobuf.GeneratedMessage
        implements ObjectCountsOrBuilder {
      // Use ObjectCounts.newBuilder() to construct.
      private ObjectCounts(Builder builder) {
        super(builder);
      }
      private ObjectCounts(boolean noInit) {}

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

      public ObjectCounts getDefaultInstanceForType() {
        return defaultInstance;
      }

      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_ObjectCounts_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_ObjectCounts_fieldAccessorTable;
      }

      private int bitField0_;
      // optional int32 total = 1;
      public static final int TOTAL_FIELD_NUMBER = 1;
      private int total_;
      public boolean hasTotal() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      public int getTotal() {
        return total_;
      }

      // optional int32 whole = 2;
      public static final int WHOLE_FIELD_NUMBER = 2;
      private int whole_;
      public boolean hasWhole() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      public int getWhole() {
        return whole_;
      }

      // optional int32 ofs_delta = 3;
      public static final int OFS_DELTA_FIELD_NUMBER = 3;
      private int ofsDelta_;
      public boolean hasOfsDelta() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      public int getOfsDelta() {
        return ofsDelta_;
      }

      // optional int32 ref_delta = 4;
      public static final int REF_DELTA_FIELD_NUMBER = 4;
      private int refDelta_;
      public boolean hasRefDelta() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      public int getRefDelta() {
        return refDelta_;
      }

      private void initFields() {
        total_ = 0;
        whole_ = 0;
        ofsDelta_ = 0;
        refDelta_ = 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.writeInt32(1, total_);
        }
        if (((bitField0_ & 0x00000002) == 0x00000002)) {
          output.writeInt32(2, whole_);
        }
        if (((bitField0_ & 0x00000004) == 0x00000004)) {
          output.writeInt32(3, ofsDelta_);
        }
        if (((bitField0_ & 0x00000008) == 0x00000008)) {
          output.writeInt32(4, refDelta_);
        }
        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, total_);
        }
        if (((bitField0_ & 0x00000002) == 0x00000002)) {
          size += com.google.protobuf.CodedOutputStream
            .computeInt32Size(2, whole_);
        }
        if (((bitField0_ & 0x00000004) == 0x00000004)) {
          size += com.google.protobuf.CodedOutputStream
            .computeInt32Size(3, ofsDelta_);
        }
        if (((bitField0_ & 0x00000008) == 0x00000008)) {
          size += com.google.protobuf.CodedOutputStream
            .computeInt32Size(4, refDelta_);
        }
        size += getUnknownFields().getSerializedSize();
        memoizedSerializedSize = size;
        return size;
      }

      @java.lang.Override
      protected Object writeReplace() throws java.io.ObjectStreamException {
        return super.writeReplace();
      }

      @java.lang.Override
      public boolean equals(final Object obj) {
        if (obj == this) {
         return true;
        }
        if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts)) {
          return super.equals(obj);
        }
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts) obj;

        boolean result = true;
        result = result && (hasTotal() == other.hasTotal());
        if (hasTotal()) {
          result = result && (getTotal()
              == other.getTotal());
        }
        result = result && (hasWhole() == other.hasWhole());
        if (hasWhole()) {
          result = result && (getWhole()
              == other.getWhole());
        }
        result = result && (hasOfsDelta() == other.hasOfsDelta());
        if (hasOfsDelta()) {
          result = result && (getOfsDelta()
              == other.getOfsDelta());
        }
        result = result && (hasRefDelta() == other.hasRefDelta());
        if (hasRefDelta()) {
          result = result && (getRefDelta()
              == other.getRefDelta());
        }
        result = result &&
            getUnknownFields().equals(other.getUnknownFields());
        return result;
      }

      @java.lang.Override
      public int hashCode() {
        int hash = 41;
        hash = (19 * hash) + getDescriptorForType().hashCode();
        if (hasTotal()) {
          hash = (37 * hash) + TOTAL_FIELD_NUMBER;
          hash = (53 * hash) + getTotal();
        }
        if (hasWhole()) {
          hash = (37 * hash) + WHOLE_FIELD_NUMBER;
          hash = (53 * hash) + getWhole();
        }
        if (hasOfsDelta()) {
          hash = (37 * hash) + OFS_DELTA_FIELD_NUMBER;
          hash = (53 * hash) + getOfsDelta();
        }
        if (hasRefDelta()) {
          hash = (37 * hash) + REF_DELTA_FIELD_NUMBER;
          hash = (53 * hash) + getRefDelta();
        }
        hash = (29 * hash) + getUnknownFields().hashCode();
        return hash;
      }

      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts parseFrom(
          com.google.protobuf.ByteString data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts parseFrom(
          com.google.protobuf.ByteString data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts parseFrom(byte[] data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts parseFrom(
          byte[] data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts parseFrom(java.io.InputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts parseFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts parseDelimitedFrom(java.io.InputStream input)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts parseDelimitedFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts parseFrom(
          com.google.protobuf.CodedInputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts parseFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }

      public static Builder newBuilder() { return Builder.create(); }
      public Builder newBuilderForType() { return newBuilder(); }
      public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts 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;
      }
      public static final class Builder extends
          com.google.protobuf.GeneratedMessage.Builder<Builder>
         implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCountsOrBuilder {
        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_ObjectCounts_descriptor;
        }

        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_ObjectCounts_fieldAccessorTable;
        }

        // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.newBuilder()
        private Builder() {
          maybeForceBuilderInitialization();
        }

        private Builder(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();
          total_ = 0;
          bitField0_ = (bitField0_ & ~0x00000001);
          whole_ = 0;
          bitField0_ = (bitField0_ & ~0x00000002);
          ofsDelta_ = 0;
          bitField0_ = (bitField0_ & ~0x00000004);
          refDelta_ = 0;
          bitField0_ = (bitField0_ & ~0x00000008);
          return this;
        }

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

        public com.google.protobuf.Descriptors.Descriptor
            getDescriptorForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.getDescriptor();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts getDefaultInstanceForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.getDefaultInstance();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts build() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(result);
          }
          return result;
        }

        private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts buildParsed()
            throws com.google.protobuf.InvalidProtocolBufferException {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(
              result).asInvalidProtocolBufferException();
          }
          return result;
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts buildPartial() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts(this);
          int from_bitField0_ = bitField0_;
          int to_bitField0_ = 0;
          if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
            to_bitField0_ |= 0x00000001;
          }
          result.total_ = total_;
          if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
            to_bitField0_ |= 0x00000002;
          }
          result.whole_ = whole_;
          if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
            to_bitField0_ |= 0x00000004;
          }
          result.ofsDelta_ = ofsDelta_;
          if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
            to_bitField0_ |= 0x00000008;
          }
          result.refDelta_ = refDelta_;
          result.bitField0_ = to_bitField0_;
          onBuilt();
          return result;
        }

        public Builder mergeFrom(com.google.protobuf.Message other) {
          if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts) {
            return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts)other);
          } else {
            super.mergeFrom(other);
            return this;
          }
        }

        public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts other) {
          if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.getDefaultInstance()) return this;
          if (other.hasTotal()) {
            setTotal(other.getTotal());
          }
          if (other.hasWhole()) {
            setWhole(other.getWhole());
          }
          if (other.hasOfsDelta()) {
            setOfsDelta(other.getOfsDelta());
          }
          if (other.hasRefDelta()) {
            setRefDelta(other.getRefDelta());
          }
          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 {
          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
            com.google.protobuf.UnknownFieldSet.newBuilder(
              this.getUnknownFields());
          while (true) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              default: {
                if (!parseUnknownField(input, unknownFields,
                                       extensionRegistry, tag)) {
                  this.setUnknownFields(unknownFields.build());
                  onChanged();
                  return this;
                }
                break;
              }
              case 8: {
                bitField0_ |= 0x00000001;
                total_ = input.readInt32();
                break;
              }
              case 16: {
                bitField0_ |= 0x00000002;
                whole_ = input.readInt32();
                break;
              }
              case 24: {
                bitField0_ |= 0x00000004;
                ofsDelta_ = input.readInt32();
                break;
              }
              case 32: {
                bitField0_ |= 0x00000008;
                refDelta_ = input.readInt32();
                break;
              }
            }
          }
        }

        private int bitField0_;

        // optional int32 total = 1;
        private int total_ ;
        public boolean hasTotal() {
          return ((bitField0_ & 0x00000001) == 0x00000001);
        }
        public int getTotal() {
          return total_;
        }
        public Builder setTotal(int value) {
          bitField0_ |= 0x00000001;
          total_ = value;
          onChanged();
          return this;
        }
        public Builder clearTotal() {
          bitField0_ = (bitField0_ & ~0x00000001);
          total_ = 0;
          onChanged();
          return this;
        }

        // optional int32 whole = 2;
        private int whole_ ;
        public boolean hasWhole() {
          return ((bitField0_ & 0x00000002) == 0x00000002);
        }
        public int getWhole() {
          return whole_;
        }
        public Builder setWhole(int value) {
          bitField0_ |= 0x00000002;
          whole_ = value;
          onChanged();
          return this;
        }
        public Builder clearWhole() {
          bitField0_ = (bitField0_ & ~0x00000002);
          whole_ = 0;
          onChanged();
          return this;
        }

        // optional int32 ofs_delta = 3;
        private int ofsDelta_ ;
        public boolean hasOfsDelta() {
          return ((bitField0_ & 0x00000004) == 0x00000004);
        }
        public int getOfsDelta() {
          return ofsDelta_;
        }
        public Builder setOfsDelta(int value) {
          bitField0_ |= 0x00000004;
          ofsDelta_ = value;
          onChanged();
          return this;
        }
        public Builder clearOfsDelta() {
          bitField0_ = (bitField0_ & ~0x00000004);
          ofsDelta_ = 0;
          onChanged();
          return this;
        }

        // optional int32 ref_delta = 4;
        private int refDelta_ ;
        public boolean hasRefDelta() {
          return ((bitField0_ & 0x00000008) == 0x00000008);
        }
        public int getRefDelta() {
          return refDelta_;
        }
        public Builder setRefDelta(int value) {
          bitField0_ |= 0x00000008;
          refDelta_ = value;
          onChanged();
          return this;
        }
        public Builder clearRefDelta() {
          bitField0_ = (bitField0_ & ~0x00000008);
          refDelta_ = 0;
          onChanged();
          return this;
        }

        // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.ChunkInfo.ObjectCounts)
      }

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

      // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.ChunkInfo.ObjectCounts)
    }

    private int bitField0_;
    // optional .org.eclipse.jgit.storage.dht.ChunkInfo.Source source = 1;
    public static final int SOURCE_FIELD_NUMBER = 1;
    private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source source_;
    public boolean hasSource() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source getSource() {
      return source_;
    }

    // optional .org.eclipse.jgit.storage.dht.ChunkInfo.ObjectType object_type = 2;
    public static final int OBJECT_TYPE_FIELD_NUMBER = 2;
    private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType objectType_;
    public boolean hasObjectType() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType getObjectType() {
      return objectType_;
    }

    // optional bool is_fragment = 3;
    public static final int IS_FRAGMENT_FIELD_NUMBER = 3;
    private boolean isFragment_;
    public boolean hasIsFragment() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    public boolean getIsFragment() {
      return isFragment_;
    }

    // optional string cached_pack_key = 4;
    public static final int CACHED_PACK_KEY_FIELD_NUMBER = 4;
    private Object cachedPackKey_;
    public boolean hasCachedPackKey() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    public String getCachedPackKey() {
      Object ref = cachedPackKey_;
      if (ref instanceof String) {
        return (String) ref;
      } else {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        String s = bs.toStringUtf8();
        if (com.google.protobuf.Internal.isValidUtf8(bs)) {
          cachedPackKey_ = s;
        }
        return s;
      }
    }
    private com.google.protobuf.ByteString getCachedPackKeyBytes() {
      Object ref = cachedPackKey_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8((String) ref);
        cachedPackKey_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // optional .org.eclipse.jgit.storage.dht.ChunkInfo.ObjectCounts object_counts = 5;
    public static final int OBJECT_COUNTS_FIELD_NUMBER = 5;
    private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts objectCounts_;
    public boolean hasObjectCounts() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts getObjectCounts() {
      return objectCounts_;
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCountsOrBuilder getObjectCountsOrBuilder() {
      return objectCounts_;
    }

    // optional int32 chunk_size = 6;
    public static final int CHUNK_SIZE_FIELD_NUMBER = 6;
    private int chunkSize_;
    public boolean hasChunkSize() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    public int getChunkSize() {
      return chunkSize_;
    }

    // optional int32 index_size = 7;
    public static final int INDEX_SIZE_FIELD_NUMBER = 7;
    private int indexSize_;
    public boolean hasIndexSize() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    public int getIndexSize() {
      return indexSize_;
    }

    // optional int32 meta_size = 8;
    public static final int META_SIZE_FIELD_NUMBER = 8;
    private int metaSize_;
    public boolean hasMetaSize() {
      return ((bitField0_ & 0x00000080) == 0x00000080);
    }
    public int getMetaSize() {
      return metaSize_;
    }

    private void initFields() {
      source_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source.RECEIVE;
      objectType_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType.MIXED;
      isFragment_ = false;
      cachedPackKey_ = "";
      objectCounts_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.getDefaultInstance();
      chunkSize_ = 0;
      indexSize_ = 0;
      metaSize_ = 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.writeEnum(1, source_.getNumber());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeEnum(2, objectType_.getNumber());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, isFragment_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBytes(4, getCachedPackKeyBytes());
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeMessage(5, objectCounts_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeInt32(6, chunkSize_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        output.writeInt32(7, indexSize_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        output.writeInt32(8, metaSize_);
      }
      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
          .computeEnumSize(1, source_.getNumber());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, objectType_.getNumber());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, isFragment_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(4, getCachedPackKeyBytes());
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, objectCounts_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(6, chunkSize_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(7, indexSize_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(8, metaSize_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    @java.lang.Override
    protected Object writeReplace() throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    @java.lang.Override
    public boolean equals(final Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo)) {
        return super.equals(obj);
      }
      org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo) obj;

      boolean result = true;
      result = result && (hasSource() == other.hasSource());
      if (hasSource()) {
        result = result &&
            (getSource() == other.getSource());
      }
      result = result && (hasObjectType() == other.hasObjectType());
      if (hasObjectType()) {
        result = result &&
            (getObjectType() == other.getObjectType());
      }
      result = result && (hasIsFragment() == other.hasIsFragment());
      if (hasIsFragment()) {
        result = result && (getIsFragment()
            == other.getIsFragment());
      }
      result = result && (hasCachedPackKey() == other.hasCachedPackKey());
      if (hasCachedPackKey()) {
        result = result && getCachedPackKey()
            .equals(other.getCachedPackKey());
      }
      result = result && (hasObjectCounts() == other.hasObjectCounts());
      if (hasObjectCounts()) {
        result = result && getObjectCounts()
            .equals(other.getObjectCounts());
      }
      result = result && (hasChunkSize() == other.hasChunkSize());
      if (hasChunkSize()) {
        result = result && (getChunkSize()
            == other.getChunkSize());
      }
      result = result && (hasIndexSize() == other.hasIndexSize());
      if (hasIndexSize()) {
        result = result && (getIndexSize()
            == other.getIndexSize());
      }
      result = result && (hasMetaSize() == other.hasMetaSize());
      if (hasMetaSize()) {
        result = result && (getMetaSize()
            == other.getMetaSize());
      }
      result = result &&
          getUnknownFields().equals(other.getUnknownFields());
      return result;
    }

    @java.lang.Override
    public int hashCode() {
      int hash = 41;
      hash = (19 * hash) + getDescriptorForType().hashCode();
      if (hasSource()) {
        hash = (37 * hash) + SOURCE_FIELD_NUMBER;
        hash = (53 * hash) + hashEnum(getSource());
      }
      if (hasObjectType()) {
        hash = (37 * hash) + OBJECT_TYPE_FIELD_NUMBER;
        hash = (53 * hash) + hashEnum(getObjectType());
      }
      if (hasIsFragment()) {
        hash = (37 * hash) + IS_FRAGMENT_FIELD_NUMBER;
        hash = (53 * hash) + hashBoolean(getIsFragment());
      }
      if (hasCachedPackKey()) {
        hash = (37 * hash) + CACHED_PACK_KEY_FIELD_NUMBER;
        hash = (53 * hash) + getCachedPackKey().hashCode();
      }
      if (hasObjectCounts()) {
        hash = (37 * hash) + OBJECT_COUNTS_FIELD_NUMBER;
        hash = (53 * hash) + getObjectCounts().hashCode();
      }
      if (hasChunkSize()) {
        hash = (37 * hash) + CHUNK_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + getChunkSize();
      }
      if (hasIndexSize()) {
        hash = (37 * hash) + INDEX_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + getIndexSize();
      }
      if (hasMetaSize()) {
        hash = (37 * hash) + META_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + getMetaSize();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      return hash;
    }

    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo 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;
    }
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfoOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_fieldAccessorTable;
      }

      // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

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

      public Builder clear() {
        super.clear();
        source_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source.RECEIVE;
        bitField0_ = (bitField0_ & ~0x00000001);
        objectType_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType.MIXED;
        bitField0_ = (bitField0_ & ~0x00000002);
        isFragment_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        cachedPackKey_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        if (objectCountsBuilder_ == null) {
          objectCounts_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.getDefaultInstance();
        } else {
          objectCountsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        chunkSize_ = 0;
        bitField0_ = (bitField0_ & ~0x00000020);
        indexSize_ = 0;
        bitField0_ = (bitField0_ & ~0x00000040);
        metaSize_ = 0;
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }

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

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.getDescriptor();
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo getDefaultInstanceForType() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.getDefaultInstance();
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo build() {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo buildParsed()
          throws com.google.protobuf.InvalidProtocolBufferException {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(
            result).asInvalidProtocolBufferException();
        }
        return result;
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo buildPartial() {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.source_ = source_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.objectType_ = objectType_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.isFragment_ = isFragment_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.cachedPackKey_ = cachedPackKey_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        if (objectCountsBuilder_ == null) {
          result.objectCounts_ = objectCounts_;
        } else {
          result.objectCounts_ = objectCountsBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.chunkSize_ = chunkSize_;
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000040;
        }
        result.indexSize_ = indexSize_;
        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
          to_bitField0_ |= 0x00000080;
        }
        result.metaSize_ = metaSize_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo) {
          return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo other) {
        if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.getDefaultInstance()) return this;
        if (other.hasSource()) {
          setSource(other.getSource());
        }
        if (other.hasObjectType()) {
          setObjectType(other.getObjectType());
        }
        if (other.hasIsFragment()) {
          setIsFragment(other.getIsFragment());
        }
        if (other.hasCachedPackKey()) {
          setCachedPackKey(other.getCachedPackKey());
        }
        if (other.hasObjectCounts()) {
          mergeObjectCounts(other.getObjectCounts());
        }
        if (other.hasChunkSize()) {
          setChunkSize(other.getChunkSize());
        }
        if (other.hasIndexSize()) {
          setIndexSize(other.getIndexSize());
        }
        if (other.hasMetaSize()) {
          setMetaSize(other.getMetaSize());
        }
        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 {
        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder(
            this.getUnknownFields());
        while (true) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              this.setUnknownFields(unknownFields.build());
              onChanged();
              return this;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              }
              break;
            }
            case 8: {
              int rawValue = input.readEnum();
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source value = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(1, rawValue);
              } else {
                bitField0_ |= 0x00000001;
                source_ = value;
              }
              break;
            }
            case 16: {
              int rawValue = input.readEnum();
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType value = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(2, rawValue);
              } else {
                bitField0_ |= 0x00000002;
                objectType_ = value;
              }
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              isFragment_ = input.readBool();
              break;
            }
            case 34: {
              bitField0_ |= 0x00000008;
              cachedPackKey_ = input.readBytes();
              break;
            }
            case 42: {
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.Builder subBuilder = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.newBuilder();
              if (hasObjectCounts()) {
                subBuilder.mergeFrom(getObjectCounts());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setObjectCounts(subBuilder.buildPartial());
              break;
            }
            case 48: {
              bitField0_ |= 0x00000020;
              chunkSize_ = input.readInt32();
              break;
            }
            case 56: {
              bitField0_ |= 0x00000040;
              indexSize_ = input.readInt32();
              break;
            }
            case 64: {
              bitField0_ |= 0x00000080;
              metaSize_ = input.readInt32();
              break;
            }
          }
        }
      }

      private int bitField0_;

      // optional .org.eclipse.jgit.storage.dht.ChunkInfo.Source source = 1;
      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source source_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source.RECEIVE;
      public boolean hasSource() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source getSource() {
        return source_;
      }
      public Builder setSource(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        source_ = value;
        onChanged();
        return this;
      }
      public Builder clearSource() {
        bitField0_ = (bitField0_ & ~0x00000001);
        source_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Source.RECEIVE;
        onChanged();
        return this;
      }

      // optional .org.eclipse.jgit.storage.dht.ChunkInfo.ObjectType object_type = 2;
      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType objectType_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType.MIXED;
      public boolean hasObjectType() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType getObjectType() {
        return objectType_;
      }
      public Builder setObjectType(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        objectType_ = value;
        onChanged();
        return this;
      }
      public Builder clearObjectType() {
        bitField0_ = (bitField0_ & ~0x00000002);
        objectType_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectType.MIXED;
        onChanged();
        return this;
      }

      // optional bool is_fragment = 3;
      private boolean isFragment_ ;
      public boolean hasIsFragment() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      public boolean getIsFragment() {
        return isFragment_;
      }
      public Builder setIsFragment(boolean value) {
        bitField0_ |= 0x00000004;
        isFragment_ = value;
        onChanged();
        return this;
      }
      public Builder clearIsFragment() {
        bitField0_ = (bitField0_ & ~0x00000004);
        isFragment_ = false;
        onChanged();
        return this;
      }

      // optional string cached_pack_key = 4;
      private Object cachedPackKey_ = "";
      public boolean hasCachedPackKey() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      public String getCachedPackKey() {
        Object ref = cachedPackKey_;
        if (!(ref instanceof String)) {
          String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
          cachedPackKey_ = s;
          return s;
        } else {
          return (String) ref;
        }
      }
      public Builder setCachedPackKey(String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        cachedPackKey_ = value;
        onChanged();
        return this;
      }
      public Builder clearCachedPackKey() {
        bitField0_ = (bitField0_ & ~0x00000008);
        cachedPackKey_ = getDefaultInstance().getCachedPackKey();
        onChanged();
        return this;
      }
      void setCachedPackKey(com.google.protobuf.ByteString value) {
        bitField0_ |= 0x00000008;
        cachedPackKey_ = value;
        onChanged();
      }

      // optional .org.eclipse.jgit.storage.dht.ChunkInfo.ObjectCounts object_counts = 5;
      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts objectCounts_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCountsOrBuilder> objectCountsBuilder_;
      public boolean hasObjectCounts() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts getObjectCounts() {
        if (objectCountsBuilder_ == null) {
          return objectCounts_;
        } else {
          return objectCountsBuilder_.getMessage();
        }
      }
      public Builder setObjectCounts(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts value) {
        if (objectCountsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          objectCounts_ = value;
          onChanged();
        } else {
          objectCountsBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      public Builder setObjectCounts(
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.Builder builderForValue) {
        if (objectCountsBuilder_ == null) {
          objectCounts_ = builderForValue.build();
          onChanged();
        } else {
          objectCountsBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      public Builder mergeObjectCounts(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts value) {
        if (objectCountsBuilder_ == null) {
          if (((bitField0_ & 0x00000010) == 0x00000010) &&
              objectCounts_ != org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.getDefaultInstance()) {
            objectCounts_ =
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.newBuilder(objectCounts_).mergeFrom(value).buildPartial();
          } else {
            objectCounts_ = value;
          }
          onChanged();
        } else {
          objectCountsBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      public Builder clearObjectCounts() {
        if (objectCountsBuilder_ == null) {
          objectCounts_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.getDefaultInstance();
          onChanged();
        } else {
          objectCountsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.Builder getObjectCountsBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getObjectCountsFieldBuilder().getBuilder();
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCountsOrBuilder getObjectCountsOrBuilder() {
        if (objectCountsBuilder_ != null) {
          return objectCountsBuilder_.getMessageOrBuilder();
        } else {
          return objectCounts_;
        }
      }
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCountsOrBuilder>
          getObjectCountsFieldBuilder() {
        if (objectCountsBuilder_ == null) {
          objectCountsBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCountsOrBuilder>(
                  objectCounts_,
                  getParentForChildren(),
                  isClean());
          objectCounts_ = null;
        }
        return objectCountsBuilder_;
      }

      // optional int32 chunk_size = 6;
      private int chunkSize_ ;
      public boolean hasChunkSize() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      public int getChunkSize() {
        return chunkSize_;
      }
      public Builder setChunkSize(int value) {
        bitField0_ |= 0x00000020;
        chunkSize_ = value;
        onChanged();
        return this;
      }
      public Builder clearChunkSize() {
        bitField0_ = (bitField0_ & ~0x00000020);
        chunkSize_ = 0;
        onChanged();
        return this;
      }

      // optional int32 index_size = 7;
      private int indexSize_ ;
      public boolean hasIndexSize() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      public int getIndexSize() {
        return indexSize_;
      }
      public Builder setIndexSize(int value) {
        bitField0_ |= 0x00000040;
        indexSize_ = value;
        onChanged();
        return this;
      }
      public Builder clearIndexSize() {
        bitField0_ = (bitField0_ & ~0x00000040);
        indexSize_ = 0;
        onChanged();
        return this;
      }

      // optional int32 meta_size = 8;
      private int metaSize_ ;
      public boolean hasMetaSize() {
        return ((bitField0_ & 0x00000080) == 0x00000080);
      }
      public int getMetaSize() {
        return metaSize_;
      }
      public Builder setMetaSize(int value) {
        bitField0_ |= 0x00000080;
        metaSize_ = value;
        onChanged();
        return this;
      }
      public Builder clearMetaSize() {
        bitField0_ = (bitField0_ & ~0x00000080);
        metaSize_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.ChunkInfo)
    }

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

    // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.ChunkInfo)
  }

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

    // repeated .org.eclipse.jgit.storage.dht.ChunkMeta.BaseChunk base_chunk = 1;
    java.util.List<org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk>
        getBaseChunkList();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk getBaseChunk(int index);
    int getBaseChunkCount();
    java.util.List<? extends org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunkOrBuilder>
        getBaseChunkOrBuilderList();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunkOrBuilder getBaseChunkOrBuilder(
        int index);

    // repeated string fragment = 2;
    java.util.List<String> getFragmentList();
    int getFragmentCount();
    String getFragment(int index);

    // optional .org.eclipse.jgit.storage.dht.ChunkMeta.PrefetchHint commit_prefetch = 51;
    boolean hasCommitPrefetch();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint getCommitPrefetch();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder getCommitPrefetchOrBuilder();

    // optional .org.eclipse.jgit.storage.dht.ChunkMeta.PrefetchHint tree_prefetch = 52;
    boolean hasTreePrefetch();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint getTreePrefetch();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder getTreePrefetchOrBuilder();
  }
  public static final class ChunkMeta extends
      com.google.protobuf.GeneratedMessage
      implements ChunkMetaOrBuilder {
    // Use ChunkMeta.newBuilder() to construct.
    private ChunkMeta(Builder builder) {
      super(builder);
    }
    private ChunkMeta(boolean noInit) {}

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

    public ChunkMeta getDefaultInstanceForType() {
      return defaultInstance;
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_fieldAccessorTable;
    }

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

      // required int64 relative_start = 1;
      boolean hasRelativeStart();
      long getRelativeStart();

      // required string chunk_key = 2;
      boolean hasChunkKey();
      String getChunkKey();
    }
    public static final class BaseChunk extends
        com.google.protobuf.GeneratedMessage
        implements BaseChunkOrBuilder {
      // Use BaseChunk.newBuilder() to construct.
      private BaseChunk(Builder builder) {
        super(builder);
      }
      private BaseChunk(boolean noInit) {}

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

      public BaseChunk getDefaultInstanceForType() {
        return defaultInstance;
      }

      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_BaseChunk_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_BaseChunk_fieldAccessorTable;
      }

      private int bitField0_;
      // required int64 relative_start = 1;
      public static final int RELATIVE_START_FIELD_NUMBER = 1;
      private long relativeStart_;
      public boolean hasRelativeStart() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      public long getRelativeStart() {
        return relativeStart_;
      }

      // required string chunk_key = 2;
      public static final int CHUNK_KEY_FIELD_NUMBER = 2;
      private Object chunkKey_;
      public boolean hasChunkKey() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      public String getChunkKey() {
        Object ref = chunkKey_;
        if (ref instanceof String) {
          return (String) ref;
        } else {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          String s = bs.toStringUtf8();
          if (com.google.protobuf.Internal.isValidUtf8(bs)) {
            chunkKey_ = s;
          }
          return s;
        }
      }
      private com.google.protobuf.ByteString getChunkKeyBytes() {
        Object ref = chunkKey_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b =
              com.google.protobuf.ByteString.copyFromUtf8((String) ref);
          chunkKey_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }

      private void initFields() {
        relativeStart_ = 0L;
        chunkKey_ = "";
      }
      private byte memoizedIsInitialized = -1;
      public final boolean isInitialized() {
        byte isInitialized = memoizedIsInitialized;
        if (isInitialized != -1) return isInitialized == 1;

        if (!hasRelativeStart()) {
          memoizedIsInitialized = 0;
          return false;
        }
        if (!hasChunkKey()) {
          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, relativeStart_);
        }
        if (((bitField0_ & 0x00000002) == 0x00000002)) {
          output.writeBytes(2, getChunkKeyBytes());
        }
        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, relativeStart_);
        }
        if (((bitField0_ & 0x00000002) == 0x00000002)) {
          size += com.google.protobuf.CodedOutputStream
            .computeBytesSize(2, getChunkKeyBytes());
        }
        size += getUnknownFields().getSerializedSize();
        memoizedSerializedSize = size;
        return size;
      }

      @java.lang.Override
      protected Object writeReplace() throws java.io.ObjectStreamException {
        return super.writeReplace();
      }

      @java.lang.Override
      public boolean equals(final Object obj) {
        if (obj == this) {
         return true;
        }
        if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk)) {
          return super.equals(obj);
        }
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk) obj;

        boolean result = true;
        result = result && (hasRelativeStart() == other.hasRelativeStart());
        if (hasRelativeStart()) {
          result = result && (getRelativeStart()
              == other.getRelativeStart());
        }
        result = result && (hasChunkKey() == other.hasChunkKey());
        if (hasChunkKey()) {
          result = result && getChunkKey()
              .equals(other.getChunkKey());
        }
        result = result &&
            getUnknownFields().equals(other.getUnknownFields());
        return result;
      }

      @java.lang.Override
      public int hashCode() {
        int hash = 41;
        hash = (19 * hash) + getDescriptorForType().hashCode();
        if (hasRelativeStart()) {
          hash = (37 * hash) + RELATIVE_START_FIELD_NUMBER;
          hash = (53 * hash) + hashLong(getRelativeStart());
        }
        if (hasChunkKey()) {
          hash = (37 * hash) + CHUNK_KEY_FIELD_NUMBER;
          hash = (53 * hash) + getChunkKey().hashCode();
        }
        hash = (29 * hash) + getUnknownFields().hashCode();
        return hash;
      }

      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk parseFrom(
          com.google.protobuf.ByteString data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk parseFrom(
          com.google.protobuf.ByteString data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk parseFrom(byte[] data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk parseFrom(
          byte[] data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk parseFrom(java.io.InputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk parseFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk parseDelimitedFrom(java.io.InputStream input)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk parseDelimitedFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk parseFrom(
          com.google.protobuf.CodedInputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk parseFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }

      public static Builder newBuilder() { return Builder.create(); }
      public Builder newBuilderForType() { return newBuilder(); }
      public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk 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;
      }
      public static final class Builder extends
          com.google.protobuf.GeneratedMessage.Builder<Builder>
         implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunkOrBuilder {
        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_BaseChunk_descriptor;
        }

        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_BaseChunk_fieldAccessorTable;
        }

        // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.newBuilder()
        private Builder() {
          maybeForceBuilderInitialization();
        }

        private Builder(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();
          relativeStart_ = 0L;
          bitField0_ = (bitField0_ & ~0x00000001);
          chunkKey_ = "";
          bitField0_ = (bitField0_ & ~0x00000002);
          return this;
        }

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

        public com.google.protobuf.Descriptors.Descriptor
            getDescriptorForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.getDescriptor();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk getDefaultInstanceForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.getDefaultInstance();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk build() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(result);
          }
          return result;
        }

        private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk buildParsed()
            throws com.google.protobuf.InvalidProtocolBufferException {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(
              result).asInvalidProtocolBufferException();
          }
          return result;
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk buildPartial() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk(this);
          int from_bitField0_ = bitField0_;
          int to_bitField0_ = 0;
          if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
            to_bitField0_ |= 0x00000001;
          }
          result.relativeStart_ = relativeStart_;
          if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
            to_bitField0_ |= 0x00000002;
          }
          result.chunkKey_ = chunkKey_;
          result.bitField0_ = to_bitField0_;
          onBuilt();
          return result;
        }

        public Builder mergeFrom(com.google.protobuf.Message other) {
          if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk) {
            return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk)other);
          } else {
            super.mergeFrom(other);
            return this;
          }
        }

        public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk other) {
          if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.getDefaultInstance()) return this;
          if (other.hasRelativeStart()) {
            setRelativeStart(other.getRelativeStart());
          }
          if (other.hasChunkKey()) {
            setChunkKey(other.getChunkKey());
          }
          this.mergeUnknownFields(other.getUnknownFields());
          return this;
        }

        public final boolean isInitialized() {
          if (!hasRelativeStart()) {

            return false;
          }
          if (!hasChunkKey()) {

            return false;
          }
          return true;
        }

        public Builder mergeFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
            com.google.protobuf.UnknownFieldSet.newBuilder(
              this.getUnknownFields());
          while (true) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              default: {
                if (!parseUnknownField(input, unknownFields,
                                       extensionRegistry, tag)) {
                  this.setUnknownFields(unknownFields.build());
                  onChanged();
                  return this;
                }
                break;
              }
              case 8: {
                bitField0_ |= 0x00000001;
                relativeStart_ = input.readInt64();
                break;
              }
              case 18: {
                bitField0_ |= 0x00000002;
                chunkKey_ = input.readBytes();
                break;
              }
            }
          }
        }

        private int bitField0_;

        // required int64 relative_start = 1;
        private long relativeStart_ ;
        public boolean hasRelativeStart() {
          return ((bitField0_ & 0x00000001) == 0x00000001);
        }
        public long getRelativeStart() {
          return relativeStart_;
        }
        public Builder setRelativeStart(long value) {
          bitField0_ |= 0x00000001;
          relativeStart_ = value;
          onChanged();
          return this;
        }
        public Builder clearRelativeStart() {
          bitField0_ = (bitField0_ & ~0x00000001);
          relativeStart_ = 0L;
          onChanged();
          return this;
        }

        // required string chunk_key = 2;
        private Object chunkKey_ = "";
        public boolean hasChunkKey() {
          return ((bitField0_ & 0x00000002) == 0x00000002);
        }
        public String getChunkKey() {
          Object ref = chunkKey_;
          if (!(ref instanceof String)) {
            String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
            chunkKey_ = s;
            return s;
          } else {
            return (String) ref;
          }
        }
        public Builder setChunkKey(String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
          chunkKey_ = value;
          onChanged();
          return this;
        }
        public Builder clearChunkKey() {
          bitField0_ = (bitField0_ & ~0x00000002);
          chunkKey_ = getDefaultInstance().getChunkKey();
          onChanged();
          return this;
        }
        void setChunkKey(com.google.protobuf.ByteString value) {
          bitField0_ |= 0x00000002;
          chunkKey_ = value;
          onChanged();
        }

        // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.ChunkMeta.BaseChunk)
      }

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

      // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.ChunkMeta.BaseChunk)
    }

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

      // repeated string edge = 1;
      java.util.List<String> getEdgeList();
      int getEdgeCount();
      String getEdge(int index);

      // repeated string sequential = 2;
      java.util.List<String> getSequentialList();
      int getSequentialCount();
      String getSequential(int index);
    }
    public static final class PrefetchHint extends
        com.google.protobuf.GeneratedMessage
        implements PrefetchHintOrBuilder {
      // Use PrefetchHint.newBuilder() to construct.
      private PrefetchHint(Builder builder) {
        super(builder);
      }
      private PrefetchHint(boolean noInit) {}

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

      public PrefetchHint getDefaultInstanceForType() {
        return defaultInstance;
      }

      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_PrefetchHint_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_PrefetchHint_fieldAccessorTable;
      }

      // repeated string edge = 1;
      public static final int EDGE_FIELD_NUMBER = 1;
      private com.google.protobuf.LazyStringList edge_;
      public java.util.List<String>
          getEdgeList() {
        return edge_;
      }
      public int getEdgeCount() {
        return edge_.size();
      }
      public String getEdge(int index) {
        return edge_.get(index);
      }

      // repeated string sequential = 2;
      public static final int SEQUENTIAL_FIELD_NUMBER = 2;
      private com.google.protobuf.LazyStringList sequential_;
      public java.util.List<String>
          getSequentialList() {
        return sequential_;
      }
      public int getSequentialCount() {
        return sequential_.size();
      }
      public String getSequential(int index) {
        return sequential_.get(index);
      }

      private void initFields() {
        edge_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        sequential_ = com.google.protobuf.LazyStringArrayList.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 < edge_.size(); i++) {
          output.writeBytes(1, edge_.getByteString(i));
        }
        for (int i = 0; i < sequential_.size(); i++) {
          output.writeBytes(2, sequential_.getByteString(i));
        }
        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 < edge_.size(); i++) {
            dataSize += com.google.protobuf.CodedOutputStream
              .computeBytesSizeNoTag(edge_.getByteString(i));
          }
          size += dataSize;
          size += 1 * getEdgeList().size();
        }
        {
          int dataSize = 0;
          for (int i = 0; i < sequential_.size(); i++) {
            dataSize += com.google.protobuf.CodedOutputStream
              .computeBytesSizeNoTag(sequential_.getByteString(i));
          }
          size += dataSize;
          size += 1 * getSequentialList().size();
        }
        size += getUnknownFields().getSerializedSize();
        memoizedSerializedSize = size;
        return size;
      }

      @java.lang.Override
      protected Object writeReplace() throws java.io.ObjectStreamException {
        return super.writeReplace();
      }

      @java.lang.Override
      public boolean equals(final Object obj) {
        if (obj == this) {
         return true;
        }
        if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint)) {
          return super.equals(obj);
        }
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint) obj;

        boolean result = true;
        result = result && getEdgeList()
            .equals(other.getEdgeList());
        result = result && getSequentialList()
            .equals(other.getSequentialList());
        result = result &&
            getUnknownFields().equals(other.getUnknownFields());
        return result;
      }

      @java.lang.Override
      public int hashCode() {
        int hash = 41;
        hash = (19 * hash) + getDescriptorForType().hashCode();
        if (getEdgeCount() > 0) {
          hash = (37 * hash) + EDGE_FIELD_NUMBER;
          hash = (53 * hash) + getEdgeList().hashCode();
        }
        if (getSequentialCount() > 0) {
          hash = (37 * hash) + SEQUENTIAL_FIELD_NUMBER;
          hash = (53 * hash) + getSequentialList().hashCode();
        }
        hash = (29 * hash) + getUnknownFields().hashCode();
        return hash;
      }

      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint parseFrom(
          com.google.protobuf.ByteString data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint parseFrom(
          com.google.protobuf.ByteString data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint parseFrom(byte[] data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint parseFrom(
          byte[] data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint parseFrom(java.io.InputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint parseFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint parseDelimitedFrom(java.io.InputStream input)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint parseDelimitedFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint parseFrom(
          com.google.protobuf.CodedInputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint parseFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }

      public static Builder newBuilder() { return Builder.create(); }
      public Builder newBuilderForType() { return newBuilder(); }
      public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint 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;
      }
      public static final class Builder extends
          com.google.protobuf.GeneratedMessage.Builder<Builder>
         implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder {
        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_PrefetchHint_descriptor;
        }

        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_PrefetchHint_fieldAccessorTable;
        }

        // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.newBuilder()
        private Builder() {
          maybeForceBuilderInitialization();
        }

        private Builder(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();
          edge_ = com.google.protobuf.LazyStringArrayList.EMPTY;
          bitField0_ = (bitField0_ & ~0x00000001);
          sequential_ = com.google.protobuf.LazyStringArrayList.EMPTY;
          bitField0_ = (bitField0_ & ~0x00000002);
          return this;
        }

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

        public com.google.protobuf.Descriptors.Descriptor
            getDescriptorForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDescriptor();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint getDefaultInstanceForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint build() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(result);
          }
          return result;
        }

        private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint buildParsed()
            throws com.google.protobuf.InvalidProtocolBufferException {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(
              result).asInvalidProtocolBufferException();
          }
          return result;
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint buildPartial() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint(this);
          int from_bitField0_ = bitField0_;
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            edge_ = new com.google.protobuf.UnmodifiableLazyStringList(
                edge_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.edge_ = edge_;
          if (((bitField0_ & 0x00000002) == 0x00000002)) {
            sequential_ = new com.google.protobuf.UnmodifiableLazyStringList(
                sequential_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.sequential_ = sequential_;
          onBuilt();
          return result;
        }

        public Builder mergeFrom(com.google.protobuf.Message other) {
          if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint) {
            return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint)other);
          } else {
            super.mergeFrom(other);
            return this;
          }
        }

        public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint other) {
          if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance()) return this;
          if (!other.edge_.isEmpty()) {
            if (edge_.isEmpty()) {
              edge_ = other.edge_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureEdgeIsMutable();
              edge_.addAll(other.edge_);
            }
            onChanged();
          }
          if (!other.sequential_.isEmpty()) {
            if (sequential_.isEmpty()) {
              sequential_ = other.sequential_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureSequentialIsMutable();
              sequential_.addAll(other.sequential_);
            }
            onChanged();
          }
          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 {
          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
            com.google.protobuf.UnknownFieldSet.newBuilder(
              this.getUnknownFields());
          while (true) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              default: {
                if (!parseUnknownField(input, unknownFields,
                                       extensionRegistry, tag)) {
                  this.setUnknownFields(unknownFields.build());
                  onChanged();
                  return this;
                }
                break;
              }
              case 10: {
                ensureEdgeIsMutable();
                edge_.add(input.readBytes());
                break;
              }
              case 18: {
                ensureSequentialIsMutable();
                sequential_.add(input.readBytes());
                break;
              }
            }
          }
        }

        private int bitField0_;

        // repeated string edge = 1;
        private com.google.protobuf.LazyStringList edge_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        private void ensureEdgeIsMutable() {
          if (!((bitField0_ & 0x00000001) == 0x00000001)) {
            edge_ = new com.google.protobuf.LazyStringArrayList(edge_);
            bitField0_ |= 0x00000001;
           }
        }
        public java.util.List<String>
            getEdgeList() {
          return java.util.Collections.unmodifiableList(edge_);
        }
        public int getEdgeCount() {
          return edge_.size();
        }
        public String getEdge(int index) {
          return edge_.get(index);
        }
        public Builder setEdge(
            int index, String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureEdgeIsMutable();
          edge_.set(index, value);
          onChanged();
          return this;
        }
        public Builder addEdge(String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureEdgeIsMutable();
          edge_.add(value);
          onChanged();
          return this;
        }
        public Builder addAllEdge(
            java.lang.Iterable<String> values) {
          ensureEdgeIsMutable();
          super.addAll(values, edge_);
          onChanged();
          return this;
        }
        public Builder clearEdge() {
          edge_ = com.google.protobuf.LazyStringArrayList.EMPTY;
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
          return this;
        }
        void addEdge(com.google.protobuf.ByteString value) {
          ensureEdgeIsMutable();
          edge_.add(value);
          onChanged();
        }

        // repeated string sequential = 2;
        private com.google.protobuf.LazyStringList sequential_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        private void ensureSequentialIsMutable() {
          if (!((bitField0_ & 0x00000002) == 0x00000002)) {
            sequential_ = new com.google.protobuf.LazyStringArrayList(sequential_);
            bitField0_ |= 0x00000002;
           }
        }
        public java.util.List<String>
            getSequentialList() {
          return java.util.Collections.unmodifiableList(sequential_);
        }
        public int getSequentialCount() {
          return sequential_.size();
        }
        public String getSequential(int index) {
          return sequential_.get(index);
        }
        public Builder setSequential(
            int index, String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureSequentialIsMutable();
          sequential_.set(index, value);
          onChanged();
          return this;
        }
        public Builder addSequential(String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureSequentialIsMutable();
          sequential_.add(value);
          onChanged();
          return this;
        }
        public Builder addAllSequential(
            java.lang.Iterable<String> values) {
          ensureSequentialIsMutable();
          super.addAll(values, sequential_);
          onChanged();
          return this;
        }
        public Builder clearSequential() {
          sequential_ = com.google.protobuf.LazyStringArrayList.EMPTY;
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
          return this;
        }
        void addSequential(com.google.protobuf.ByteString value) {
          ensureSequentialIsMutable();
          sequential_.add(value);
          onChanged();
        }

        // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.ChunkMeta.PrefetchHint)
      }

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

      // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.ChunkMeta.PrefetchHint)
    }

    private int bitField0_;
    // repeated .org.eclipse.jgit.storage.dht.ChunkMeta.BaseChunk base_chunk = 1;
    public static final int BASE_CHUNK_FIELD_NUMBER = 1;
    private java.util.List<org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk> baseChunk_;
    public java.util.List<org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk> getBaseChunkList() {
      return baseChunk_;
    }
    public java.util.List<? extends org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunkOrBuilder>
        getBaseChunkOrBuilderList() {
      return baseChunk_;
    }
    public int getBaseChunkCount() {
      return baseChunk_.size();
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk getBaseChunk(int index) {
      return baseChunk_.get(index);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunkOrBuilder getBaseChunkOrBuilder(
        int index) {
      return baseChunk_.get(index);
    }

    // repeated string fragment = 2;
    public static final int FRAGMENT_FIELD_NUMBER = 2;
    private com.google.protobuf.LazyStringList fragment_;
    public java.util.List<String>
        getFragmentList() {
      return fragment_;
    }
    public int getFragmentCount() {
      return fragment_.size();
    }
    public String getFragment(int index) {
      return fragment_.get(index);
    }

    // optional .org.eclipse.jgit.storage.dht.ChunkMeta.PrefetchHint commit_prefetch = 51;
    public static final int COMMIT_PREFETCH_FIELD_NUMBER = 51;
    private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint commitPrefetch_;
    public boolean hasCommitPrefetch() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint getCommitPrefetch() {
      return commitPrefetch_;
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder getCommitPrefetchOrBuilder() {
      return commitPrefetch_;
    }

    // optional .org.eclipse.jgit.storage.dht.ChunkMeta.PrefetchHint tree_prefetch = 52;
    public static final int TREE_PREFETCH_FIELD_NUMBER = 52;
    private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint treePrefetch_;
    public boolean hasTreePrefetch() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint getTreePrefetch() {
      return treePrefetch_;
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder getTreePrefetchOrBuilder() {
      return treePrefetch_;
    }

    private void initFields() {
      baseChunk_ = java.util.Collections.emptyList();
      fragment_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      commitPrefetch_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance();
      treePrefetch_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      for (int i = 0; i < getBaseChunkCount(); i++) {
        if (!getBaseChunk(i).isInitialized()) {
          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 < baseChunk_.size(); i++) {
        output.writeMessage(1, baseChunk_.get(i));
      }
      for (int i = 0; i < fragment_.size(); i++) {
        output.writeBytes(2, fragment_.getByteString(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(51, commitPrefetch_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(52, treePrefetch_);
      }
      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 < baseChunk_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, baseChunk_.get(i));
      }
      {
        int dataSize = 0;
        for (int i = 0; i < fragment_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeBytesSizeNoTag(fragment_.getByteString(i));
        }
        size += dataSize;
        size += 1 * getFragmentList().size();
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(51, commitPrefetch_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(52, treePrefetch_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    @java.lang.Override
    protected Object writeReplace() throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    @java.lang.Override
    public boolean equals(final Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta)) {
        return super.equals(obj);
      }
      org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta) obj;

      boolean result = true;
      result = result && getBaseChunkList()
          .equals(other.getBaseChunkList());
      result = result && getFragmentList()
          .equals(other.getFragmentList());
      result = result && (hasCommitPrefetch() == other.hasCommitPrefetch());
      if (hasCommitPrefetch()) {
        result = result && getCommitPrefetch()
            .equals(other.getCommitPrefetch());
      }
      result = result && (hasTreePrefetch() == other.hasTreePrefetch());
      if (hasTreePrefetch()) {
        result = result && getTreePrefetch()
            .equals(other.getTreePrefetch());
      }
      result = result &&
          getUnknownFields().equals(other.getUnknownFields());
      return result;
    }

    @java.lang.Override
    public int hashCode() {
      int hash = 41;
      hash = (19 * hash) + getDescriptorForType().hashCode();
      if (getBaseChunkCount() > 0) {
        hash = (37 * hash) + BASE_CHUNK_FIELD_NUMBER;
        hash = (53 * hash) + getBaseChunkList().hashCode();
      }
      if (getFragmentCount() > 0) {
        hash = (37 * hash) + FRAGMENT_FIELD_NUMBER;
        hash = (53 * hash) + getFragmentList().hashCode();
      }
      if (hasCommitPrefetch()) {
        hash = (37 * hash) + COMMIT_PREFETCH_FIELD_NUMBER;
        hash = (53 * hash) + getCommitPrefetch().hashCode();
      }
      if (hasTreePrefetch()) {
        hash = (37 * hash) + TREE_PREFETCH_FIELD_NUMBER;
        hash = (53 * hash) + getTreePrefetch().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      return hash;
    }

    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta 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;
    }
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMetaOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_fieldAccessorTable;
      }

      // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

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

      public Builder clear() {
        super.clear();
        if (baseChunkBuilder_ == null) {
          baseChunk_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          baseChunkBuilder_.clear();
        }
        fragment_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000002);
        if (commitPrefetchBuilder_ == null) {
          commitPrefetch_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance();
        } else {
          commitPrefetchBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        if (treePrefetchBuilder_ == null) {
          treePrefetch_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance();
        } else {
          treePrefetchBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

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

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.getDescriptor();
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta getDefaultInstanceForType() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.getDefaultInstance();
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta build() {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta buildParsed()
          throws com.google.protobuf.InvalidProtocolBufferException {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(
            result).asInvalidProtocolBufferException();
        }
        return result;
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta buildPartial() {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (baseChunkBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            baseChunk_ = java.util.Collections.unmodifiableList(baseChunk_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.baseChunk_ = baseChunk_;
        } else {
          result.baseChunk_ = baseChunkBuilder_.build();
        }
        if (((bitField0_ & 0x00000002) == 0x00000002)) {
          fragment_ = new com.google.protobuf.UnmodifiableLazyStringList(
              fragment_);
          bitField0_ = (bitField0_ & ~0x00000002);
        }
        result.fragment_ = fragment_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000001;
        }
        if (commitPrefetchBuilder_ == null) {
          result.commitPrefetch_ = commitPrefetch_;
        } else {
          result.commitPrefetch_ = commitPrefetchBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000002;
        }
        if (treePrefetchBuilder_ == null) {
          result.treePrefetch_ = treePrefetch_;
        } else {
          result.treePrefetch_ = treePrefetchBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta) {
          return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta other) {
        if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.getDefaultInstance()) return this;
        if (baseChunkBuilder_ == null) {
          if (!other.baseChunk_.isEmpty()) {
            if (baseChunk_.isEmpty()) {
              baseChunk_ = other.baseChunk_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureBaseChunkIsMutable();
              baseChunk_.addAll(other.baseChunk_);
            }
            onChanged();
          }
        } else {
          if (!other.baseChunk_.isEmpty()) {
            if (baseChunkBuilder_.isEmpty()) {
              baseChunkBuilder_.dispose();
              baseChunkBuilder_ = null;
              baseChunk_ = other.baseChunk_;
              bitField0_ = (bitField0_ & ~0x00000001);
              baseChunkBuilder_ =
                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getBaseChunkFieldBuilder() : null;
            } else {
              baseChunkBuilder_.addAllMessages(other.baseChunk_);
            }
          }
        }
        if (!other.fragment_.isEmpty()) {
          if (fragment_.isEmpty()) {
            fragment_ = other.fragment_;
            bitField0_ = (bitField0_ & ~0x00000002);
          } else {
            ensureFragmentIsMutable();
            fragment_.addAll(other.fragment_);
          }
          onChanged();
        }
        if (other.hasCommitPrefetch()) {
          mergeCommitPrefetch(other.getCommitPrefetch());
        }
        if (other.hasTreePrefetch()) {
          mergeTreePrefetch(other.getTreePrefetch());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        for (int i = 0; i < getBaseChunkCount(); i++) {
          if (!getBaseChunk(i).isInitialized()) {

            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder(
            this.getUnknownFields());
        while (true) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              this.setUnknownFields(unknownFields.build());
              onChanged();
              return this;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              }
              break;
            }
            case 10: {
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder subBuilder = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.newBuilder();
              input.readMessage(subBuilder, extensionRegistry);
              addBaseChunk(subBuilder.buildPartial());
              break;
            }
            case 18: {
              ensureFragmentIsMutable();
              fragment_.add(input.readBytes());
              break;
            }
            case 410: {
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder subBuilder = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.newBuilder();
              if (hasCommitPrefetch()) {
                subBuilder.mergeFrom(getCommitPrefetch());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setCommitPrefetch(subBuilder.buildPartial());
              break;
            }
            case 418: {
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder subBuilder = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.newBuilder();
              if (hasTreePrefetch()) {
                subBuilder.mergeFrom(getTreePrefetch());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setTreePrefetch(subBuilder.buildPartial());
              break;
            }
          }
        }
      }

      private int bitField0_;

      // repeated .org.eclipse.jgit.storage.dht.ChunkMeta.BaseChunk base_chunk = 1;
      private java.util.List<org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk> baseChunk_ =
        java.util.Collections.emptyList();
      private void ensureBaseChunkIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          baseChunk_ = new java.util.ArrayList<org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk>(baseChunk_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunkOrBuilder> baseChunkBuilder_;

      public java.util.List<org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk> getBaseChunkList() {
        if (baseChunkBuilder_ == null) {
          return java.util.Collections.unmodifiableList(baseChunk_);
        } else {
          return baseChunkBuilder_.getMessageList();
        }
      }
      public int getBaseChunkCount() {
        if (baseChunkBuilder_ == null) {
          return baseChunk_.size();
        } else {
          return baseChunkBuilder_.getCount();
        }
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk getBaseChunk(int index) {
        if (baseChunkBuilder_ == null) {
          return baseChunk_.get(index);
        } else {
          return baseChunkBuilder_.getMessage(index);
        }
      }
      public Builder setBaseChunk(
          int index, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk value) {
        if (baseChunkBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureBaseChunkIsMutable();
          baseChunk_.set(index, value);
          onChanged();
        } else {
          baseChunkBuilder_.setMessage(index, value);
        }
        return this;
      }
      public Builder setBaseChunk(
          int index, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder builderForValue) {
        if (baseChunkBuilder_ == null) {
          ensureBaseChunkIsMutable();
          baseChunk_.set(index, builderForValue.build());
          onChanged();
        } else {
          baseChunkBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      public Builder addBaseChunk(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk value) {
        if (baseChunkBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureBaseChunkIsMutable();
          baseChunk_.add(value);
          onChanged();
        } else {
          baseChunkBuilder_.addMessage(value);
        }
        return this;
      }
      public Builder addBaseChunk(
          int index, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk value) {
        if (baseChunkBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureBaseChunkIsMutable();
          baseChunk_.add(index, value);
          onChanged();
        } else {
          baseChunkBuilder_.addMessage(index, value);
        }
        return this;
      }
      public Builder addBaseChunk(
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder builderForValue) {
        if (baseChunkBuilder_ == null) {
          ensureBaseChunkIsMutable();
          baseChunk_.add(builderForValue.build());
          onChanged();
        } else {
          baseChunkBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      public Builder addBaseChunk(
          int index, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder builderForValue) {
        if (baseChunkBuilder_ == null) {
          ensureBaseChunkIsMutable();
          baseChunk_.add(index, builderForValue.build());
          onChanged();
        } else {
          baseChunkBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      public Builder addAllBaseChunk(
          java.lang.Iterable<? extends org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk> values) {
        if (baseChunkBuilder_ == null) {
          ensureBaseChunkIsMutable();
          super.addAll(values, baseChunk_);
          onChanged();
        } else {
          baseChunkBuilder_.addAllMessages(values);
        }
        return this;
      }
      public Builder clearBaseChunk() {
        if (baseChunkBuilder_ == null) {
          baseChunk_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          baseChunkBuilder_.clear();
        }
        return this;
      }
      public Builder removeBaseChunk(int index) {
        if (baseChunkBuilder_ == null) {
          ensureBaseChunkIsMutable();
          baseChunk_.remove(index);
          onChanged();
        } else {
          baseChunkBuilder_.remove(index);
        }
        return this;
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder getBaseChunkBuilder(
          int index) {
        return getBaseChunkFieldBuilder().getBuilder(index);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunkOrBuilder getBaseChunkOrBuilder(
          int index) {
        if (baseChunkBuilder_ == null) {
          return baseChunk_.get(index);  } else {
          return baseChunkBuilder_.getMessageOrBuilder(index);
        }
      }
      public java.util.List<? extends org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunkOrBuilder>
           getBaseChunkOrBuilderList() {
        if (baseChunkBuilder_ != null) {
          return baseChunkBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(baseChunk_);
        }
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder addBaseChunkBuilder() {
        return getBaseChunkFieldBuilder().addBuilder(
            org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.getDefaultInstance());
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder addBaseChunkBuilder(
          int index) {
        return getBaseChunkFieldBuilder().addBuilder(
            index, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.getDefaultInstance());
      }
      public java.util.List<org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder>
           getBaseChunkBuilderList() {
        return getBaseChunkFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunkOrBuilder>
          getBaseChunkFieldBuilder() {
        if (baseChunkBuilder_ == null) {
          baseChunkBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunkOrBuilder>(
                  baseChunk_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          baseChunk_ = null;
        }
        return baseChunkBuilder_;
      }

      // repeated string fragment = 2;
      private com.google.protobuf.LazyStringList fragment_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureFragmentIsMutable() {
        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
          fragment_ = new com.google.protobuf.LazyStringArrayList(fragment_);
          bitField0_ |= 0x00000002;
         }
      }
      public java.util.List<String>
          getFragmentList() {
        return java.util.Collections.unmodifiableList(fragment_);
      }
      public int getFragmentCount() {
        return fragment_.size();
      }
      public String getFragment(int index) {
        return fragment_.get(index);
      }
      public Builder setFragment(
          int index, String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureFragmentIsMutable();
        fragment_.set(index, value);
        onChanged();
        return this;
      }
      public Builder addFragment(String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureFragmentIsMutable();
        fragment_.add(value);
        onChanged();
        return this;
      }
      public Builder addAllFragment(
          java.lang.Iterable<String> values) {
        ensureFragmentIsMutable();
        super.addAll(values, fragment_);
        onChanged();
        return this;
      }
      public Builder clearFragment() {
        fragment_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000002);
        onChanged();
        return this;
      }
      void addFragment(com.google.protobuf.ByteString value) {
        ensureFragmentIsMutable();
        fragment_.add(value);
        onChanged();
      }

      // optional .org.eclipse.jgit.storage.dht.ChunkMeta.PrefetchHint commit_prefetch = 51;
      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint commitPrefetch_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder> commitPrefetchBuilder_;
      public boolean hasCommitPrefetch() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint getCommitPrefetch() {
        if (commitPrefetchBuilder_ == null) {
          return commitPrefetch_;
        } else {
          return commitPrefetchBuilder_.getMessage();
        }
      }
      public Builder setCommitPrefetch(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint value) {
        if (commitPrefetchBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          commitPrefetch_ = value;
          onChanged();
        } else {
          commitPrefetchBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      public Builder setCommitPrefetch(
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder builderForValue) {
        if (commitPrefetchBuilder_ == null) {
          commitPrefetch_ = builderForValue.build();
          onChanged();
        } else {
          commitPrefetchBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      public Builder mergeCommitPrefetch(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint value) {
        if (commitPrefetchBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004) &&
              commitPrefetch_ != org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance()) {
            commitPrefetch_ =
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.newBuilder(commitPrefetch_).mergeFrom(value).buildPartial();
          } else {
            commitPrefetch_ = value;
          }
          onChanged();
        } else {
          commitPrefetchBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      public Builder clearCommitPrefetch() {
        if (commitPrefetchBuilder_ == null) {
          commitPrefetch_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance();
          onChanged();
        } else {
          commitPrefetchBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder getCommitPrefetchBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getCommitPrefetchFieldBuilder().getBuilder();
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder getCommitPrefetchOrBuilder() {
        if (commitPrefetchBuilder_ != null) {
          return commitPrefetchBuilder_.getMessageOrBuilder();
        } else {
          return commitPrefetch_;
        }
      }
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder>
          getCommitPrefetchFieldBuilder() {
        if (commitPrefetchBuilder_ == null) {
          commitPrefetchBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder>(
                  commitPrefetch_,
                  getParentForChildren(),
                  isClean());
          commitPrefetch_ = null;
        }
        return commitPrefetchBuilder_;
      }

      // optional .org.eclipse.jgit.storage.dht.ChunkMeta.PrefetchHint tree_prefetch = 52;
      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint treePrefetch_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder> treePrefetchBuilder_;
      public boolean hasTreePrefetch() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint getTreePrefetch() {
        if (treePrefetchBuilder_ == null) {
          return treePrefetch_;
        } else {
          return treePrefetchBuilder_.getMessage();
        }
      }
      public Builder setTreePrefetch(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint value) {
        if (treePrefetchBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          treePrefetch_ = value;
          onChanged();
        } else {
          treePrefetchBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      public Builder setTreePrefetch(
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder builderForValue) {
        if (treePrefetchBuilder_ == null) {
          treePrefetch_ = builderForValue.build();
          onChanged();
        } else {
          treePrefetchBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      public Builder mergeTreePrefetch(org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint value) {
        if (treePrefetchBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              treePrefetch_ != org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance()) {
            treePrefetch_ =
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.newBuilder(treePrefetch_).mergeFrom(value).buildPartial();
          } else {
            treePrefetch_ = value;
          }
          onChanged();
        } else {
          treePrefetchBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      public Builder clearTreePrefetch() {
        if (treePrefetchBuilder_ == null) {
          treePrefetch_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.getDefaultInstance();
          onChanged();
        } else {
          treePrefetchBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder getTreePrefetchBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getTreePrefetchFieldBuilder().getBuilder();
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder getTreePrefetchOrBuilder() {
        if (treePrefetchBuilder_ != null) {
          return treePrefetchBuilder_.getMessageOrBuilder();
        } else {
          return treePrefetch_;
        }
      }
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder>
          getTreePrefetchFieldBuilder() {
        if (treePrefetchBuilder_ == null) {
          treePrefetchBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHintOrBuilder>(
                  treePrefetch_,
                  getParentForChildren(),
                  isClean());
          treePrefetch_ = null;
        }
        return treePrefetchBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.ChunkMeta)
    }

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

    // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.ChunkMeta)
  }

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

    // required string name = 1;
    boolean hasName();
    String getName();

    // required string version = 2;
    boolean hasVersion();
    String getVersion();

    // required int64 objects_total = 3;
    boolean hasObjectsTotal();
    long getObjectsTotal();

    // optional int64 objects_delta = 4;
    boolean hasObjectsDelta();
    long getObjectsDelta();

    // optional int64 bytes_total = 5;
    boolean hasBytesTotal();
    long getBytesTotal();

    // required .org.eclipse.jgit.storage.dht.CachedPackInfo.TipObjectList tip_list = 6;
    boolean hasTipList();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList getTipList();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectListOrBuilder getTipListOrBuilder();

    // required .org.eclipse.jgit.storage.dht.CachedPackInfo.ChunkList chunk_list = 7;
    boolean hasChunkList();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList getChunkList();
    org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkListOrBuilder getChunkListOrBuilder();
  }
  public static final class CachedPackInfo extends
      com.google.protobuf.GeneratedMessage
      implements CachedPackInfoOrBuilder {
    // Use CachedPackInfo.newBuilder() to construct.
    private CachedPackInfo(Builder builder) {
      super(builder);
    }
    private CachedPackInfo(boolean noInit) {}

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

    public CachedPackInfo getDefaultInstanceForType() {
      return defaultInstance;
    }

    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_fieldAccessorTable;
    }

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

      // repeated string object_name = 1;
      java.util.List<String> getObjectNameList();
      int getObjectNameCount();
      String getObjectName(int index);
    }
    public static final class TipObjectList extends
        com.google.protobuf.GeneratedMessage
        implements TipObjectListOrBuilder {
      // Use TipObjectList.newBuilder() to construct.
      private TipObjectList(Builder builder) {
        super(builder);
      }
      private TipObjectList(boolean noInit) {}

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

      public TipObjectList getDefaultInstanceForType() {
        return defaultInstance;
      }

      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_TipObjectList_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_TipObjectList_fieldAccessorTable;
      }

      // repeated string object_name = 1;
      public static final int OBJECT_NAME_FIELD_NUMBER = 1;
      private com.google.protobuf.LazyStringList objectName_;
      public java.util.List<String>
          getObjectNameList() {
        return objectName_;
      }
      public int getObjectNameCount() {
        return objectName_.size();
      }
      public String getObjectName(int index) {
        return objectName_.get(index);
      }

      private void initFields() {
        objectName_ = com.google.protobuf.LazyStringArrayList.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 < objectName_.size(); i++) {
          output.writeBytes(1, objectName_.getByteString(i));
        }
        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 < objectName_.size(); i++) {
            dataSize += com.google.protobuf.CodedOutputStream
              .computeBytesSizeNoTag(objectName_.getByteString(i));
          }
          size += dataSize;
          size += 1 * getObjectNameList().size();
        }
        size += getUnknownFields().getSerializedSize();
        memoizedSerializedSize = size;
        return size;
      }

      @java.lang.Override
      protected Object writeReplace() throws java.io.ObjectStreamException {
        return super.writeReplace();
      }

      @java.lang.Override
      public boolean equals(final Object obj) {
        if (obj == this) {
         return true;
        }
        if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList)) {
          return super.equals(obj);
        }
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList) obj;

        boolean result = true;
        result = result && getObjectNameList()
            .equals(other.getObjectNameList());
        result = result &&
            getUnknownFields().equals(other.getUnknownFields());
        return result;
      }

      @java.lang.Override
      public int hashCode() {
        int hash = 41;
        hash = (19 * hash) + getDescriptorForType().hashCode();
        if (getObjectNameCount() > 0) {
          hash = (37 * hash) + OBJECT_NAME_FIELD_NUMBER;
          hash = (53 * hash) + getObjectNameList().hashCode();
        }
        hash = (29 * hash) + getUnknownFields().hashCode();
        return hash;
      }

      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList parseFrom(
          com.google.protobuf.ByteString data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList parseFrom(
          com.google.protobuf.ByteString data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList parseFrom(byte[] data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList parseFrom(
          byte[] data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList parseFrom(java.io.InputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList parseFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList parseDelimitedFrom(java.io.InputStream input)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList parseDelimitedFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList parseFrom(
          com.google.protobuf.CodedInputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList parseFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }

      public static Builder newBuilder() { return Builder.create(); }
      public Builder newBuilderForType() { return newBuilder(); }
      public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList 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;
      }
      public static final class Builder extends
          com.google.protobuf.GeneratedMessage.Builder<Builder>
         implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectListOrBuilder {
        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_TipObjectList_descriptor;
        }

        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_TipObjectList_fieldAccessorTable;
        }

        // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.newBuilder()
        private Builder() {
          maybeForceBuilderInitialization();
        }

        private Builder(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();
          objectName_ = com.google.protobuf.LazyStringArrayList.EMPTY;
          bitField0_ = (bitField0_ & ~0x00000001);
          return this;
        }

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

        public com.google.protobuf.Descriptors.Descriptor
            getDescriptorForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.getDescriptor();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList getDefaultInstanceForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.getDefaultInstance();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList build() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(result);
          }
          return result;
        }

        private org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList buildParsed()
            throws com.google.protobuf.InvalidProtocolBufferException {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(
              result).asInvalidProtocolBufferException();
          }
          return result;
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList buildPartial() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList(this);
          int from_bitField0_ = bitField0_;
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            objectName_ = new com.google.protobuf.UnmodifiableLazyStringList(
                objectName_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.objectName_ = objectName_;
          onBuilt();
          return result;
        }

        public Builder mergeFrom(com.google.protobuf.Message other) {
          if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList) {
            return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList)other);
          } else {
            super.mergeFrom(other);
            return this;
          }
        }

        public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList other) {
          if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.getDefaultInstance()) return this;
          if (!other.objectName_.isEmpty()) {
            if (objectName_.isEmpty()) {
              objectName_ = other.objectName_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureObjectNameIsMutable();
              objectName_.addAll(other.objectName_);
            }
            onChanged();
          }
          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 {
          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
            com.google.protobuf.UnknownFieldSet.newBuilder(
              this.getUnknownFields());
          while (true) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              default: {
                if (!parseUnknownField(input, unknownFields,
                                       extensionRegistry, tag)) {
                  this.setUnknownFields(unknownFields.build());
                  onChanged();
                  return this;
                }
                break;
              }
              case 10: {
                ensureObjectNameIsMutable();
                objectName_.add(input.readBytes());
                break;
              }
            }
          }
        }

        private int bitField0_;

        // repeated string object_name = 1;
        private com.google.protobuf.LazyStringList objectName_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        private void ensureObjectNameIsMutable() {
          if (!((bitField0_ & 0x00000001) == 0x00000001)) {
            objectName_ = new com.google.protobuf.LazyStringArrayList(objectName_);
            bitField0_ |= 0x00000001;
           }
        }
        public java.util.List<String>
            getObjectNameList() {
          return java.util.Collections.unmodifiableList(objectName_);
        }
        public int getObjectNameCount() {
          return objectName_.size();
        }
        public String getObjectName(int index) {
          return objectName_.get(index);
        }
        public Builder setObjectName(
            int index, String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureObjectNameIsMutable();
          objectName_.set(index, value);
          onChanged();
          return this;
        }
        public Builder addObjectName(String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureObjectNameIsMutable();
          objectName_.add(value);
          onChanged();
          return this;
        }
        public Builder addAllObjectName(
            java.lang.Iterable<String> values) {
          ensureObjectNameIsMutable();
          super.addAll(values, objectName_);
          onChanged();
          return this;
        }
        public Builder clearObjectName() {
          objectName_ = com.google.protobuf.LazyStringArrayList.EMPTY;
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
          return this;
        }
        void addObjectName(com.google.protobuf.ByteString value) {
          ensureObjectNameIsMutable();
          objectName_.add(value);
          onChanged();
        }

        // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.CachedPackInfo.TipObjectList)
      }

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

      // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.CachedPackInfo.TipObjectList)
    }

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

      // repeated string chunk_key = 1;
      java.util.List<String> getChunkKeyList();
      int getChunkKeyCount();
      String getChunkKey(int index);
    }
    public static final class ChunkList extends
        com.google.protobuf.GeneratedMessage
        implements ChunkListOrBuilder {
      // Use ChunkList.newBuilder() to construct.
      private ChunkList(Builder builder) {
        super(builder);
      }
      private ChunkList(boolean noInit) {}

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

      public ChunkList getDefaultInstanceForType() {
        return defaultInstance;
      }

      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_ChunkList_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_ChunkList_fieldAccessorTable;
      }

      // repeated string chunk_key = 1;
      public static final int CHUNK_KEY_FIELD_NUMBER = 1;
      private com.google.protobuf.LazyStringList chunkKey_;
      public java.util.List<String>
          getChunkKeyList() {
        return chunkKey_;
      }
      public int getChunkKeyCount() {
        return chunkKey_.size();
      }
      public String getChunkKey(int index) {
        return chunkKey_.get(index);
      }

      private void initFields() {
        chunkKey_ = com.google.protobuf.LazyStringArrayList.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 < chunkKey_.size(); i++) {
          output.writeBytes(1, chunkKey_.getByteString(i));
        }
        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 < chunkKey_.size(); i++) {
            dataSize += com.google.protobuf.CodedOutputStream
              .computeBytesSizeNoTag(chunkKey_.getByteString(i));
          }
          size += dataSize;
          size += 1 * getChunkKeyList().size();
        }
        size += getUnknownFields().getSerializedSize();
        memoizedSerializedSize = size;
        return size;
      }

      @java.lang.Override
      protected Object writeReplace() throws java.io.ObjectStreamException {
        return super.writeReplace();
      }

      @java.lang.Override
      public boolean equals(final Object obj) {
        if (obj == this) {
         return true;
        }
        if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList)) {
          return super.equals(obj);
        }
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList) obj;

        boolean result = true;
        result = result && getChunkKeyList()
            .equals(other.getChunkKeyList());
        result = result &&
            getUnknownFields().equals(other.getUnknownFields());
        return result;
      }

      @java.lang.Override
      public int hashCode() {
        int hash = 41;
        hash = (19 * hash) + getDescriptorForType().hashCode();
        if (getChunkKeyCount() > 0) {
          hash = (37 * hash) + CHUNK_KEY_FIELD_NUMBER;
          hash = (53 * hash) + getChunkKeyList().hashCode();
        }
        hash = (29 * hash) + getUnknownFields().hashCode();
        return hash;
      }

      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList parseFrom(
          com.google.protobuf.ByteString data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList parseFrom(
          com.google.protobuf.ByteString data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList parseFrom(byte[] data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList parseFrom(
          byte[] data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return newBuilder().mergeFrom(data, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList parseFrom(java.io.InputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList parseFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList parseDelimitedFrom(java.io.InputStream input)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList parseDelimitedFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        Builder builder = newBuilder();
        if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
          return builder.buildParsed();
        } else {
          return null;
        }
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList parseFrom(
          com.google.protobuf.CodedInputStream input)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input).buildParsed();
      }
      public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList parseFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return newBuilder().mergeFrom(input, extensionRegistry)
                 .buildParsed();
      }

      public static Builder newBuilder() { return Builder.create(); }
      public Builder newBuilderForType() { return newBuilder(); }
      public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList 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;
      }
      public static final class Builder extends
          com.google.protobuf.GeneratedMessage.Builder<Builder>
         implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkListOrBuilder {
        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_ChunkList_descriptor;
        }

        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_ChunkList_fieldAccessorTable;
        }

        // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.newBuilder()
        private Builder() {
          maybeForceBuilderInitialization();
        }

        private Builder(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();
          chunkKey_ = com.google.protobuf.LazyStringArrayList.EMPTY;
          bitField0_ = (bitField0_ & ~0x00000001);
          return this;
        }

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

        public com.google.protobuf.Descriptors.Descriptor
            getDescriptorForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.getDescriptor();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList getDefaultInstanceForType() {
          return org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.getDefaultInstance();
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList build() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(result);
          }
          return result;
        }

        private org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList buildParsed()
            throws com.google.protobuf.InvalidProtocolBufferException {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(
              result).asInvalidProtocolBufferException();
          }
          return result;
        }

        public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList buildPartial() {
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList(this);
          int from_bitField0_ = bitField0_;
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            chunkKey_ = new com.google.protobuf.UnmodifiableLazyStringList(
                chunkKey_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.chunkKey_ = chunkKey_;
          onBuilt();
          return result;
        }

        public Builder mergeFrom(com.google.protobuf.Message other) {
          if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList) {
            return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList)other);
          } else {
            super.mergeFrom(other);
            return this;
          }
        }

        public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList other) {
          if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.getDefaultInstance()) return this;
          if (!other.chunkKey_.isEmpty()) {
            if (chunkKey_.isEmpty()) {
              chunkKey_ = other.chunkKey_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureChunkKeyIsMutable();
              chunkKey_.addAll(other.chunkKey_);
            }
            onChanged();
          }
          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 {
          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
            com.google.protobuf.UnknownFieldSet.newBuilder(
              this.getUnknownFields());
          while (true) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              default: {
                if (!parseUnknownField(input, unknownFields,
                                       extensionRegistry, tag)) {
                  this.setUnknownFields(unknownFields.build());
                  onChanged();
                  return this;
                }
                break;
              }
              case 10: {
                ensureChunkKeyIsMutable();
                chunkKey_.add(input.readBytes());
                break;
              }
            }
          }
        }

        private int bitField0_;

        // repeated string chunk_key = 1;
        private com.google.protobuf.LazyStringList chunkKey_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        private void ensureChunkKeyIsMutable() {
          if (!((bitField0_ & 0x00000001) == 0x00000001)) {
            chunkKey_ = new com.google.protobuf.LazyStringArrayList(chunkKey_);
            bitField0_ |= 0x00000001;
           }
        }
        public java.util.List<String>
            getChunkKeyList() {
          return java.util.Collections.unmodifiableList(chunkKey_);
        }
        public int getChunkKeyCount() {
          return chunkKey_.size();
        }
        public String getChunkKey(int index) {
          return chunkKey_.get(index);
        }
        public Builder setChunkKey(
            int index, String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureChunkKeyIsMutable();
          chunkKey_.set(index, value);
          onChanged();
          return this;
        }
        public Builder addChunkKey(String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureChunkKeyIsMutable();
          chunkKey_.add(value);
          onChanged();
          return this;
        }
        public Builder addAllChunkKey(
            java.lang.Iterable<String> values) {
          ensureChunkKeyIsMutable();
          super.addAll(values, chunkKey_);
          onChanged();
          return this;
        }
        public Builder clearChunkKey() {
          chunkKey_ = com.google.protobuf.LazyStringArrayList.EMPTY;
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
          return this;
        }
        void addChunkKey(com.google.protobuf.ByteString value) {
          ensureChunkKeyIsMutable();
          chunkKey_.add(value);
          onChanged();
        }

        // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.CachedPackInfo.ChunkList)
      }

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

      // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.CachedPackInfo.ChunkList)
    }

    private int bitField0_;
    // required string name = 1;
    public static final int NAME_FIELD_NUMBER = 1;
    private Object name_;
    public boolean hasName() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    public String getName() {
      Object ref = name_;
      if (ref instanceof String) {
        return (String) ref;
      } else {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        String s = bs.toStringUtf8();
        if (com.google.protobuf.Internal.isValidUtf8(bs)) {
          name_ = s;
        }
        return s;
      }
    }
    private com.google.protobuf.ByteString getNameBytes() {
      Object ref = name_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8((String) ref);
        name_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // required string version = 2;
    public static final int VERSION_FIELD_NUMBER = 2;
    private Object version_;
    public boolean hasVersion() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    public String getVersion() {
      Object ref = version_;
      if (ref instanceof String) {
        return (String) ref;
      } else {
        com.google.protobuf.ByteString bs =
            (com.google.protobuf.ByteString) ref;
        String s = bs.toStringUtf8();
        if (com.google.protobuf.Internal.isValidUtf8(bs)) {
          version_ = s;
        }
        return s;
      }
    }
    private com.google.protobuf.ByteString getVersionBytes() {
      Object ref = version_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b =
            com.google.protobuf.ByteString.copyFromUtf8((String) ref);
        version_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // required int64 objects_total = 3;
    public static final int OBJECTS_TOTAL_FIELD_NUMBER = 3;
    private long objectsTotal_;
    public boolean hasObjectsTotal() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    public long getObjectsTotal() {
      return objectsTotal_;
    }

    // optional int64 objects_delta = 4;
    public static final int OBJECTS_DELTA_FIELD_NUMBER = 4;
    private long objectsDelta_;
    public boolean hasObjectsDelta() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    public long getObjectsDelta() {
      return objectsDelta_;
    }

    // optional int64 bytes_total = 5;
    public static final int BYTES_TOTAL_FIELD_NUMBER = 5;
    private long bytesTotal_;
    public boolean hasBytesTotal() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    public long getBytesTotal() {
      return bytesTotal_;
    }

    // required .org.eclipse.jgit.storage.dht.CachedPackInfo.TipObjectList tip_list = 6;
    public static final int TIP_LIST_FIELD_NUMBER = 6;
    private org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList tipList_;
    public boolean hasTipList() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList getTipList() {
      return tipList_;
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectListOrBuilder getTipListOrBuilder() {
      return tipList_;
    }

    // required .org.eclipse.jgit.storage.dht.CachedPackInfo.ChunkList chunk_list = 7;
    public static final int CHUNK_LIST_FIELD_NUMBER = 7;
    private org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList chunkList_;
    public boolean hasChunkList() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList getChunkList() {
      return chunkList_;
    }
    public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkListOrBuilder getChunkListOrBuilder() {
      return chunkList_;
    }

    private void initFields() {
      name_ = "";
      version_ = "";
      objectsTotal_ = 0L;
      objectsDelta_ = 0L;
      bytesTotal_ = 0L;
      tipList_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.getDefaultInstance();
      chunkList_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasName()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasVersion()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasObjectsTotal()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasTipList()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasChunkList()) {
        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, getNameBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getVersionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt64(3, objectsTotal_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt64(4, objectsDelta_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeInt64(5, bytesTotal_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeMessage(6, tipList_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        output.writeMessage(7, chunkList_);
      }
      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, getNameBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getVersionBytes());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, objectsTotal_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(4, objectsDelta_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(5, bytesTotal_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(6, tipList_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(7, chunkList_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    @java.lang.Override
    protected Object writeReplace() throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    @java.lang.Override
    public boolean equals(final Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo)) {
        return super.equals(obj);
      }
      org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo other = (org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo) obj;

      boolean result = true;
      result = result && (hasName() == other.hasName());
      if (hasName()) {
        result = result && getName()
            .equals(other.getName());
      }
      result = result && (hasVersion() == other.hasVersion());
      if (hasVersion()) {
        result = result && getVersion()
            .equals(other.getVersion());
      }
      result = result && (hasObjectsTotal() == other.hasObjectsTotal());
      if (hasObjectsTotal()) {
        result = result && (getObjectsTotal()
            == other.getObjectsTotal());
      }
      result = result && (hasObjectsDelta() == other.hasObjectsDelta());
      if (hasObjectsDelta()) {
        result = result && (getObjectsDelta()
            == other.getObjectsDelta());
      }
      result = result && (hasBytesTotal() == other.hasBytesTotal());
      if (hasBytesTotal()) {
        result = result && (getBytesTotal()
            == other.getBytesTotal());
      }
      result = result && (hasTipList() == other.hasTipList());
      if (hasTipList()) {
        result = result && getTipList()
            .equals(other.getTipList());
      }
      result = result && (hasChunkList() == other.hasChunkList());
      if (hasChunkList()) {
        result = result && getChunkList()
            .equals(other.getChunkList());
      }
      result = result &&
          getUnknownFields().equals(other.getUnknownFields());
      return result;
    }

    @java.lang.Override
    public int hashCode() {
      int hash = 41;
      hash = (19 * hash) + getDescriptorForType().hashCode();
      if (hasName()) {
        hash = (37 * hash) + NAME_FIELD_NUMBER;
        hash = (53 * hash) + getName().hashCode();
      }
      if (hasVersion()) {
        hash = (37 * hash) + VERSION_FIELD_NUMBER;
        hash = (53 * hash) + getVersion().hashCode();
      }
      if (hasObjectsTotal()) {
        hash = (37 * hash) + OBJECTS_TOTAL_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getObjectsTotal());
      }
      if (hasObjectsDelta()) {
        hash = (37 * hash) + OBJECTS_DELTA_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getObjectsDelta());
      }
      if (hasBytesTotal()) {
        hash = (37 * hash) + BYTES_TOTAL_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getBytesTotal());
      }
      if (hasTipList()) {
        hash = (37 * hash) + TIP_LIST_FIELD_NUMBER;
        hash = (53 * hash) + getTipList().hashCode();
      }
      if (hasChunkList()) {
        hash = (37 * hash) + CHUNK_LIST_FIELD_NUMBER;
        hash = (53 * hash) + getChunkList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      return hash;
    }

    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return newBuilder().mergeFrom(data, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      Builder builder = newBuilder();
      if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
        return builder.buildParsed();
      } else {
        return null;
      }
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input).buildParsed();
    }
    public static org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return newBuilder().mergeFrom(input, extensionRegistry)
               .buildParsed();
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo 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;
    }
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfoOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_fieldAccessorTable;
      }

      // Construct using org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

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

      public Builder clear() {
        super.clear();
        name_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        version_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        objectsTotal_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000004);
        objectsDelta_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000008);
        bytesTotal_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000010);
        if (tipListBuilder_ == null) {
          tipList_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.getDefaultInstance();
        } else {
          tipListBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000020);
        if (chunkListBuilder_ == null) {
          chunkList_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.getDefaultInstance();
        } else {
          chunkListBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000040);
        return this;
      }

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

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.getDescriptor();
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo getDefaultInstanceForType() {
        return org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.getDefaultInstance();
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo build() {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo buildParsed()
          throws com.google.protobuf.InvalidProtocolBufferException {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(
            result).asInvalidProtocolBufferException();
        }
        return result;
      }

      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo buildPartial() {
        org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo result = new org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.name_ = name_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.version_ = version_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.objectsTotal_ = objectsTotal_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.objectsDelta_ = objectsDelta_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.bytesTotal_ = bytesTotal_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        if (tipListBuilder_ == null) {
          result.tipList_ = tipList_;
        } else {
          result.tipList_ = tipListBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000040;
        }
        if (chunkListBuilder_ == null) {
          result.chunkList_ = chunkList_;
        } else {
          result.chunkList_ = chunkListBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo) {
          return mergeFrom((org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo other) {
        if (other == org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.getDefaultInstance()) return this;
        if (other.hasName()) {
          setName(other.getName());
        }
        if (other.hasVersion()) {
          setVersion(other.getVersion());
        }
        if (other.hasObjectsTotal()) {
          setObjectsTotal(other.getObjectsTotal());
        }
        if (other.hasObjectsDelta()) {
          setObjectsDelta(other.getObjectsDelta());
        }
        if (other.hasBytesTotal()) {
          setBytesTotal(other.getBytesTotal());
        }
        if (other.hasTipList()) {
          mergeTipList(other.getTipList());
        }
        if (other.hasChunkList()) {
          mergeChunkList(other.getChunkList());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasName()) {

          return false;
        }
        if (!hasVersion()) {

          return false;
        }
        if (!hasObjectsTotal()) {

          return false;
        }
        if (!hasTipList()) {

          return false;
        }
        if (!hasChunkList()) {

          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder(
            this.getUnknownFields());
        while (true) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              this.setUnknownFields(unknownFields.build());
              onChanged();
              return this;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                this.setUnknownFields(unknownFields.build());
                onChanged();
                return this;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              name_ = input.readBytes();
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              version_ = input.readBytes();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              objectsTotal_ = input.readInt64();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              objectsDelta_ = input.readInt64();
              break;
            }
            case 40: {
              bitField0_ |= 0x00000010;
              bytesTotal_ = input.readInt64();
              break;
            }
            case 50: {
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.Builder subBuilder = org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.newBuilder();
              if (hasTipList()) {
                subBuilder.mergeFrom(getTipList());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setTipList(subBuilder.buildPartial());
              break;
            }
            case 58: {
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.Builder subBuilder = org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.newBuilder();
              if (hasChunkList()) {
                subBuilder.mergeFrom(getChunkList());
              }
              input.readMessage(subBuilder, extensionRegistry);
              setChunkList(subBuilder.buildPartial());
              break;
            }
          }
        }
      }

      private int bitField0_;

      // required string name = 1;
      private Object name_ = "";
      public boolean hasName() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      public String getName() {
        Object ref = name_;
        if (!(ref instanceof String)) {
          String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
          name_ = s;
          return s;
        } else {
          return (String) ref;
        }
      }
      public Builder setName(String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        name_ = value;
        onChanged();
        return this;
      }
      public Builder clearName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        name_ = getDefaultInstance().getName();
        onChanged();
        return this;
      }
      void setName(com.google.protobuf.ByteString value) {
        bitField0_ |= 0x00000001;
        name_ = value;
        onChanged();
      }

      // required string version = 2;
      private Object version_ = "";
      public boolean hasVersion() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      public String getVersion() {
        Object ref = version_;
        if (!(ref instanceof String)) {
          String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
          version_ = s;
          return s;
        } else {
          return (String) ref;
        }
      }
      public Builder setVersion(String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        version_ = value;
        onChanged();
        return this;
      }
      public Builder clearVersion() {
        bitField0_ = (bitField0_ & ~0x00000002);
        version_ = getDefaultInstance().getVersion();
        onChanged();
        return this;
      }
      void setVersion(com.google.protobuf.ByteString value) {
        bitField0_ |= 0x00000002;
        version_ = value;
        onChanged();
      }

      // required int64 objects_total = 3;
      private long objectsTotal_ ;
      public boolean hasObjectsTotal() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      public long getObjectsTotal() {
        return objectsTotal_;
      }
      public Builder setObjectsTotal(long value) {
        bitField0_ |= 0x00000004;
        objectsTotal_ = value;
        onChanged();
        return this;
      }
      public Builder clearObjectsTotal() {
        bitField0_ = (bitField0_ & ~0x00000004);
        objectsTotal_ = 0L;
        onChanged();
        return this;
      }

      // optional int64 objects_delta = 4;
      private long objectsDelta_ ;
      public boolean hasObjectsDelta() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      public long getObjectsDelta() {
        return objectsDelta_;
      }
      public Builder setObjectsDelta(long value) {
        bitField0_ |= 0x00000008;
        objectsDelta_ = value;
        onChanged();
        return this;
      }
      public Builder clearObjectsDelta() {
        bitField0_ = (bitField0_ & ~0x00000008);
        objectsDelta_ = 0L;
        onChanged();
        return this;
      }

      // optional int64 bytes_total = 5;
      private long bytesTotal_ ;
      public boolean hasBytesTotal() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      public long getBytesTotal() {
        return bytesTotal_;
      }
      public Builder setBytesTotal(long value) {
        bitField0_ |= 0x00000010;
        bytesTotal_ = value;
        onChanged();
        return this;
      }
      public Builder clearBytesTotal() {
        bitField0_ = (bitField0_ & ~0x00000010);
        bytesTotal_ = 0L;
        onChanged();
        return this;
      }

      // required .org.eclipse.jgit.storage.dht.CachedPackInfo.TipObjectList tip_list = 6;
      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList tipList_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectListOrBuilder> tipListBuilder_;
      public boolean hasTipList() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList getTipList() {
        if (tipListBuilder_ == null) {
          return tipList_;
        } else {
          return tipListBuilder_.getMessage();
        }
      }
      public Builder setTipList(org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList value) {
        if (tipListBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          tipList_ = value;
          onChanged();
        } else {
          tipListBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000020;
        return this;
      }
      public Builder setTipList(
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.Builder builderForValue) {
        if (tipListBuilder_ == null) {
          tipList_ = builderForValue.build();
          onChanged();
        } else {
          tipListBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000020;
        return this;
      }
      public Builder mergeTipList(org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList value) {
        if (tipListBuilder_ == null) {
          if (((bitField0_ & 0x00000020) == 0x00000020) &&
              tipList_ != org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.getDefaultInstance()) {
            tipList_ =
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.newBuilder(tipList_).mergeFrom(value).buildPartial();
          } else {
            tipList_ = value;
          }
          onChanged();
        } else {
          tipListBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000020;
        return this;
      }
      public Builder clearTipList() {
        if (tipListBuilder_ == null) {
          tipList_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.getDefaultInstance();
          onChanged();
        } else {
          tipListBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000020);
        return this;
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.Builder getTipListBuilder() {
        bitField0_ |= 0x00000020;
        onChanged();
        return getTipListFieldBuilder().getBuilder();
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectListOrBuilder getTipListOrBuilder() {
        if (tipListBuilder_ != null) {
          return tipListBuilder_.getMessageOrBuilder();
        } else {
          return tipList_;
        }
      }
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectListOrBuilder>
          getTipListFieldBuilder() {
        if (tipListBuilder_ == null) {
          tipListBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectListOrBuilder>(
                  tipList_,
                  getParentForChildren(),
                  isClean());
          tipList_ = null;
        }
        return tipListBuilder_;
      }

      // required .org.eclipse.jgit.storage.dht.CachedPackInfo.ChunkList chunk_list = 7;
      private org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList chunkList_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.getDefaultInstance();
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkListOrBuilder> chunkListBuilder_;
      public boolean hasChunkList() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList getChunkList() {
        if (chunkListBuilder_ == null) {
          return chunkList_;
        } else {
          return chunkListBuilder_.getMessage();
        }
      }
      public Builder setChunkList(org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList value) {
        if (chunkListBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          chunkList_ = value;
          onChanged();
        } else {
          chunkListBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000040;
        return this;
      }
      public Builder setChunkList(
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.Builder builderForValue) {
        if (chunkListBuilder_ == null) {
          chunkList_ = builderForValue.build();
          onChanged();
        } else {
          chunkListBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000040;
        return this;
      }
      public Builder mergeChunkList(org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList value) {
        if (chunkListBuilder_ == null) {
          if (((bitField0_ & 0x00000040) == 0x00000040) &&
              chunkList_ != org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.getDefaultInstance()) {
            chunkList_ =
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.newBuilder(chunkList_).mergeFrom(value).buildPartial();
          } else {
            chunkList_ = value;
          }
          onChanged();
        } else {
          chunkListBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000040;
        return this;
      }
      public Builder clearChunkList() {
        if (chunkListBuilder_ == null) {
          chunkList_ = org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.getDefaultInstance();
          onChanged();
        } else {
          chunkListBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000040);
        return this;
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.Builder getChunkListBuilder() {
        bitField0_ |= 0x00000040;
        onChanged();
        return getChunkListFieldBuilder().getBuilder();
      }
      public org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkListOrBuilder getChunkListOrBuilder() {
        if (chunkListBuilder_ != null) {
          return chunkListBuilder_.getMessageOrBuilder();
        } else {
          return chunkList_;
        }
      }
      private com.google.protobuf.SingleFieldBuilder<
          org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkListOrBuilder>
          getChunkListFieldBuilder() {
        if (chunkListBuilder_ == null) {
          chunkListBuilder_ = new com.google.protobuf.SingleFieldBuilder<
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.Builder, org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkListOrBuilder>(
                  chunkList_,
                  getParentForChildren(),
                  isClean());
          chunkList_ = null;
        }
        return chunkListBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.eclipse.jgit.storage.dht.CachedPackInfo)
    }

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

    // @@protoc_insertion_point(class_scope:org.eclipse.jgit.storage.dht.CachedPackInfo)
  }

  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_RefData_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_RefData_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_RefData_Id_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_RefData_Id_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_ObjectInfo_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_ObjectInfo_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_ObjectCounts_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_ObjectCounts_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_BaseChunk_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_BaseChunk_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_PrefetchHint_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_PrefetchHint_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_TipObjectList_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_TipObjectList_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_ChunkList_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_ChunkList_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,org/eclipse/jgit/storage/dht/git_store" +
      ".proto\022\034org.eclipse.jgit.storage.dht\"\343\001\n" +
      "\007RefData\022\023\n\010sequence\030\005 \002(\r:\0010\022\016\n\006symref\030" +
      "\001 \001(\t\0228\n\006target\030\002 \001(\0132(.org.eclipse.jgit" +
      ".storage.dht.RefData.Id\022\021\n\tis_peeled\030\003 \001" +
      "(\010\0228\n\006peeled\030\004 \001(\0132(.org.eclipse.jgit.st" +
      "orage.dht.RefData.Id\032,\n\002Id\022\023\n\013object_nam" +
      "e\030\001 \002(\t\022\021\n\tchunk_key\030\002 \001(\t\"\364\001\n\nObjectInf" +
      "o\022H\n\013object_type\030\001 \001(\01623.org.eclipse.jgi" +
      "t.storage.dht.ObjectInfo.ObjectType\022\016\n\006o",
      "ffset\030\002 \002(\005\022\023\n\013packed_size\030\003 \002(\003\022\025\n\rinfl" +
      "ated_size\030\004 \002(\003\022\022\n\ndelta_base\030\005 \001(\014\022\025\n\ri" +
      "s_fragmented\030\006 \001(\010\"5\n\nObjectType\022\n\n\006COMM" +
      "IT\020\001\022\010\n\004TREE\020\002\022\010\n\004BLOB\020\003\022\007\n\003TAG\020\004\"\217\004\n\tCh" +
      "unkInfo\022>\n\006source\030\001 \001(\0162..org.eclipse.jg" +
      "it.storage.dht.ChunkInfo.Source\022G\n\013objec" +
      "t_type\030\002 \001(\01622.org.eclipse.jgit.storage." +
      "dht.ChunkInfo.ObjectType\022\023\n\013is_fragment\030" +
      "\003 \001(\010\022\027\n\017cached_pack_key\030\004 \001(\t\022K\n\robject" +
      "_counts\030\005 \001(\01324.org.eclipse.jgit.storage",
      ".dht.ChunkInfo.ObjectCounts\022\022\n\nchunk_siz" +
      "e\030\006 \001(\005\022\022\n\nindex_size\030\007 \001(\005\022\021\n\tmeta_size" +
      "\030\010 \001(\005\032R\n\014ObjectCounts\022\r\n\005total\030\001 \001(\005\022\r\n" +
      "\005whole\030\002 \001(\005\022\021\n\tofs_delta\030\003 \001(\005\022\021\n\tref_d" +
      "elta\030\004 \001(\005\"-\n\006Source\022\013\n\007RECEIVE\020\001\022\n\n\006INS" +
      "ERT\020\002\022\n\n\006REPACK\020\003\"@\n\nObjectType\022\t\n\005MIXED" +
      "\020\000\022\n\n\006COMMIT\020\001\022\010\n\004TREE\020\002\022\010\n\004BLOB\020\003\022\007\n\003TA" +
      "G\020\004\"\352\002\n\tChunkMeta\022E\n\nbase_chunk\030\001 \003(\01321." +
      "org.eclipse.jgit.storage.dht.ChunkMeta.B" +
      "aseChunk\022\020\n\010fragment\030\002 \003(\t\022M\n\017commit_pre",
      "fetch\0303 \001(\01324.org.eclipse.jgit.storage.d" +
      "ht.ChunkMeta.PrefetchHint\022K\n\rtree_prefet" +
      "ch\0304 \001(\01324.org.eclipse.jgit.storage.dht." +
      "ChunkMeta.PrefetchHint\0326\n\tBaseChunk\022\026\n\016r" +
      "elative_start\030\001 \002(\003\022\021\n\tchunk_key\030\002 \002(\t\0320" +
      "\n\014PrefetchHint\022\014\n\004edge\030\001 \003(\t\022\022\n\nsequenti" +
      "al\030\002 \003(\t\"\322\002\n\016CachedPackInfo\022\014\n\004name\030\001 \002(" +
      "\t\022\017\n\007version\030\002 \002(\t\022\025\n\robjects_total\030\003 \002(" +
      "\003\022\025\n\robjects_delta\030\004 \001(\003\022\023\n\013bytes_total\030" +
      "\005 \001(\003\022L\n\010tip_list\030\006 \002(\0132:.org.eclipse.jg",
      "it.storage.dht.CachedPackInfo.TipObjectL" +
      "ist\022J\n\nchunk_list\030\007 \002(\01326.org.eclipse.jg" +
      "it.storage.dht.CachedPackInfo.ChunkList\032" +
      "$\n\rTipObjectList\022\023\n\013object_name\030\001 \003(\t\032\036\n" +
      "\tChunkList\022\021\n\tchunk_key\030\001 \003(\tB1\n,org.ecl" +
      "ipse.jgit.generated.storage.dht.proto\240\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_org_eclipse_jgit_storage_dht_RefData_descriptor =
            getDescriptor().getMessageTypes().get(0);
          internal_static_org_eclipse_jgit_storage_dht_RefData_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_RefData_descriptor,
              new java.lang.String[] { "Sequence", "Symref", "Target", "IsPeeled", "Peeled", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Builder.class);
          internal_static_org_eclipse_jgit_storage_dht_RefData_Id_descriptor =
            internal_static_org_eclipse_jgit_storage_dht_RefData_descriptor.getNestedTypes().get(0);
          internal_static_org_eclipse_jgit_storage_dht_RefData_Id_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_RefData_Id_descriptor,
              new java.lang.String[] { "ObjectName", "ChunkKey", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.RefData.Id.Builder.class);
          internal_static_org_eclipse_jgit_storage_dht_ObjectInfo_descriptor =
            getDescriptor().getMessageTypes().get(1);
          internal_static_org_eclipse_jgit_storage_dht_ObjectInfo_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_ObjectInfo_descriptor,
              new java.lang.String[] { "ObjectType", "Offset", "PackedSize", "InflatedSize", "DeltaBase", "IsFragmented", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ObjectInfo.Builder.class);
          internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_descriptor =
            getDescriptor().getMessageTypes().get(2);
          internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_descriptor,
              new java.lang.String[] { "Source", "ObjectType", "IsFragment", "CachedPackKey", "ObjectCounts", "ChunkSize", "IndexSize", "MetaSize", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.Builder.class);
          internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_ObjectCounts_descriptor =
            internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_descriptor.getNestedTypes().get(0);
          internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_ObjectCounts_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_ChunkInfo_ObjectCounts_descriptor,
              new java.lang.String[] { "Total", "Whole", "OfsDelta", "RefDelta", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkInfo.ObjectCounts.Builder.class);
          internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_descriptor =
            getDescriptor().getMessageTypes().get(3);
          internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_descriptor,
              new java.lang.String[] { "BaseChunk", "Fragment", "CommitPrefetch", "TreePrefetch", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.Builder.class);
          internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_BaseChunk_descriptor =
            internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_descriptor.getNestedTypes().get(0);
          internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_BaseChunk_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_BaseChunk_descriptor,
              new java.lang.String[] { "RelativeStart", "ChunkKey", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.BaseChunk.Builder.class);
          internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_PrefetchHint_descriptor =
            internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_descriptor.getNestedTypes().get(1);
          internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_PrefetchHint_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_ChunkMeta_PrefetchHint_descriptor,
              new java.lang.String[] { "Edge", "Sequential", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.ChunkMeta.PrefetchHint.Builder.class);
          internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_descriptor =
            getDescriptor().getMessageTypes().get(4);
          internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_descriptor,
              new java.lang.String[] { "Name", "Version", "ObjectsTotal", "ObjectsDelta", "BytesTotal", "TipList", "ChunkList", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.Builder.class);
          internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_TipObjectList_descriptor =
            internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_descriptor.getNestedTypes().get(0);
          internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_TipObjectList_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_TipObjectList_descriptor,
              new java.lang.String[] { "ObjectName", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.TipObjectList.Builder.class);
          internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_ChunkList_descriptor =
            internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_descriptor.getNestedTypes().get(1);
          internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_ChunkList_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_org_eclipse_jgit_storage_dht_CachedPackInfo_ChunkList_descriptor,
              new java.lang.String[] { "ChunkKey", },
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.class,
              org.eclipse.jgit.generated.storage.dht.proto.GitStore.CachedPackInfo.ChunkList.Builder.class);
          return null;
        }
      };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        }, assigner);
  }

  // @@protoc_insertion_point(outer_class_scope)
}
