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

package org.apache.accumulo.examples.wikisearch.protobuf;

public final class TermWeight {
  private TermWeight() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  public interface InfoOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.apache.accumulo.examples.wikisearch.protobuf.Info)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>required float normalizedTermFrequency = 1;</code>
     * @return Whether the normalizedTermFrequency field is set.
     */
    boolean hasNormalizedTermFrequency();
    /**
     * <code>required float normalizedTermFrequency = 1;</code>
     * @return The normalizedTermFrequency.
     */
    float getNormalizedTermFrequency();

    /**
     * <code>repeated uint32 wordOffset = 2;</code>
     * @return A list containing the wordOffset.
     */
    java.util.List<java.lang.Integer> getWordOffsetList();
    /**
     * <code>repeated uint32 wordOffset = 2;</code>
     * @return The count of wordOffset.
     */
    int getWordOffsetCount();
    /**
     * <code>repeated uint32 wordOffset = 2;</code>
     * @param index The index of the element to return.
     * @return The wordOffset at the given index.
     */
    int getWordOffset(int index);
  }
  /**
   * Protobuf type {@code org.apache.accumulo.examples.wikisearch.protobuf.Info}
   */
  public static final class Info extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:org.apache.accumulo.examples.wikisearch.protobuf.Info)
      InfoOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Info.newBuilder() to construct.
    private Info(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Info() {
      wordOffset_ = emptyIntList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Info();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private Info(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 13: {
              bitField0_ |= 0x00000001;
              normalizedTermFrequency_ = input.readFloat();
              break;
            }
            case 16: {
              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
                wordOffset_ = newIntList();
                mutable_bitField0_ |= 0x00000002;
              }
              wordOffset_.addInt(input.readUInt32());
              break;
            }
            case 18: {
              int length = input.readRawVarint32();
              int limit = input.pushLimit(length);
              if (!((mutable_bitField0_ & 0x00000002) != 0) && input.getBytesUntilLimit() > 0) {
                wordOffset_ = newIntList();
                mutable_bitField0_ |= 0x00000002;
              }
              while (input.getBytesUntilLimit() > 0) {
                wordOffset_.addInt(input.readUInt32());
              }
              input.popLimit(limit);
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000002) != 0)) {
          wordOffset_.makeImmutable(); // C
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.internal_static_org_apache_accumulo_examples_wikisearch_protobuf_Info_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.internal_static_org_apache_accumulo_examples_wikisearch_protobuf_Info_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info.class, org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info.Builder.class);
    }

    private int bitField0_;
    public static final int NORMALIZEDTERMFREQUENCY_FIELD_NUMBER = 1;
    private float normalizedTermFrequency_;
    /**
     * <code>required float normalizedTermFrequency = 1;</code>
     * @return Whether the normalizedTermFrequency field is set.
     */
    @java.lang.Override
    public boolean hasNormalizedTermFrequency() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>required float normalizedTermFrequency = 1;</code>
     * @return The normalizedTermFrequency.
     */
    @java.lang.Override
    public float getNormalizedTermFrequency() {
      return normalizedTermFrequency_;
    }

    public static final int WORDOFFSET_FIELD_NUMBER = 2;
    private com.google.protobuf.Internal.IntList wordOffset_;
    /**
     * <code>repeated uint32 wordOffset = 2;</code>
     * @return A list containing the wordOffset.
     */
    @java.lang.Override
    public java.util.List<java.lang.Integer>
        getWordOffsetList() {
      return wordOffset_;
    }
    /**
     * <code>repeated uint32 wordOffset = 2;</code>
     * @return The count of wordOffset.
     */
    public int getWordOffsetCount() {
      return wordOffset_.size();
    }
    /**
     * <code>repeated uint32 wordOffset = 2;</code>
     * @param index The index of the element to return.
     * @return The wordOffset at the given index.
     */
    public int getWordOffset(int index) {
      return wordOffset_.getInt(index);
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

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

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeFloat(1, normalizedTermFrequency_);
      }
      for (int i = 0; i < wordOffset_.size(); i++) {
        output.writeUInt32(2, wordOffset_.getInt(i));
      }
      unknownFields.writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeFloatSize(1, normalizedTermFrequency_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < wordOffset_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeUInt32SizeNoTag(wordOffset_.getInt(i));
        }
        size += dataSize;
        size += 1 * getWordOffsetList().size();
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info)) {
        return super.equals(obj);
      }
      org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info other = (org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info) obj;

      if (hasNormalizedTermFrequency() != other.hasNormalizedTermFrequency()) return false;
      if (hasNormalizedTermFrequency()) {
        if (java.lang.Float.floatToIntBits(getNormalizedTermFrequency())
            != java.lang.Float.floatToIntBits(
                other.getNormalizedTermFrequency())) return false;
      }
      if (!getWordOffsetList()
          .equals(other.getWordOffsetList())) return false;
      if (!unknownFields.equals(other.unknownFields)) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasNormalizedTermFrequency()) {
        hash = (37 * hash) + NORMALIZEDTERMFREQUENCY_FIELD_NUMBER;
        hash = (53 * hash) + java.lang.Float.floatToIntBits(
            getNormalizedTermFrequency());
      }
      if (getWordOffsetCount() > 0) {
        hash = (37 * hash) + WORDOFFSET_FIELD_NUMBER;
        hash = (53 * hash) + getWordOffsetList().hashCode();
      }
      hash = (29 * hash) + unknownFields.hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.apache.accumulo.examples.wikisearch.protobuf.Info}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.apache.accumulo.examples.wikisearch.protobuf.Info)
        org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.InfoOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.internal_static_org_apache_accumulo_examples_wikisearch_protobuf_Info_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.internal_static_org_apache_accumulo_examples_wikisearch_protobuf_Info_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info.class, org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info.Builder.class);
      }

      // Construct using org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        normalizedTermFrequency_ = 0F;
        bitField0_ = (bitField0_ & ~0x00000001);
        wordOffset_ = emptyIntList();
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.internal_static_org_apache_accumulo_examples_wikisearch_protobuf_Info_descriptor;
      }

      @java.lang.Override
      public org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info getDefaultInstanceForType() {
        return org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info build() {
        org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info buildPartial() {
        org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info result = new org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.normalizedTermFrequency_ = normalizedTermFrequency_;
          to_bitField0_ |= 0x00000001;
        }
        if (((bitField0_ & 0x00000002) != 0)) {
          wordOffset_.makeImmutable();
          bitField0_ = (bitField0_ & ~0x00000002);
        }
        result.wordOffset_ = wordOffset_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info) {
          return mergeFrom((org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info other) {
        if (other == org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info.getDefaultInstance()) return this;
        if (other.hasNormalizedTermFrequency()) {
          setNormalizedTermFrequency(other.getNormalizedTermFrequency());
        }
        if (!other.wordOffset_.isEmpty()) {
          if (wordOffset_.isEmpty()) {
            wordOffset_ = other.wordOffset_;
            bitField0_ = (bitField0_ & ~0x00000002);
          } else {
            ensureWordOffsetIsMutable();
            wordOffset_.addAll(other.wordOffset_);
          }
          onChanged();
        }
        this.mergeUnknownFields(other.unknownFields);
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        if (!hasNormalizedTermFrequency()) {
          return false;
        }
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private float normalizedTermFrequency_ ;
      /**
       * <code>required float normalizedTermFrequency = 1;</code>
       * @return Whether the normalizedTermFrequency field is set.
       */
      @java.lang.Override
      public boolean hasNormalizedTermFrequency() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>required float normalizedTermFrequency = 1;</code>
       * @return The normalizedTermFrequency.
       */
      @java.lang.Override
      public float getNormalizedTermFrequency() {
        return normalizedTermFrequency_;
      }
      /**
       * <code>required float normalizedTermFrequency = 1;</code>
       * @param value The normalizedTermFrequency to set.
       * @return This builder for chaining.
       */
      public Builder setNormalizedTermFrequency(float value) {
        bitField0_ |= 0x00000001;
        normalizedTermFrequency_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required float normalizedTermFrequency = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearNormalizedTermFrequency() {
        bitField0_ = (bitField0_ & ~0x00000001);
        normalizedTermFrequency_ = 0F;
        onChanged();
        return this;
      }

      private com.google.protobuf.Internal.IntList wordOffset_ = emptyIntList();
      private void ensureWordOffsetIsMutable() {
        if (!((bitField0_ & 0x00000002) != 0)) {
          wordOffset_ = mutableCopy(wordOffset_);
          bitField0_ |= 0x00000002;
         }
      }
      /**
       * <code>repeated uint32 wordOffset = 2;</code>
       * @return A list containing the wordOffset.
       */
      public java.util.List<java.lang.Integer>
          getWordOffsetList() {
        return ((bitField0_ & 0x00000002) != 0) ?
                 java.util.Collections.unmodifiableList(wordOffset_) : wordOffset_;
      }
      /**
       * <code>repeated uint32 wordOffset = 2;</code>
       * @return The count of wordOffset.
       */
      public int getWordOffsetCount() {
        return wordOffset_.size();
      }
      /**
       * <code>repeated uint32 wordOffset = 2;</code>
       * @param index The index of the element to return.
       * @return The wordOffset at the given index.
       */
      public int getWordOffset(int index) {
        return wordOffset_.getInt(index);
      }
      /**
       * <code>repeated uint32 wordOffset = 2;</code>
       * @param index The index to set the value at.
       * @param value The wordOffset to set.
       * @return This builder for chaining.
       */
      public Builder setWordOffset(
          int index, int value) {
        ensureWordOffsetIsMutable();
        wordOffset_.setInt(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated uint32 wordOffset = 2;</code>
       * @param value The wordOffset to add.
       * @return This builder for chaining.
       */
      public Builder addWordOffset(int value) {
        ensureWordOffsetIsMutable();
        wordOffset_.addInt(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated uint32 wordOffset = 2;</code>
       * @param values The wordOffset to add.
       * @return This builder for chaining.
       */
      public Builder addAllWordOffset(
          java.lang.Iterable<? extends java.lang.Integer> values) {
        ensureWordOffsetIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, wordOffset_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated uint32 wordOffset = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearWordOffset() {
        wordOffset_ = emptyIntList();
        bitField0_ = (bitField0_ & ~0x00000002);
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:org.apache.accumulo.examples.wikisearch.protobuf.Info)
    }

    // @@protoc_insertion_point(class_scope:org.apache.accumulo.examples.wikisearch.protobuf.Info)
    private static final org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info();
    }

    public static org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<Info>
        PARSER = new com.google.protobuf.AbstractParser<Info>() {
      @java.lang.Override
      public Info parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new Info(input, extensionRegistry);
      }
    };

    public static com.google.protobuf.Parser<Info> parser() {
      return PARSER;
    }

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

    @java.lang.Override
    public org.apache.accumulo.examples.wikisearch.protobuf.TermWeight.Info getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_accumulo_examples_wikisearch_protobuf_Info_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_accumulo_examples_wikisearch_protobuf_Info_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\020TermWeight.proto\0220org.apache.accumulo." +
      "examples.wikisearch.protobuf\";\n\004Info\022\037\n\027" +
      "normalizedTermFrequency\030\001 \002(\002\022\022\n\nwordOff" +
      "set\030\002 \003(\rB4\n0org.apache.accumulo.example" +
      "s.wikisearch.protobufH\001"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        });
    internal_static_org_apache_accumulo_examples_wikisearch_protobuf_Info_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_org_apache_accumulo_examples_wikisearch_protobuf_Info_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_accumulo_examples_wikisearch_protobuf_Info_descriptor,
        new java.lang.String[] { "NormalizedTermFrequency", "WordOffset", });
  }

  // @@protoc_insertion_point(outer_class_scope)
}
