/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: org/waveprotocol/box/search/search.proto

package org.waveprotocol.box.search;

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

    // required string query = 1;
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The query to execute.
     * </pre>
     */
    boolean hasQuery();
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The query to execute.
     * </pre>
     */
    java.lang.String getQuery();
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The query to execute.
     * </pre>
     */
    com.google.protobuf.ByteString
        getQueryBytes();

    // required int32 index = 2;
    /**
     * <code>required int32 index = 2;</code>
     *
     * <pre>
     * The index from which to return results.
     * </pre>
     */
    boolean hasIndex();
    /**
     * <code>required int32 index = 2;</code>
     *
     * <pre>
     * The index from which to return results.
     * </pre>
     */
    int getIndex();

    // required int32 numResults = 3;
    /**
     * <code>required int32 numResults = 3;</code>
     *
     * <pre>
     * The number of results to return.
     * </pre>
     */
    boolean hasNumResults();
    /**
     * <code>required int32 numResults = 3;</code>
     *
     * <pre>
     * The number of results to return.
     * </pre>
     */
    int getNumResults();
  }
  /**
   * Protobuf type {@code search.SearchRequest}
   */
  public static final class SearchRequest extends
      com.google.protobuf.GeneratedMessage
      implements SearchRequestOrBuilder {
    // Use SearchRequest.newBuilder() to construct.
    private SearchRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SearchRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

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

    public SearchRequest getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SearchRequest(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              query_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              index_ = input.readInt32();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              numResults_ = input.readInt32();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchRequest_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchRequest_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.waveprotocol.box.search.SearchProto.SearchRequest.class, org.waveprotocol.box.search.SearchProto.SearchRequest.Builder.class);
    }

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

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

    private int bitField0_;
    // required string query = 1;
    public static final int QUERY_FIELD_NUMBER = 1;
    private java.lang.Object query_;
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The query to execute.
     * </pre>
     */
    public boolean hasQuery() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The query to execute.
     * </pre>
     */
    public java.lang.String getQuery() {
      java.lang.Object ref = query_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          query_ = s;
        }
        return s;
      }
    }
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The query to execute.
     * </pre>
     */
    public com.google.protobuf.ByteString
        getQueryBytes() {
      java.lang.Object ref = query_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        query_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // required int32 index = 2;
    public static final int INDEX_FIELD_NUMBER = 2;
    private int index_;
    /**
     * <code>required int32 index = 2;</code>
     *
     * <pre>
     * The index from which to return results.
     * </pre>
     */
    public boolean hasIndex() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int32 index = 2;</code>
     *
     * <pre>
     * The index from which to return results.
     * </pre>
     */
    public int getIndex() {
      return index_;
    }

    // required int32 numResults = 3;
    public static final int NUMRESULTS_FIELD_NUMBER = 3;
    private int numResults_;
    /**
     * <code>required int32 numResults = 3;</code>
     *
     * <pre>
     * The number of results to return.
     * </pre>
     */
    public boolean hasNumResults() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required int32 numResults = 3;</code>
     *
     * <pre>
     * The number of results to return.
     * </pre>
     */
    public int getNumResults() {
      return numResults_;
    }

    private void initFields() {
      query_ = "";
      index_ = 0;
      numResults_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasQuery()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasIndex()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasNumResults()) {
        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, getQueryBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, index_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt32(3, numResults_);
      }
      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, getQueryBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, index_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, numResults_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

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

    public static org.waveprotocol.box.search.SearchProto.SearchRequest parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchRequest parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchRequest parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchRequest parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchRequest parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchRequest parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchRequest parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchRequest parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchRequest parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchRequest parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.waveprotocol.box.search.SearchProto.SearchRequest prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code search.SearchRequest}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.waveprotocol.box.search.SearchProto.SearchRequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchRequest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchRequest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.waveprotocol.box.search.SearchProto.SearchRequest.class, org.waveprotocol.box.search.SearchProto.SearchRequest.Builder.class);
      }

      // Construct using org.waveprotocol.box.search.SearchProto.SearchRequest.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

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

      public Builder clear() {
        super.clear();
        query_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        index_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        numResults_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

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

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchRequest_descriptor;
      }

      public org.waveprotocol.box.search.SearchProto.SearchRequest getDefaultInstanceForType() {
        return org.waveprotocol.box.search.SearchProto.SearchRequest.getDefaultInstance();
      }

      public org.waveprotocol.box.search.SearchProto.SearchRequest build() {
        org.waveprotocol.box.search.SearchProto.SearchRequest result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.waveprotocol.box.search.SearchProto.SearchRequest buildPartial() {
        org.waveprotocol.box.search.SearchProto.SearchRequest result = new org.waveprotocol.box.search.SearchProto.SearchRequest(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.query_ = query_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.index_ = index_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.numResults_ = numResults_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.waveprotocol.box.search.SearchProto.SearchRequest) {
          return mergeFrom((org.waveprotocol.box.search.SearchProto.SearchRequest)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.waveprotocol.box.search.SearchProto.SearchRequest other) {
        if (other == org.waveprotocol.box.search.SearchProto.SearchRequest.getDefaultInstance()) return this;
        if (other.hasQuery()) {
          bitField0_ |= 0x00000001;
          query_ = other.query_;
          onChanged();
        }
        if (other.hasIndex()) {
          setIndex(other.getIndex());
        }
        if (other.hasNumResults()) {
          setNumResults(other.getNumResults());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasQuery()) {
          
          return false;
        }
        if (!hasIndex()) {
          
          return false;
        }
        if (!hasNumResults()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.waveprotocol.box.search.SearchProto.SearchRequest parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.waveprotocol.box.search.SearchProto.SearchRequest) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required string query = 1;
      private java.lang.Object query_ = "";
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The query to execute.
       * </pre>
       */
      public boolean hasQuery() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The query to execute.
       * </pre>
       */
      public java.lang.String getQuery() {
        java.lang.Object ref = query_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          query_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The query to execute.
       * </pre>
       */
      public com.google.protobuf.ByteString
          getQueryBytes() {
        java.lang.Object ref = query_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          query_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The query to execute.
       * </pre>
       */
      public Builder setQuery(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        query_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The query to execute.
       * </pre>
       */
      public Builder clearQuery() {
        bitField0_ = (bitField0_ & ~0x00000001);
        query_ = getDefaultInstance().getQuery();
        onChanged();
        return this;
      }
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The query to execute.
       * </pre>
       */
      public Builder setQueryBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        query_ = value;
        onChanged();
        return this;
      }

      // required int32 index = 2;
      private int index_ ;
      /**
       * <code>required int32 index = 2;</code>
       *
       * <pre>
       * The index from which to return results.
       * </pre>
       */
      public boolean hasIndex() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int32 index = 2;</code>
       *
       * <pre>
       * The index from which to return results.
       * </pre>
       */
      public int getIndex() {
        return index_;
      }
      /**
       * <code>required int32 index = 2;</code>
       *
       * <pre>
       * The index from which to return results.
       * </pre>
       */
      public Builder setIndex(int value) {
        bitField0_ |= 0x00000002;
        index_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 index = 2;</code>
       *
       * <pre>
       * The index from which to return results.
       * </pre>
       */
      public Builder clearIndex() {
        bitField0_ = (bitField0_ & ~0x00000002);
        index_ = 0;
        onChanged();
        return this;
      }

      // required int32 numResults = 3;
      private int numResults_ ;
      /**
       * <code>required int32 numResults = 3;</code>
       *
       * <pre>
       * The number of results to return.
       * </pre>
       */
      public boolean hasNumResults() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required int32 numResults = 3;</code>
       *
       * <pre>
       * The number of results to return.
       * </pre>
       */
      public int getNumResults() {
        return numResults_;
      }
      /**
       * <code>required int32 numResults = 3;</code>
       *
       * <pre>
       * The number of results to return.
       * </pre>
       */
      public Builder setNumResults(int value) {
        bitField0_ |= 0x00000004;
        numResults_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 numResults = 3;</code>
       *
       * <pre>
       * The number of results to return.
       * </pre>
       */
      public Builder clearNumResults() {
        bitField0_ = (bitField0_ & ~0x00000004);
        numResults_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:search.SearchRequest)
    }

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

    // @@protoc_insertion_point(class_scope:search.SearchRequest)
  }

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

    // required string query = 1;
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The search query.
     * </pre>
     */
    boolean hasQuery();
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The search query.
     * </pre>
     */
    java.lang.String getQuery();
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The search query.
     * </pre>
     */
    com.google.protobuf.ByteString
        getQueryBytes();

    // required int32 totalResults = 2;
    /**
     * <code>required int32 totalResults = 2;</code>
     *
     * <pre>
     * The total number of results to the query (not necessarily all returned).
     * </pre>
     */
    boolean hasTotalResults();
    /**
     * <code>required int32 totalResults = 2;</code>
     *
     * <pre>
     * The total number of results to the query (not necessarily all returned).
     * </pre>
     */
    int getTotalResults();

    // repeated .search.SearchResponse.Digest digests = 3;
    /**
     * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
     *
     * <pre>
     * A list of digests, representing the segment [index, index + result_count] 
     * from the query parameters.
     * </pre>
     */
    java.util.List<org.waveprotocol.box.search.SearchProto.SearchResponse.Digest> 
        getDigestsList();
    /**
     * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
     *
     * <pre>
     * A list of digests, representing the segment [index, index + result_count] 
     * from the query parameters.
     * </pre>
     */
    org.waveprotocol.box.search.SearchProto.SearchResponse.Digest getDigests(int index);
    /**
     * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
     *
     * <pre>
     * A list of digests, representing the segment [index, index + result_count] 
     * from the query parameters.
     * </pre>
     */
    int getDigestsCount();
    /**
     * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
     *
     * <pre>
     * A list of digests, representing the segment [index, index + result_count] 
     * from the query parameters.
     * </pre>
     */
    java.util.List<? extends org.waveprotocol.box.search.SearchProto.SearchResponse.DigestOrBuilder> 
        getDigestsOrBuilderList();
    /**
     * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
     *
     * <pre>
     * A list of digests, representing the segment [index, index + result_count] 
     * from the query parameters.
     * </pre>
     */
    org.waveprotocol.box.search.SearchProto.SearchResponse.DigestOrBuilder getDigestsOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code search.SearchResponse}
   */
  public static final class SearchResponse extends
      com.google.protobuf.GeneratedMessage
      implements SearchResponseOrBuilder {
    // Use SearchResponse.newBuilder() to construct.
    private SearchResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SearchResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

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

    public SearchResponse getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SearchResponse(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              bitField0_ |= 0x00000001;
              query_ = input.readBytes();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              totalResults_ = input.readInt32();
              break;
            }
            case 26: {
              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
                digests_ = new java.util.ArrayList<org.waveprotocol.box.search.SearchProto.SearchResponse.Digest>();
                mutable_bitField0_ |= 0x00000004;
              }
              digests_.add(input.readMessage(org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
          digests_ = java.util.Collections.unmodifiableList(digests_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchResponse_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchResponse_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.waveprotocol.box.search.SearchProto.SearchResponse.class, org.waveprotocol.box.search.SearchProto.SearchResponse.Builder.class);
    }

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

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

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

      // required string title = 1;
      /**
       * <code>required string title = 1;</code>
       *
       * <pre>
       * The wave title.
       * </pre>
       */
      boolean hasTitle();
      /**
       * <code>required string title = 1;</code>
       *
       * <pre>
       * The wave title.
       * </pre>
       */
      java.lang.String getTitle();
      /**
       * <code>required string title = 1;</code>
       *
       * <pre>
       * The wave title.
       * </pre>
       */
      com.google.protobuf.ByteString
          getTitleBytes();

      // required string snippet = 2;
      /**
       * <code>required string snippet = 2;</code>
       *
       * <pre>
       * The text snippet.
       * </pre>
       */
      boolean hasSnippet();
      /**
       * <code>required string snippet = 2;</code>
       *
       * <pre>
       * The text snippet.
       * </pre>
       */
      java.lang.String getSnippet();
      /**
       * <code>required string snippet = 2;</code>
       *
       * <pre>
       * The text snippet.
       * </pre>
       */
      com.google.protobuf.ByteString
          getSnippetBytes();

      // required string waveId = 3;
      /**
       * <code>required string waveId = 3;</code>
       *
       * <pre>
       * Serialized wave id
       * </pre>
       */
      boolean hasWaveId();
      /**
       * <code>required string waveId = 3;</code>
       *
       * <pre>
       * Serialized wave id
       * </pre>
       */
      java.lang.String getWaveId();
      /**
       * <code>required string waveId = 3;</code>
       *
       * <pre>
       * Serialized wave id
       * </pre>
       */
      com.google.protobuf.ByteString
          getWaveIdBytes();

      // required int64 lastModified = 4;
      /**
       * <code>required int64 lastModified = 4;</code>
       *
       * <pre>
       * Last modified time of the wave.
       * </pre>
       */
      boolean hasLastModified();
      /**
       * <code>required int64 lastModified = 4;</code>
       *
       * <pre>
       * Last modified time of the wave.
       * </pre>
       */
      long getLastModified();

      // required int32 unreadCount = 5;
      /**
       * <code>required int32 unreadCount = 5;</code>
       *
       * <pre>
       * Unread count for the user.
       * </pre>
       */
      boolean hasUnreadCount();
      /**
       * <code>required int32 unreadCount = 5;</code>
       *
       * <pre>
       * Unread count for the user.
       * </pre>
       */
      int getUnreadCount();

      // required int32 blipCount = 6;
      /**
       * <code>required int32 blipCount = 6;</code>
       *
       * <pre>
       * Number of blips in the wave.
       * </pre>
       */
      boolean hasBlipCount();
      /**
       * <code>required int32 blipCount = 6;</code>
       *
       * <pre>
       * Number of blips in the wave.
       * </pre>
       */
      int getBlipCount();

      // repeated string participants = 7;
      /**
       * <code>repeated string participants = 7;</code>
       *
       * <pre>
       * Wave participants.
       * </pre>
       */
      java.util.List<java.lang.String>
      getParticipantsList();
      /**
       * <code>repeated string participants = 7;</code>
       *
       * <pre>
       * Wave participants.
       * </pre>
       */
      int getParticipantsCount();
      /**
       * <code>repeated string participants = 7;</code>
       *
       * <pre>
       * Wave participants.
       * </pre>
       */
      java.lang.String getParticipants(int index);
      /**
       * <code>repeated string participants = 7;</code>
       *
       * <pre>
       * Wave participants.
       * </pre>
       */
      com.google.protobuf.ByteString
          getParticipantsBytes(int index);

      // required string author = 8;
      /**
       * <code>required string author = 8;</code>
       *
       * <pre>
       * The wave author.
       * </pre>
       */
      boolean hasAuthor();
      /**
       * <code>required string author = 8;</code>
       *
       * <pre>
       * The wave author.
       * </pre>
       */
      java.lang.String getAuthor();
      /**
       * <code>required string author = 8;</code>
       *
       * <pre>
       * The wave author.
       * </pre>
       */
      com.google.protobuf.ByteString
          getAuthorBytes();
    }
    /**
     * Protobuf type {@code search.SearchResponse.Digest}
     *
     * <pre>
     * The wave list digest.
     * </pre>
     */
    public static final class Digest extends
        com.google.protobuf.GeneratedMessage
        implements DigestOrBuilder {
      // Use Digest.newBuilder() to construct.
      private Digest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
        super(builder);
        this.unknownFields = builder.getUnknownFields();
      }
      private Digest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

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

      public Digest getDefaultInstanceForType() {
        return defaultInstance;
      }

      private final com.google.protobuf.UnknownFieldSet unknownFields;
      @java.lang.Override
      public final com.google.protobuf.UnknownFieldSet
          getUnknownFields() {
        return this.unknownFields;
      }
      private Digest(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        initFields();
        int mutable_bitField0_ = 0;
        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
            com.google.protobuf.UnknownFieldSet.newBuilder();
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              default: {
                if (!parseUnknownField(input, unknownFields,
                                       extensionRegistry, tag)) {
                  done = true;
                }
                break;
              }
              case 10: {
                bitField0_ |= 0x00000001;
                title_ = input.readBytes();
                break;
              }
              case 18: {
                bitField0_ |= 0x00000002;
                snippet_ = input.readBytes();
                break;
              }
              case 26: {
                bitField0_ |= 0x00000004;
                waveId_ = input.readBytes();
                break;
              }
              case 32: {
                bitField0_ |= 0x00000008;
                lastModified_ = input.readInt64();
                break;
              }
              case 40: {
                bitField0_ |= 0x00000010;
                unreadCount_ = input.readInt32();
                break;
              }
              case 48: {
                bitField0_ |= 0x00000020;
                blipCount_ = input.readInt32();
                break;
              }
              case 58: {
                if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
                  participants_ = new com.google.protobuf.LazyStringArrayList();
                  mutable_bitField0_ |= 0x00000040;
                }
                participants_.add(input.readBytes());
                break;
              }
              case 66: {
                bitField0_ |= 0x00000040;
                author_ = input.readBytes();
                break;
              }
            }
          }
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(this);
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(
              e.getMessage()).setUnfinishedMessage(this);
        } finally {
          if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
            participants_ = new com.google.protobuf.UnmodifiableLazyStringList(participants_);
          }
          this.unknownFields = unknownFields.build();
          makeExtensionsImmutable();
        }
      }
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchResponse_Digest_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchResponse_Digest_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.class, org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder.class);
      }

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

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

      private int bitField0_;
      // required string title = 1;
      public static final int TITLE_FIELD_NUMBER = 1;
      private java.lang.Object title_;
      /**
       * <code>required string title = 1;</code>
       *
       * <pre>
       * The wave title.
       * </pre>
       */
      public boolean hasTitle() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required string title = 1;</code>
       *
       * <pre>
       * The wave title.
       * </pre>
       */
      public java.lang.String getTitle() {
        java.lang.Object ref = title_;
        if (ref instanceof java.lang.String) {
          return (java.lang.String) ref;
        } else {
          com.google.protobuf.ByteString bs = 
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            title_ = s;
          }
          return s;
        }
      }
      /**
       * <code>required string title = 1;</code>
       *
       * <pre>
       * The wave title.
       * </pre>
       */
      public com.google.protobuf.ByteString
          getTitleBytes() {
        java.lang.Object ref = title_;
        if (ref instanceof java.lang.String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          title_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }

      // required string snippet = 2;
      public static final int SNIPPET_FIELD_NUMBER = 2;
      private java.lang.Object snippet_;
      /**
       * <code>required string snippet = 2;</code>
       *
       * <pre>
       * The text snippet.
       * </pre>
       */
      public boolean hasSnippet() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required string snippet = 2;</code>
       *
       * <pre>
       * The text snippet.
       * </pre>
       */
      public java.lang.String getSnippet() {
        java.lang.Object ref = snippet_;
        if (ref instanceof java.lang.String) {
          return (java.lang.String) ref;
        } else {
          com.google.protobuf.ByteString bs = 
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            snippet_ = s;
          }
          return s;
        }
      }
      /**
       * <code>required string snippet = 2;</code>
       *
       * <pre>
       * The text snippet.
       * </pre>
       */
      public com.google.protobuf.ByteString
          getSnippetBytes() {
        java.lang.Object ref = snippet_;
        if (ref instanceof java.lang.String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          snippet_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }

      // required string waveId = 3;
      public static final int WAVEID_FIELD_NUMBER = 3;
      private java.lang.Object waveId_;
      /**
       * <code>required string waveId = 3;</code>
       *
       * <pre>
       * Serialized wave id
       * </pre>
       */
      public boolean hasWaveId() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required string waveId = 3;</code>
       *
       * <pre>
       * Serialized wave id
       * </pre>
       */
      public java.lang.String getWaveId() {
        java.lang.Object ref = waveId_;
        if (ref instanceof java.lang.String) {
          return (java.lang.String) ref;
        } else {
          com.google.protobuf.ByteString bs = 
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            waveId_ = s;
          }
          return s;
        }
      }
      /**
       * <code>required string waveId = 3;</code>
       *
       * <pre>
       * Serialized wave id
       * </pre>
       */
      public com.google.protobuf.ByteString
          getWaveIdBytes() {
        java.lang.Object ref = waveId_;
        if (ref instanceof java.lang.String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          waveId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }

      // required int64 lastModified = 4;
      public static final int LASTMODIFIED_FIELD_NUMBER = 4;
      private long lastModified_;
      /**
       * <code>required int64 lastModified = 4;</code>
       *
       * <pre>
       * Last modified time of the wave.
       * </pre>
       */
      public boolean hasLastModified() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required int64 lastModified = 4;</code>
       *
       * <pre>
       * Last modified time of the wave.
       * </pre>
       */
      public long getLastModified() {
        return lastModified_;
      }

      // required int32 unreadCount = 5;
      public static final int UNREADCOUNT_FIELD_NUMBER = 5;
      private int unreadCount_;
      /**
       * <code>required int32 unreadCount = 5;</code>
       *
       * <pre>
       * Unread count for the user.
       * </pre>
       */
      public boolean hasUnreadCount() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>required int32 unreadCount = 5;</code>
       *
       * <pre>
       * Unread count for the user.
       * </pre>
       */
      public int getUnreadCount() {
        return unreadCount_;
      }

      // required int32 blipCount = 6;
      public static final int BLIPCOUNT_FIELD_NUMBER = 6;
      private int blipCount_;
      /**
       * <code>required int32 blipCount = 6;</code>
       *
       * <pre>
       * Number of blips in the wave.
       * </pre>
       */
      public boolean hasBlipCount() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>required int32 blipCount = 6;</code>
       *
       * <pre>
       * Number of blips in the wave.
       * </pre>
       */
      public int getBlipCount() {
        return blipCount_;
      }

      // repeated string participants = 7;
      public static final int PARTICIPANTS_FIELD_NUMBER = 7;
      private com.google.protobuf.LazyStringList participants_;
      /**
       * <code>repeated string participants = 7;</code>
       *
       * <pre>
       * Wave participants.
       * </pre>
       */
      public java.util.List<java.lang.String>
          getParticipantsList() {
        return participants_;
      }
      /**
       * <code>repeated string participants = 7;</code>
       *
       * <pre>
       * Wave participants.
       * </pre>
       */
      public int getParticipantsCount() {
        return participants_.size();
      }
      /**
       * <code>repeated string participants = 7;</code>
       *
       * <pre>
       * Wave participants.
       * </pre>
       */
      public java.lang.String getParticipants(int index) {
        return participants_.get(index);
      }
      /**
       * <code>repeated string participants = 7;</code>
       *
       * <pre>
       * Wave participants.
       * </pre>
       */
      public com.google.protobuf.ByteString
          getParticipantsBytes(int index) {
        return participants_.getByteString(index);
      }

      // required string author = 8;
      public static final int AUTHOR_FIELD_NUMBER = 8;
      private java.lang.Object author_;
      /**
       * <code>required string author = 8;</code>
       *
       * <pre>
       * The wave author.
       * </pre>
       */
      public boolean hasAuthor() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      /**
       * <code>required string author = 8;</code>
       *
       * <pre>
       * The wave author.
       * </pre>
       */
      public java.lang.String getAuthor() {
        java.lang.Object ref = author_;
        if (ref instanceof java.lang.String) {
          return (java.lang.String) ref;
        } else {
          com.google.protobuf.ByteString bs = 
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            author_ = s;
          }
          return s;
        }
      }
      /**
       * <code>required string author = 8;</code>
       *
       * <pre>
       * The wave author.
       * </pre>
       */
      public com.google.protobuf.ByteString
          getAuthorBytes() {
        java.lang.Object ref = author_;
        if (ref instanceof java.lang.String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          author_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }

      private void initFields() {
        title_ = "";
        snippet_ = "";
        waveId_ = "";
        lastModified_ = 0L;
        unreadCount_ = 0;
        blipCount_ = 0;
        participants_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        author_ = "";
      }
      private byte memoizedIsInitialized = -1;
      public final boolean isInitialized() {
        byte isInitialized = memoizedIsInitialized;
        if (isInitialized != -1) return isInitialized == 1;

        if (!hasTitle()) {
          memoizedIsInitialized = 0;
          return false;
        }
        if (!hasSnippet()) {
          memoizedIsInitialized = 0;
          return false;
        }
        if (!hasWaveId()) {
          memoizedIsInitialized = 0;
          return false;
        }
        if (!hasLastModified()) {
          memoizedIsInitialized = 0;
          return false;
        }
        if (!hasUnreadCount()) {
          memoizedIsInitialized = 0;
          return false;
        }
        if (!hasBlipCount()) {
          memoizedIsInitialized = 0;
          return false;
        }
        if (!hasAuthor()) {
          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, getTitleBytes());
        }
        if (((bitField0_ & 0x00000002) == 0x00000002)) {
          output.writeBytes(2, getSnippetBytes());
        }
        if (((bitField0_ & 0x00000004) == 0x00000004)) {
          output.writeBytes(3, getWaveIdBytes());
        }
        if (((bitField0_ & 0x00000008) == 0x00000008)) {
          output.writeInt64(4, lastModified_);
        }
        if (((bitField0_ & 0x00000010) == 0x00000010)) {
          output.writeInt32(5, unreadCount_);
        }
        if (((bitField0_ & 0x00000020) == 0x00000020)) {
          output.writeInt32(6, blipCount_);
        }
        for (int i = 0; i < participants_.size(); i++) {
          output.writeBytes(7, participants_.getByteString(i));
        }
        if (((bitField0_ & 0x00000040) == 0x00000040)) {
          output.writeBytes(8, getAuthorBytes());
        }
        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, getTitleBytes());
        }
        if (((bitField0_ & 0x00000002) == 0x00000002)) {
          size += com.google.protobuf.CodedOutputStream
            .computeBytesSize(2, getSnippetBytes());
        }
        if (((bitField0_ & 0x00000004) == 0x00000004)) {
          size += com.google.protobuf.CodedOutputStream
            .computeBytesSize(3, getWaveIdBytes());
        }
        if (((bitField0_ & 0x00000008) == 0x00000008)) {
          size += com.google.protobuf.CodedOutputStream
            .computeInt64Size(4, lastModified_);
        }
        if (((bitField0_ & 0x00000010) == 0x00000010)) {
          size += com.google.protobuf.CodedOutputStream
            .computeInt32Size(5, unreadCount_);
        }
        if (((bitField0_ & 0x00000020) == 0x00000020)) {
          size += com.google.protobuf.CodedOutputStream
            .computeInt32Size(6, blipCount_);
        }
        {
          int dataSize = 0;
          for (int i = 0; i < participants_.size(); i++) {
            dataSize += com.google.protobuf.CodedOutputStream
              .computeBytesSizeNoTag(participants_.getByteString(i));
          }
          size += dataSize;
          size += 1 * getParticipantsList().size();
        }
        if (((bitField0_ & 0x00000040) == 0x00000040)) {
          size += com.google.protobuf.CodedOutputStream
            .computeBytesSize(8, getAuthorBytes());
        }
        size += getUnknownFields().getSerializedSize();
        memoizedSerializedSize = size;
        return size;
      }

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

      public static org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parseFrom(
          com.google.protobuf.ByteString data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data);
      }
      public static org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parseFrom(
          com.google.protobuf.ByteString data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data, extensionRegistry);
      }
      public static org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parseFrom(byte[] data)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data);
      }
      public static org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parseFrom(
          byte[] data,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return PARSER.parseFrom(data, extensionRegistry);
      }
      public static org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parseFrom(java.io.InputStream input)
          throws java.io.IOException {
        return PARSER.parseFrom(input);
      }
      public static org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parseFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return PARSER.parseFrom(input, extensionRegistry);
      }
      public static org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parseDelimitedFrom(java.io.InputStream input)
          throws java.io.IOException {
        return PARSER.parseDelimitedFrom(input);
      }
      public static org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parseDelimitedFrom(
          java.io.InputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return PARSER.parseDelimitedFrom(input, extensionRegistry);
      }
      public static org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parseFrom(
          com.google.protobuf.CodedInputStream input)
          throws java.io.IOException {
        return PARSER.parseFrom(input);
      }
      public static org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parseFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        return PARSER.parseFrom(input, extensionRegistry);
      }

      public static Builder newBuilder() { return Builder.create(); }
      public Builder newBuilderForType() { return newBuilder(); }
      public static Builder newBuilder(org.waveprotocol.box.search.SearchProto.SearchResponse.Digest prototype) {
        return newBuilder().mergeFrom(prototype);
      }
      public Builder toBuilder() { return newBuilder(this); }

      @java.lang.Override
      protected Builder newBuilderForType(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        Builder builder = new Builder(parent);
        return builder;
      }
      /**
       * Protobuf type {@code search.SearchResponse.Digest}
       *
       * <pre>
       * The wave list digest.
       * </pre>
       */
      public static final class Builder extends
          com.google.protobuf.GeneratedMessage.Builder<Builder>
         implements org.waveprotocol.box.search.SearchProto.SearchResponse.DigestOrBuilder {
        public static final com.google.protobuf.Descriptors.Descriptor
            getDescriptor() {
          return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchResponse_Digest_descriptor;
        }

        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchResponse_Digest_fieldAccessorTable
              .ensureFieldAccessorsInitialized(
                  org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.class, org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder.class);
        }

        // Construct using org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.newBuilder()
        private Builder() {
          maybeForceBuilderInitialization();
        }

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

        public Builder clear() {
          super.clear();
          title_ = "";
          bitField0_ = (bitField0_ & ~0x00000001);
          snippet_ = "";
          bitField0_ = (bitField0_ & ~0x00000002);
          waveId_ = "";
          bitField0_ = (bitField0_ & ~0x00000004);
          lastModified_ = 0L;
          bitField0_ = (bitField0_ & ~0x00000008);
          unreadCount_ = 0;
          bitField0_ = (bitField0_ & ~0x00000010);
          blipCount_ = 0;
          bitField0_ = (bitField0_ & ~0x00000020);
          participants_ = com.google.protobuf.LazyStringArrayList.EMPTY;
          bitField0_ = (bitField0_ & ~0x00000040);
          author_ = "";
          bitField0_ = (bitField0_ & ~0x00000080);
          return this;
        }

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

        public com.google.protobuf.Descriptors.Descriptor
            getDescriptorForType() {
          return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchResponse_Digest_descriptor;
        }

        public org.waveprotocol.box.search.SearchProto.SearchResponse.Digest getDefaultInstanceForType() {
          return org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.getDefaultInstance();
        }

        public org.waveprotocol.box.search.SearchProto.SearchResponse.Digest build() {
          org.waveprotocol.box.search.SearchProto.SearchResponse.Digest result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(result);
          }
          return result;
        }

        public org.waveprotocol.box.search.SearchProto.SearchResponse.Digest buildPartial() {
          org.waveprotocol.box.search.SearchProto.SearchResponse.Digest result = new org.waveprotocol.box.search.SearchProto.SearchResponse.Digest(this);
          int from_bitField0_ = bitField0_;
          int to_bitField0_ = 0;
          if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
            to_bitField0_ |= 0x00000001;
          }
          result.title_ = title_;
          if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
            to_bitField0_ |= 0x00000002;
          }
          result.snippet_ = snippet_;
          if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
            to_bitField0_ |= 0x00000004;
          }
          result.waveId_ = waveId_;
          if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
            to_bitField0_ |= 0x00000008;
          }
          result.lastModified_ = lastModified_;
          if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
            to_bitField0_ |= 0x00000010;
          }
          result.unreadCount_ = unreadCount_;
          if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
            to_bitField0_ |= 0x00000020;
          }
          result.blipCount_ = blipCount_;
          if (((bitField0_ & 0x00000040) == 0x00000040)) {
            participants_ = new com.google.protobuf.UnmodifiableLazyStringList(
                participants_);
            bitField0_ = (bitField0_ & ~0x00000040);
          }
          result.participants_ = participants_;
          if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
            to_bitField0_ |= 0x00000040;
          }
          result.author_ = author_;
          result.bitField0_ = to_bitField0_;
          onBuilt();
          return result;
        }

        public Builder mergeFrom(com.google.protobuf.Message other) {
          if (other instanceof org.waveprotocol.box.search.SearchProto.SearchResponse.Digest) {
            return mergeFrom((org.waveprotocol.box.search.SearchProto.SearchResponse.Digest)other);
          } else {
            super.mergeFrom(other);
            return this;
          }
        }

        public Builder mergeFrom(org.waveprotocol.box.search.SearchProto.SearchResponse.Digest other) {
          if (other == org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.getDefaultInstance()) return this;
          if (other.hasTitle()) {
            bitField0_ |= 0x00000001;
            title_ = other.title_;
            onChanged();
          }
          if (other.hasSnippet()) {
            bitField0_ |= 0x00000002;
            snippet_ = other.snippet_;
            onChanged();
          }
          if (other.hasWaveId()) {
            bitField0_ |= 0x00000004;
            waveId_ = other.waveId_;
            onChanged();
          }
          if (other.hasLastModified()) {
            setLastModified(other.getLastModified());
          }
          if (other.hasUnreadCount()) {
            setUnreadCount(other.getUnreadCount());
          }
          if (other.hasBlipCount()) {
            setBlipCount(other.getBlipCount());
          }
          if (!other.participants_.isEmpty()) {
            if (participants_.isEmpty()) {
              participants_ = other.participants_;
              bitField0_ = (bitField0_ & ~0x00000040);
            } else {
              ensureParticipantsIsMutable();
              participants_.addAll(other.participants_);
            }
            onChanged();
          }
          if (other.hasAuthor()) {
            bitField0_ |= 0x00000080;
            author_ = other.author_;
            onChanged();
          }
          this.mergeUnknownFields(other.getUnknownFields());
          return this;
        }

        public final boolean isInitialized() {
          if (!hasTitle()) {
            
            return false;
          }
          if (!hasSnippet()) {
            
            return false;
          }
          if (!hasWaveId()) {
            
            return false;
          }
          if (!hasLastModified()) {
            
            return false;
          }
          if (!hasUnreadCount()) {
            
            return false;
          }
          if (!hasBlipCount()) {
            
            return false;
          }
          if (!hasAuthor()) {
            
            return false;
          }
          return true;
        }

        public Builder mergeFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws java.io.IOException {
          org.waveprotocol.box.search.SearchProto.SearchResponse.Digest parsedMessage = null;
          try {
            parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            parsedMessage = (org.waveprotocol.box.search.SearchProto.SearchResponse.Digest) e.getUnfinishedMessage();
            throw e;
          } finally {
            if (parsedMessage != null) {
              mergeFrom(parsedMessage);
            }
          }
          return this;
        }
        private int bitField0_;

        // required string title = 1;
        private java.lang.Object title_ = "";
        /**
         * <code>required string title = 1;</code>
         *
         * <pre>
         * The wave title.
         * </pre>
         */
        public boolean hasTitle() {
          return ((bitField0_ & 0x00000001) == 0x00000001);
        }
        /**
         * <code>required string title = 1;</code>
         *
         * <pre>
         * The wave title.
         * </pre>
         */
        public java.lang.String getTitle() {
          java.lang.Object ref = title_;
          if (!(ref instanceof java.lang.String)) {
            java.lang.String s = ((com.google.protobuf.ByteString) ref)
                .toStringUtf8();
            title_ = s;
            return s;
          } else {
            return (java.lang.String) ref;
          }
        }
        /**
         * <code>required string title = 1;</code>
         *
         * <pre>
         * The wave title.
         * </pre>
         */
        public com.google.protobuf.ByteString
            getTitleBytes() {
          java.lang.Object ref = title_;
          if (ref instanceof String) {
            com.google.protobuf.ByteString b = 
                com.google.protobuf.ByteString.copyFromUtf8(
                    (java.lang.String) ref);
            title_ = b;
            return b;
          } else {
            return (com.google.protobuf.ByteString) ref;
          }
        }
        /**
         * <code>required string title = 1;</code>
         *
         * <pre>
         * The wave title.
         * </pre>
         */
        public Builder setTitle(
            java.lang.String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
          title_ = value;
          onChanged();
          return this;
        }
        /**
         * <code>required string title = 1;</code>
         *
         * <pre>
         * The wave title.
         * </pre>
         */
        public Builder clearTitle() {
          bitField0_ = (bitField0_ & ~0x00000001);
          title_ = getDefaultInstance().getTitle();
          onChanged();
          return this;
        }
        /**
         * <code>required string title = 1;</code>
         *
         * <pre>
         * The wave title.
         * </pre>
         */
        public Builder setTitleBytes(
            com.google.protobuf.ByteString value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
          title_ = value;
          onChanged();
          return this;
        }

        // required string snippet = 2;
        private java.lang.Object snippet_ = "";
        /**
         * <code>required string snippet = 2;</code>
         *
         * <pre>
         * The text snippet.
         * </pre>
         */
        public boolean hasSnippet() {
          return ((bitField0_ & 0x00000002) == 0x00000002);
        }
        /**
         * <code>required string snippet = 2;</code>
         *
         * <pre>
         * The text snippet.
         * </pre>
         */
        public java.lang.String getSnippet() {
          java.lang.Object ref = snippet_;
          if (!(ref instanceof java.lang.String)) {
            java.lang.String s = ((com.google.protobuf.ByteString) ref)
                .toStringUtf8();
            snippet_ = s;
            return s;
          } else {
            return (java.lang.String) ref;
          }
        }
        /**
         * <code>required string snippet = 2;</code>
         *
         * <pre>
         * The text snippet.
         * </pre>
         */
        public com.google.protobuf.ByteString
            getSnippetBytes() {
          java.lang.Object ref = snippet_;
          if (ref instanceof String) {
            com.google.protobuf.ByteString b = 
                com.google.protobuf.ByteString.copyFromUtf8(
                    (java.lang.String) ref);
            snippet_ = b;
            return b;
          } else {
            return (com.google.protobuf.ByteString) ref;
          }
        }
        /**
         * <code>required string snippet = 2;</code>
         *
         * <pre>
         * The text snippet.
         * </pre>
         */
        public Builder setSnippet(
            java.lang.String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
          snippet_ = value;
          onChanged();
          return this;
        }
        /**
         * <code>required string snippet = 2;</code>
         *
         * <pre>
         * The text snippet.
         * </pre>
         */
        public Builder clearSnippet() {
          bitField0_ = (bitField0_ & ~0x00000002);
          snippet_ = getDefaultInstance().getSnippet();
          onChanged();
          return this;
        }
        /**
         * <code>required string snippet = 2;</code>
         *
         * <pre>
         * The text snippet.
         * </pre>
         */
        public Builder setSnippetBytes(
            com.google.protobuf.ByteString value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
          snippet_ = value;
          onChanged();
          return this;
        }

        // required string waveId = 3;
        private java.lang.Object waveId_ = "";
        /**
         * <code>required string waveId = 3;</code>
         *
         * <pre>
         * Serialized wave id
         * </pre>
         */
        public boolean hasWaveId() {
          return ((bitField0_ & 0x00000004) == 0x00000004);
        }
        /**
         * <code>required string waveId = 3;</code>
         *
         * <pre>
         * Serialized wave id
         * </pre>
         */
        public java.lang.String getWaveId() {
          java.lang.Object ref = waveId_;
          if (!(ref instanceof java.lang.String)) {
            java.lang.String s = ((com.google.protobuf.ByteString) ref)
                .toStringUtf8();
            waveId_ = s;
            return s;
          } else {
            return (java.lang.String) ref;
          }
        }
        /**
         * <code>required string waveId = 3;</code>
         *
         * <pre>
         * Serialized wave id
         * </pre>
         */
        public com.google.protobuf.ByteString
            getWaveIdBytes() {
          java.lang.Object ref = waveId_;
          if (ref instanceof String) {
            com.google.protobuf.ByteString b = 
                com.google.protobuf.ByteString.copyFromUtf8(
                    (java.lang.String) ref);
            waveId_ = b;
            return b;
          } else {
            return (com.google.protobuf.ByteString) ref;
          }
        }
        /**
         * <code>required string waveId = 3;</code>
         *
         * <pre>
         * Serialized wave id
         * </pre>
         */
        public Builder setWaveId(
            java.lang.String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
          waveId_ = value;
          onChanged();
          return this;
        }
        /**
         * <code>required string waveId = 3;</code>
         *
         * <pre>
         * Serialized wave id
         * </pre>
         */
        public Builder clearWaveId() {
          bitField0_ = (bitField0_ & ~0x00000004);
          waveId_ = getDefaultInstance().getWaveId();
          onChanged();
          return this;
        }
        /**
         * <code>required string waveId = 3;</code>
         *
         * <pre>
         * Serialized wave id
         * </pre>
         */
        public Builder setWaveIdBytes(
            com.google.protobuf.ByteString value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
          waveId_ = value;
          onChanged();
          return this;
        }

        // required int64 lastModified = 4;
        private long lastModified_ ;
        /**
         * <code>required int64 lastModified = 4;</code>
         *
         * <pre>
         * Last modified time of the wave.
         * </pre>
         */
        public boolean hasLastModified() {
          return ((bitField0_ & 0x00000008) == 0x00000008);
        }
        /**
         * <code>required int64 lastModified = 4;</code>
         *
         * <pre>
         * Last modified time of the wave.
         * </pre>
         */
        public long getLastModified() {
          return lastModified_;
        }
        /**
         * <code>required int64 lastModified = 4;</code>
         *
         * <pre>
         * Last modified time of the wave.
         * </pre>
         */
        public Builder setLastModified(long value) {
          bitField0_ |= 0x00000008;
          lastModified_ = value;
          onChanged();
          return this;
        }
        /**
         * <code>required int64 lastModified = 4;</code>
         *
         * <pre>
         * Last modified time of the wave.
         * </pre>
         */
        public Builder clearLastModified() {
          bitField0_ = (bitField0_ & ~0x00000008);
          lastModified_ = 0L;
          onChanged();
          return this;
        }

        // required int32 unreadCount = 5;
        private int unreadCount_ ;
        /**
         * <code>required int32 unreadCount = 5;</code>
         *
         * <pre>
         * Unread count for the user.
         * </pre>
         */
        public boolean hasUnreadCount() {
          return ((bitField0_ & 0x00000010) == 0x00000010);
        }
        /**
         * <code>required int32 unreadCount = 5;</code>
         *
         * <pre>
         * Unread count for the user.
         * </pre>
         */
        public int getUnreadCount() {
          return unreadCount_;
        }
        /**
         * <code>required int32 unreadCount = 5;</code>
         *
         * <pre>
         * Unread count for the user.
         * </pre>
         */
        public Builder setUnreadCount(int value) {
          bitField0_ |= 0x00000010;
          unreadCount_ = value;
          onChanged();
          return this;
        }
        /**
         * <code>required int32 unreadCount = 5;</code>
         *
         * <pre>
         * Unread count for the user.
         * </pre>
         */
        public Builder clearUnreadCount() {
          bitField0_ = (bitField0_ & ~0x00000010);
          unreadCount_ = 0;
          onChanged();
          return this;
        }

        // required int32 blipCount = 6;
        private int blipCount_ ;
        /**
         * <code>required int32 blipCount = 6;</code>
         *
         * <pre>
         * Number of blips in the wave.
         * </pre>
         */
        public boolean hasBlipCount() {
          return ((bitField0_ & 0x00000020) == 0x00000020);
        }
        /**
         * <code>required int32 blipCount = 6;</code>
         *
         * <pre>
         * Number of blips in the wave.
         * </pre>
         */
        public int getBlipCount() {
          return blipCount_;
        }
        /**
         * <code>required int32 blipCount = 6;</code>
         *
         * <pre>
         * Number of blips in the wave.
         * </pre>
         */
        public Builder setBlipCount(int value) {
          bitField0_ |= 0x00000020;
          blipCount_ = value;
          onChanged();
          return this;
        }
        /**
         * <code>required int32 blipCount = 6;</code>
         *
         * <pre>
         * Number of blips in the wave.
         * </pre>
         */
        public Builder clearBlipCount() {
          bitField0_ = (bitField0_ & ~0x00000020);
          blipCount_ = 0;
          onChanged();
          return this;
        }

        // repeated string participants = 7;
        private com.google.protobuf.LazyStringList participants_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        private void ensureParticipantsIsMutable() {
          if (!((bitField0_ & 0x00000040) == 0x00000040)) {
            participants_ = new com.google.protobuf.LazyStringArrayList(participants_);
            bitField0_ |= 0x00000040;
           }
        }
        /**
         * <code>repeated string participants = 7;</code>
         *
         * <pre>
         * Wave participants.
         * </pre>
         */
        public java.util.List<java.lang.String>
            getParticipantsList() {
          return java.util.Collections.unmodifiableList(participants_);
        }
        /**
         * <code>repeated string participants = 7;</code>
         *
         * <pre>
         * Wave participants.
         * </pre>
         */
        public int getParticipantsCount() {
          return participants_.size();
        }
        /**
         * <code>repeated string participants = 7;</code>
         *
         * <pre>
         * Wave participants.
         * </pre>
         */
        public java.lang.String getParticipants(int index) {
          return participants_.get(index);
        }
        /**
         * <code>repeated string participants = 7;</code>
         *
         * <pre>
         * Wave participants.
         * </pre>
         */
        public com.google.protobuf.ByteString
            getParticipantsBytes(int index) {
          return participants_.getByteString(index);
        }
        /**
         * <code>repeated string participants = 7;</code>
         *
         * <pre>
         * Wave participants.
         * </pre>
         */
        public Builder setParticipants(
            int index, java.lang.String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureParticipantsIsMutable();
          participants_.set(index, value);
          onChanged();
          return this;
        }
        /**
         * <code>repeated string participants = 7;</code>
         *
         * <pre>
         * Wave participants.
         * </pre>
         */
        public Builder addParticipants(
            java.lang.String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureParticipantsIsMutable();
          participants_.add(value);
          onChanged();
          return this;
        }
        /**
         * <code>repeated string participants = 7;</code>
         *
         * <pre>
         * Wave participants.
         * </pre>
         */
        public Builder addAllParticipants(
            java.lang.Iterable<java.lang.String> values) {
          ensureParticipantsIsMutable();
          super.addAll(values, participants_);
          onChanged();
          return this;
        }
        /**
         * <code>repeated string participants = 7;</code>
         *
         * <pre>
         * Wave participants.
         * </pre>
         */
        public Builder clearParticipants() {
          participants_ = com.google.protobuf.LazyStringArrayList.EMPTY;
          bitField0_ = (bitField0_ & ~0x00000040);
          onChanged();
          return this;
        }
        /**
         * <code>repeated string participants = 7;</code>
         *
         * <pre>
         * Wave participants.
         * </pre>
         */
        public Builder addParticipantsBytes(
            com.google.protobuf.ByteString value) {
          if (value == null) {
    throw new NullPointerException();
  }
  ensureParticipantsIsMutable();
          participants_.add(value);
          onChanged();
          return this;
        }

        // required string author = 8;
        private java.lang.Object author_ = "";
        /**
         * <code>required string author = 8;</code>
         *
         * <pre>
         * The wave author.
         * </pre>
         */
        public boolean hasAuthor() {
          return ((bitField0_ & 0x00000080) == 0x00000080);
        }
        /**
         * <code>required string author = 8;</code>
         *
         * <pre>
         * The wave author.
         * </pre>
         */
        public java.lang.String getAuthor() {
          java.lang.Object ref = author_;
          if (!(ref instanceof java.lang.String)) {
            java.lang.String s = ((com.google.protobuf.ByteString) ref)
                .toStringUtf8();
            author_ = s;
            return s;
          } else {
            return (java.lang.String) ref;
          }
        }
        /**
         * <code>required string author = 8;</code>
         *
         * <pre>
         * The wave author.
         * </pre>
         */
        public com.google.protobuf.ByteString
            getAuthorBytes() {
          java.lang.Object ref = author_;
          if (ref instanceof String) {
            com.google.protobuf.ByteString b = 
                com.google.protobuf.ByteString.copyFromUtf8(
                    (java.lang.String) ref);
            author_ = b;
            return b;
          } else {
            return (com.google.protobuf.ByteString) ref;
          }
        }
        /**
         * <code>required string author = 8;</code>
         *
         * <pre>
         * The wave author.
         * </pre>
         */
        public Builder setAuthor(
            java.lang.String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000080;
          author_ = value;
          onChanged();
          return this;
        }
        /**
         * <code>required string author = 8;</code>
         *
         * <pre>
         * The wave author.
         * </pre>
         */
        public Builder clearAuthor() {
          bitField0_ = (bitField0_ & ~0x00000080);
          author_ = getDefaultInstance().getAuthor();
          onChanged();
          return this;
        }
        /**
         * <code>required string author = 8;</code>
         *
         * <pre>
         * The wave author.
         * </pre>
         */
        public Builder setAuthorBytes(
            com.google.protobuf.ByteString value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000080;
          author_ = value;
          onChanged();
          return this;
        }

        // @@protoc_insertion_point(builder_scope:search.SearchResponse.Digest)
      }

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

      // @@protoc_insertion_point(class_scope:search.SearchResponse.Digest)
    }

    private int bitField0_;
    // required string query = 1;
    public static final int QUERY_FIELD_NUMBER = 1;
    private java.lang.Object query_;
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The search query.
     * </pre>
     */
    public boolean hasQuery() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The search query.
     * </pre>
     */
    public java.lang.String getQuery() {
      java.lang.Object ref = query_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          query_ = s;
        }
        return s;
      }
    }
    /**
     * <code>required string query = 1;</code>
     *
     * <pre>
     * The search query.
     * </pre>
     */
    public com.google.protobuf.ByteString
        getQueryBytes() {
      java.lang.Object ref = query_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        query_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // required int32 totalResults = 2;
    public static final int TOTALRESULTS_FIELD_NUMBER = 2;
    private int totalResults_;
    /**
     * <code>required int32 totalResults = 2;</code>
     *
     * <pre>
     * The total number of results to the query (not necessarily all returned).
     * </pre>
     */
    public boolean hasTotalResults() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int32 totalResults = 2;</code>
     *
     * <pre>
     * The total number of results to the query (not necessarily all returned).
     * </pre>
     */
    public int getTotalResults() {
      return totalResults_;
    }

    // repeated .search.SearchResponse.Digest digests = 3;
    public static final int DIGESTS_FIELD_NUMBER = 3;
    private java.util.List<org.waveprotocol.box.search.SearchProto.SearchResponse.Digest> digests_;
    /**
     * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
     *
     * <pre>
     * A list of digests, representing the segment [index, index + result_count] 
     * from the query parameters.
     * </pre>
     */
    public java.util.List<org.waveprotocol.box.search.SearchProto.SearchResponse.Digest> getDigestsList() {
      return digests_;
    }
    /**
     * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
     *
     * <pre>
     * A list of digests, representing the segment [index, index + result_count] 
     * from the query parameters.
     * </pre>
     */
    public java.util.List<? extends org.waveprotocol.box.search.SearchProto.SearchResponse.DigestOrBuilder> 
        getDigestsOrBuilderList() {
      return digests_;
    }
    /**
     * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
     *
     * <pre>
     * A list of digests, representing the segment [index, index + result_count] 
     * from the query parameters.
     * </pre>
     */
    public int getDigestsCount() {
      return digests_.size();
    }
    /**
     * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
     *
     * <pre>
     * A list of digests, representing the segment [index, index + result_count] 
     * from the query parameters.
     * </pre>
     */
    public org.waveprotocol.box.search.SearchProto.SearchResponse.Digest getDigests(int index) {
      return digests_.get(index);
    }
    /**
     * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
     *
     * <pre>
     * A list of digests, representing the segment [index, index + result_count] 
     * from the query parameters.
     * </pre>
     */
    public org.waveprotocol.box.search.SearchProto.SearchResponse.DigestOrBuilder getDigestsOrBuilder(
        int index) {
      return digests_.get(index);
    }

    private void initFields() {
      query_ = "";
      totalResults_ = 0;
      digests_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasQuery()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasTotalResults()) {
        memoizedIsInitialized = 0;
        return false;
      }
      for (int i = 0; i < getDigestsCount(); i++) {
        if (!getDigests(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBytes(1, getQueryBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, totalResults_);
      }
      for (int i = 0; i < digests_.size(); i++) {
        output.writeMessage(3, digests_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, getQueryBytes());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, totalResults_);
      }
      for (int i = 0; i < digests_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, digests_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

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

    public static org.waveprotocol.box.search.SearchProto.SearchResponse parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchResponse parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchResponse parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchResponse parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchResponse parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchResponse parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchResponse parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchResponse parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchResponse parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.waveprotocol.box.search.SearchProto.SearchResponse parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.waveprotocol.box.search.SearchProto.SearchResponse prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code search.SearchResponse}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.waveprotocol.box.search.SearchProto.SearchResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchResponse_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchResponse_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.waveprotocol.box.search.SearchProto.SearchResponse.class, org.waveprotocol.box.search.SearchProto.SearchResponse.Builder.class);
      }

      // Construct using org.waveprotocol.box.search.SearchProto.SearchResponse.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

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

      public Builder clear() {
        super.clear();
        query_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        totalResults_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        if (digestsBuilder_ == null) {
          digests_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000004);
        } else {
          digestsBuilder_.clear();
        }
        return this;
      }

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

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.waveprotocol.box.search.SearchProto.internal_static_search_SearchResponse_descriptor;
      }

      public org.waveprotocol.box.search.SearchProto.SearchResponse getDefaultInstanceForType() {
        return org.waveprotocol.box.search.SearchProto.SearchResponse.getDefaultInstance();
      }

      public org.waveprotocol.box.search.SearchProto.SearchResponse build() {
        org.waveprotocol.box.search.SearchProto.SearchResponse result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.waveprotocol.box.search.SearchProto.SearchResponse buildPartial() {
        org.waveprotocol.box.search.SearchProto.SearchResponse result = new org.waveprotocol.box.search.SearchProto.SearchResponse(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.query_ = query_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.totalResults_ = totalResults_;
        if (digestsBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004)) {
            digests_ = java.util.Collections.unmodifiableList(digests_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.digests_ = digests_;
        } else {
          result.digests_ = digestsBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.waveprotocol.box.search.SearchProto.SearchResponse) {
          return mergeFrom((org.waveprotocol.box.search.SearchProto.SearchResponse)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.waveprotocol.box.search.SearchProto.SearchResponse other) {
        if (other == org.waveprotocol.box.search.SearchProto.SearchResponse.getDefaultInstance()) return this;
        if (other.hasQuery()) {
          bitField0_ |= 0x00000001;
          query_ = other.query_;
          onChanged();
        }
        if (other.hasTotalResults()) {
          setTotalResults(other.getTotalResults());
        }
        if (digestsBuilder_ == null) {
          if (!other.digests_.isEmpty()) {
            if (digests_.isEmpty()) {
              digests_ = other.digests_;
              bitField0_ = (bitField0_ & ~0x00000004);
            } else {
              ensureDigestsIsMutable();
              digests_.addAll(other.digests_);
            }
            onChanged();
          }
        } else {
          if (!other.digests_.isEmpty()) {
            if (digestsBuilder_.isEmpty()) {
              digestsBuilder_.dispose();
              digestsBuilder_ = null;
              digests_ = other.digests_;
              bitField0_ = (bitField0_ & ~0x00000004);
              digestsBuilder_ = 
                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getDigestsFieldBuilder() : null;
            } else {
              digestsBuilder_.addAllMessages(other.digests_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasQuery()) {
          
          return false;
        }
        if (!hasTotalResults()) {
          
          return false;
        }
        for (int i = 0; i < getDigestsCount(); i++) {
          if (!getDigests(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.waveprotocol.box.search.SearchProto.SearchResponse parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.waveprotocol.box.search.SearchProto.SearchResponse) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required string query = 1;
      private java.lang.Object query_ = "";
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The search query.
       * </pre>
       */
      public boolean hasQuery() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The search query.
       * </pre>
       */
      public java.lang.String getQuery() {
        java.lang.Object ref = query_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          query_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The search query.
       * </pre>
       */
      public com.google.protobuf.ByteString
          getQueryBytes() {
        java.lang.Object ref = query_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          query_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The search query.
       * </pre>
       */
      public Builder setQuery(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        query_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The search query.
       * </pre>
       */
      public Builder clearQuery() {
        bitField0_ = (bitField0_ & ~0x00000001);
        query_ = getDefaultInstance().getQuery();
        onChanged();
        return this;
      }
      /**
       * <code>required string query = 1;</code>
       *
       * <pre>
       * The search query.
       * </pre>
       */
      public Builder setQueryBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        query_ = value;
        onChanged();
        return this;
      }

      // required int32 totalResults = 2;
      private int totalResults_ ;
      /**
       * <code>required int32 totalResults = 2;</code>
       *
       * <pre>
       * The total number of results to the query (not necessarily all returned).
       * </pre>
       */
      public boolean hasTotalResults() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int32 totalResults = 2;</code>
       *
       * <pre>
       * The total number of results to the query (not necessarily all returned).
       * </pre>
       */
      public int getTotalResults() {
        return totalResults_;
      }
      /**
       * <code>required int32 totalResults = 2;</code>
       *
       * <pre>
       * The total number of results to the query (not necessarily all returned).
       * </pre>
       */
      public Builder setTotalResults(int value) {
        bitField0_ |= 0x00000002;
        totalResults_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 totalResults = 2;</code>
       *
       * <pre>
       * The total number of results to the query (not necessarily all returned).
       * </pre>
       */
      public Builder clearTotalResults() {
        bitField0_ = (bitField0_ & ~0x00000002);
        totalResults_ = 0;
        onChanged();
        return this;
      }

      // repeated .search.SearchResponse.Digest digests = 3;
      private java.util.List<org.waveprotocol.box.search.SearchProto.SearchResponse.Digest> digests_ =
        java.util.Collections.emptyList();
      private void ensureDigestsIsMutable() {
        if (!((bitField0_ & 0x00000004) == 0x00000004)) {
          digests_ = new java.util.ArrayList<org.waveprotocol.box.search.SearchProto.SearchResponse.Digest>(digests_);
          bitField0_ |= 0x00000004;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilder<
          org.waveprotocol.box.search.SearchProto.SearchResponse.Digest, org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder, org.waveprotocol.box.search.SearchProto.SearchResponse.DigestOrBuilder> digestsBuilder_;

      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public java.util.List<org.waveprotocol.box.search.SearchProto.SearchResponse.Digest> getDigestsList() {
        if (digestsBuilder_ == null) {
          return java.util.Collections.unmodifiableList(digests_);
        } else {
          return digestsBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public int getDigestsCount() {
        if (digestsBuilder_ == null) {
          return digests_.size();
        } else {
          return digestsBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public org.waveprotocol.box.search.SearchProto.SearchResponse.Digest getDigests(int index) {
        if (digestsBuilder_ == null) {
          return digests_.get(index);
        } else {
          return digestsBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public Builder setDigests(
          int index, org.waveprotocol.box.search.SearchProto.SearchResponse.Digest value) {
        if (digestsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDigestsIsMutable();
          digests_.set(index, value);
          onChanged();
        } else {
          digestsBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public Builder setDigests(
          int index, org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder builderForValue) {
        if (digestsBuilder_ == null) {
          ensureDigestsIsMutable();
          digests_.set(index, builderForValue.build());
          onChanged();
        } else {
          digestsBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public Builder addDigests(org.waveprotocol.box.search.SearchProto.SearchResponse.Digest value) {
        if (digestsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDigestsIsMutable();
          digests_.add(value);
          onChanged();
        } else {
          digestsBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public Builder addDigests(
          int index, org.waveprotocol.box.search.SearchProto.SearchResponse.Digest value) {
        if (digestsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDigestsIsMutable();
          digests_.add(index, value);
          onChanged();
        } else {
          digestsBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public Builder addDigests(
          org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder builderForValue) {
        if (digestsBuilder_ == null) {
          ensureDigestsIsMutable();
          digests_.add(builderForValue.build());
          onChanged();
        } else {
          digestsBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public Builder addDigests(
          int index, org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder builderForValue) {
        if (digestsBuilder_ == null) {
          ensureDigestsIsMutable();
          digests_.add(index, builderForValue.build());
          onChanged();
        } else {
          digestsBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public Builder addAllDigests(
          java.lang.Iterable<? extends org.waveprotocol.box.search.SearchProto.SearchResponse.Digest> values) {
        if (digestsBuilder_ == null) {
          ensureDigestsIsMutable();
          super.addAll(values, digests_);
          onChanged();
        } else {
          digestsBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public Builder clearDigests() {
        if (digestsBuilder_ == null) {
          digests_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000004);
          onChanged();
        } else {
          digestsBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public Builder removeDigests(int index) {
        if (digestsBuilder_ == null) {
          ensureDigestsIsMutable();
          digests_.remove(index);
          onChanged();
        } else {
          digestsBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder getDigestsBuilder(
          int index) {
        return getDigestsFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public org.waveprotocol.box.search.SearchProto.SearchResponse.DigestOrBuilder getDigestsOrBuilder(
          int index) {
        if (digestsBuilder_ == null) {
          return digests_.get(index);  } else {
          return digestsBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public java.util.List<? extends org.waveprotocol.box.search.SearchProto.SearchResponse.DigestOrBuilder> 
           getDigestsOrBuilderList() {
        if (digestsBuilder_ != null) {
          return digestsBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(digests_);
        }
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder addDigestsBuilder() {
        return getDigestsFieldBuilder().addBuilder(
            org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.getDefaultInstance());
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder addDigestsBuilder(
          int index) {
        return getDigestsFieldBuilder().addBuilder(
            index, org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.getDefaultInstance());
      }
      /**
       * <code>repeated .search.SearchResponse.Digest digests = 3;</code>
       *
       * <pre>
       * A list of digests, representing the segment [index, index + result_count] 
       * from the query parameters.
       * </pre>
       */
      public java.util.List<org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder> 
           getDigestsBuilderList() {
        return getDigestsFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilder<
          org.waveprotocol.box.search.SearchProto.SearchResponse.Digest, org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder, org.waveprotocol.box.search.SearchProto.SearchResponse.DigestOrBuilder> 
          getDigestsFieldBuilder() {
        if (digestsBuilder_ == null) {
          digestsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
              org.waveprotocol.box.search.SearchProto.SearchResponse.Digest, org.waveprotocol.box.search.SearchProto.SearchResponse.Digest.Builder, org.waveprotocol.box.search.SearchProto.SearchResponse.DigestOrBuilder>(
                  digests_,
                  ((bitField0_ & 0x00000004) == 0x00000004),
                  getParentForChildren(),
                  isClean());
          digests_ = null;
        }
        return digestsBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:search.SearchResponse)
    }

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

    // @@protoc_insertion_point(class_scope:search.SearchResponse)
  }

  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_search_SearchRequest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_search_SearchRequest_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_search_SearchResponse_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_search_SearchResponse_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_search_SearchResponse_Digest_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_search_SearchResponse_Digest_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/waveprotocol/box/search/search.pro" +
      "to\022\006search\"A\n\rSearchRequest\022\r\n\005query\030\001 \002" +
      "(\t\022\r\n\005index\030\002 \002(\005\022\022\n\nnumResults\030\003 \002(\005\"\204\002" +
      "\n\016SearchResponse\022\r\n\005query\030\001 \002(\t\022\024\n\014total" +
      "Results\030\002 \002(\005\022.\n\007digests\030\003 \003(\0132\035.search." +
      "SearchResponse.Digest\032\234\001\n\006Digest\022\r\n\005titl" +
      "e\030\001 \002(\t\022\017\n\007snippet\030\002 \002(\t\022\016\n\006waveId\030\003 \002(\t" +
      "\022\024\n\014lastModified\030\004 \002(\003\022\023\n\013unreadCount\030\005 " +
      "\002(\005\022\021\n\tblipCount\030\006 \002(\005\022\024\n\014participants\030\007" +
      " \003(\t\022\016\n\006author\030\010 \002(\tB*\n\033org.waveprotocol",
      ".box.searchB\013SearchProto"
    };
    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_search_SearchRequest_descriptor =
            getDescriptor().getMessageTypes().get(0);
          internal_static_search_SearchRequest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_search_SearchRequest_descriptor,
              new java.lang.String[] { "Query", "Index", "NumResults", });
          internal_static_search_SearchResponse_descriptor =
            getDescriptor().getMessageTypes().get(1);
          internal_static_search_SearchResponse_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_search_SearchResponse_descriptor,
              new java.lang.String[] { "Query", "TotalResults", "Digests", });
          internal_static_search_SearchResponse_Digest_descriptor =
            internal_static_search_SearchResponse_descriptor.getNestedTypes().get(0);
          internal_static_search_SearchResponse_Digest_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_search_SearchResponse_Digest_descriptor,
              new java.lang.String[] { "Title", "Snippet", "WaveId", "LastModified", "UnreadCount", "BlipCount", "Participants", "Author", });
          return null;
        }
      };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        }, assigner);
  }

  // @@protoc_insertion_point(outer_class_scope)
}
