// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: cobalt/storage/store/storage.proto

package dev.cobalt.storage;

@SuppressWarnings("unchecked")
public final class StorageProto {
  private StorageProto() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }
  public interface CookieOrBuilder extends
      // @@protoc_insertion_point(interface_extends:cobalt.storage.Cookie)
      com.google.protobuf.MessageLiteOrBuilder {

    /**
     * <pre>
     * The name of the cookie.
     * </pre>
     *
     * <code>optional string name = 1;</code>
     */
    java.lang.String getName();
    /**
     * <pre>
     * The name of the cookie.
     * </pre>
     *
     * <code>optional string name = 1;</code>
     */
    com.google.protobuf.ByteString
        getNameBytes();

    /**
     * <pre>
     * The value of the cookie.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    java.lang.String getValue();
    /**
     * <pre>
     * The value of the cookie.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    com.google.protobuf.ByteString
        getValueBytes();

    /**
     * <pre>
     * The domain of the url for which the cookie is store.
     * </pre>
     *
     * <code>optional string domain = 3;</code>
     */
    java.lang.String getDomain();
    /**
     * <pre>
     * The domain of the url for which the cookie is store.
     * </pre>
     *
     * <code>optional string domain = 3;</code>
     */
    com.google.protobuf.ByteString
        getDomainBytes();

    /**
     * <pre>
     * The path of the url for which the cookie is stored.
     * </pre>
     *
     * <code>optional string path = 4;</code>
     */
    java.lang.String getPath();
    /**
     * <pre>
     * The path of the url for which the cookie is stored.
     * </pre>
     *
     * <code>optional string path = 4;</code>
     */
    com.google.protobuf.ByteString
        getPathBytes();

    /**
     * <pre>
     * The creation time for the cookie in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 creation_time_us = 5;</code>
     */
    long getCreationTimeUs();

    /**
     * <pre>
     * The expiration time for the cookie in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 expiration_time_us = 6;</code>
     */
    long getExpirationTimeUs();

    /**
     * <pre>
     * The last access time in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 last_access_time_us = 7;</code>
     */
    long getLastAccessTimeUs();

    /**
     * <pre>
     * Whether the cookie should be transmitted only over secure connection.
     * Defaults to false.
     * </pre>
     *
     * <code>optional bool secure = 8;</code>
     */
    boolean getSecure();

    /**
     * <pre>
     * Whether this is an HTTP-only cookie. Defaults to false.
     * </pre>
     *
     * <code>optional bool http_only = 9;</code>
     */
    boolean getHttpOnly();
  }
  /**
   * <pre>
   * A single cookie representation.
   * </pre>
   *
   * Protobuf type {@code cobalt.storage.Cookie}
   */
  public  static final class Cookie extends
      com.google.protobuf.GeneratedMessageLite<
          Cookie, Cookie.Builder> implements
      // @@protoc_insertion_point(message_implements:cobalt.storage.Cookie)
      CookieOrBuilder {
    private Cookie() {
      name_ = "";
      value_ = "";
      domain_ = "";
      path_ = "";
      creationTimeUs_ = 0L;
      expirationTimeUs_ = 0L;
      lastAccessTimeUs_ = 0L;
      secure_ = false;
      httpOnly_ = false;
    }
    public static final int NAME_FIELD_NUMBER = 1;
    private java.lang.String name_;
    /**
     * <pre>
     * The name of the cookie.
     * </pre>
     *
     * <code>optional string name = 1;</code>
     */
    public java.lang.String getName() {
      return name_;
    }
    /**
     * <pre>
     * The name of the cookie.
     * </pre>
     *
     * <code>optional string name = 1;</code>
     */
    public com.google.protobuf.ByteString
        getNameBytes() {
      return com.google.protobuf.ByteString.copyFromUtf8(name_);
    }
    /**
     * <pre>
     * The name of the cookie.
     * </pre>
     *
     * <code>optional string name = 1;</code>
     */
    private void setName(
        java.lang.String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  
      name_ = value;
    }
    /**
     * <pre>
     * The name of the cookie.
     * </pre>
     *
     * <code>optional string name = 1;</code>
     */
    private void clearName() {
      
      name_ = getDefaultInstance().getName();
    }
    /**
     * <pre>
     * The name of the cookie.
     * </pre>
     *
     * <code>optional string name = 1;</code>
     */
    private void setNameBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
      
      name_ = value.toStringUtf8();
    }

    public static final int VALUE_FIELD_NUMBER = 2;
    private java.lang.String value_;
    /**
     * <pre>
     * The value of the cookie.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    public java.lang.String getValue() {
      return value_;
    }
    /**
     * <pre>
     * The value of the cookie.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    public com.google.protobuf.ByteString
        getValueBytes() {
      return com.google.protobuf.ByteString.copyFromUtf8(value_);
    }
    /**
     * <pre>
     * The value of the cookie.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    private void setValue(
        java.lang.String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  
      value_ = value;
    }
    /**
     * <pre>
     * The value of the cookie.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    private void clearValue() {
      
      value_ = getDefaultInstance().getValue();
    }
    /**
     * <pre>
     * The value of the cookie.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    private void setValueBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
      
      value_ = value.toStringUtf8();
    }

    public static final int DOMAIN_FIELD_NUMBER = 3;
    private java.lang.String domain_;
    /**
     * <pre>
     * The domain of the url for which the cookie is store.
     * </pre>
     *
     * <code>optional string domain = 3;</code>
     */
    public java.lang.String getDomain() {
      return domain_;
    }
    /**
     * <pre>
     * The domain of the url for which the cookie is store.
     * </pre>
     *
     * <code>optional string domain = 3;</code>
     */
    public com.google.protobuf.ByteString
        getDomainBytes() {
      return com.google.protobuf.ByteString.copyFromUtf8(domain_);
    }
    /**
     * <pre>
     * The domain of the url for which the cookie is store.
     * </pre>
     *
     * <code>optional string domain = 3;</code>
     */
    private void setDomain(
        java.lang.String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  
      domain_ = value;
    }
    /**
     * <pre>
     * The domain of the url for which the cookie is store.
     * </pre>
     *
     * <code>optional string domain = 3;</code>
     */
    private void clearDomain() {
      
      domain_ = getDefaultInstance().getDomain();
    }
    /**
     * <pre>
     * The domain of the url for which the cookie is store.
     * </pre>
     *
     * <code>optional string domain = 3;</code>
     */
    private void setDomainBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
      
      domain_ = value.toStringUtf8();
    }

    public static final int PATH_FIELD_NUMBER = 4;
    private java.lang.String path_;
    /**
     * <pre>
     * The path of the url for which the cookie is stored.
     * </pre>
     *
     * <code>optional string path = 4;</code>
     */
    public java.lang.String getPath() {
      return path_;
    }
    /**
     * <pre>
     * The path of the url for which the cookie is stored.
     * </pre>
     *
     * <code>optional string path = 4;</code>
     */
    public com.google.protobuf.ByteString
        getPathBytes() {
      return com.google.protobuf.ByteString.copyFromUtf8(path_);
    }
    /**
     * <pre>
     * The path of the url for which the cookie is stored.
     * </pre>
     *
     * <code>optional string path = 4;</code>
     */
    private void setPath(
        java.lang.String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  
      path_ = value;
    }
    /**
     * <pre>
     * The path of the url for which the cookie is stored.
     * </pre>
     *
     * <code>optional string path = 4;</code>
     */
    private void clearPath() {
      
      path_ = getDefaultInstance().getPath();
    }
    /**
     * <pre>
     * The path of the url for which the cookie is stored.
     * </pre>
     *
     * <code>optional string path = 4;</code>
     */
    private void setPathBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
      
      path_ = value.toStringUtf8();
    }

    public static final int CREATION_TIME_US_FIELD_NUMBER = 5;
    private long creationTimeUs_;
    /**
     * <pre>
     * The creation time for the cookie in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 creation_time_us = 5;</code>
     */
    public long getCreationTimeUs() {
      return creationTimeUs_;
    }
    /**
     * <pre>
     * The creation time for the cookie in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 creation_time_us = 5;</code>
     */
    private void setCreationTimeUs(long value) {
      
      creationTimeUs_ = value;
    }
    /**
     * <pre>
     * The creation time for the cookie in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 creation_time_us = 5;</code>
     */
    private void clearCreationTimeUs() {
      
      creationTimeUs_ = 0L;
    }

    public static final int EXPIRATION_TIME_US_FIELD_NUMBER = 6;
    private long expirationTimeUs_;
    /**
     * <pre>
     * The expiration time for the cookie in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 expiration_time_us = 6;</code>
     */
    public long getExpirationTimeUs() {
      return expirationTimeUs_;
    }
    /**
     * <pre>
     * The expiration time for the cookie in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 expiration_time_us = 6;</code>
     */
    private void setExpirationTimeUs(long value) {
      
      expirationTimeUs_ = value;
    }
    /**
     * <pre>
     * The expiration time for the cookie in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 expiration_time_us = 6;</code>
     */
    private void clearExpirationTimeUs() {
      
      expirationTimeUs_ = 0L;
    }

    public static final int LAST_ACCESS_TIME_US_FIELD_NUMBER = 7;
    private long lastAccessTimeUs_;
    /**
     * <pre>
     * The last access time in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 last_access_time_us = 7;</code>
     */
    public long getLastAccessTimeUs() {
      return lastAccessTimeUs_;
    }
    /**
     * <pre>
     * The last access time in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 last_access_time_us = 7;</code>
     */
    private void setLastAccessTimeUs(long value) {
      
      lastAccessTimeUs_ = value;
    }
    /**
     * <pre>
     * The last access time in microseconds since
     * Windows epoch - 1/1/1601 UTC.
     * </pre>
     *
     * <code>optional int64 last_access_time_us = 7;</code>
     */
    private void clearLastAccessTimeUs() {
      
      lastAccessTimeUs_ = 0L;
    }

    public static final int SECURE_FIELD_NUMBER = 8;
    private boolean secure_;
    /**
     * <pre>
     * Whether the cookie should be transmitted only over secure connection.
     * Defaults to false.
     * </pre>
     *
     * <code>optional bool secure = 8;</code>
     */
    public boolean getSecure() {
      return secure_;
    }
    /**
     * <pre>
     * Whether the cookie should be transmitted only over secure connection.
     * Defaults to false.
     * </pre>
     *
     * <code>optional bool secure = 8;</code>
     */
    private void setSecure(boolean value) {
      
      secure_ = value;
    }
    /**
     * <pre>
     * Whether the cookie should be transmitted only over secure connection.
     * Defaults to false.
     * </pre>
     *
     * <code>optional bool secure = 8;</code>
     */
    private void clearSecure() {
      
      secure_ = false;
    }

    public static final int HTTP_ONLY_FIELD_NUMBER = 9;
    private boolean httpOnly_;
    /**
     * <pre>
     * Whether this is an HTTP-only cookie. Defaults to false.
     * </pre>
     *
     * <code>optional bool http_only = 9;</code>
     */
    public boolean getHttpOnly() {
      return httpOnly_;
    }
    /**
     * <pre>
     * Whether this is an HTTP-only cookie. Defaults to false.
     * </pre>
     *
     * <code>optional bool http_only = 9;</code>
     */
    private void setHttpOnly(boolean value) {
      
      httpOnly_ = value;
    }
    /**
     * <pre>
     * Whether this is an HTTP-only cookie. Defaults to false.
     * </pre>
     *
     * <code>optional bool http_only = 9;</code>
     */
    private void clearHttpOnly() {
      
      httpOnly_ = false;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (!name_.isEmpty()) {
        output.writeString(1, getName());
      }
      if (!value_.isEmpty()) {
        output.writeString(2, getValue());
      }
      if (!domain_.isEmpty()) {
        output.writeString(3, getDomain());
      }
      if (!path_.isEmpty()) {
        output.writeString(4, getPath());
      }
      if (creationTimeUs_ != 0L) {
        output.writeInt64(5, creationTimeUs_);
      }
      if (expirationTimeUs_ != 0L) {
        output.writeInt64(6, expirationTimeUs_);
      }
      if (lastAccessTimeUs_ != 0L) {
        output.writeInt64(7, lastAccessTimeUs_);
      }
      if (secure_ != false) {
        output.writeBool(8, secure_);
      }
      if (httpOnly_ != false) {
        output.writeBool(9, httpOnly_);
      }
    }

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

      size = 0;
      if (!name_.isEmpty()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(1, getName());
      }
      if (!value_.isEmpty()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(2, getValue());
      }
      if (!domain_.isEmpty()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(3, getDomain());
      }
      if (!path_.isEmpty()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(4, getPath());
      }
      if (creationTimeUs_ != 0L) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(5, creationTimeUs_);
      }
      if (expirationTimeUs_ != 0L) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(6, expirationTimeUs_);
      }
      if (lastAccessTimeUs_ != 0L) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(7, lastAccessTimeUs_);
      }
      if (secure_ != false) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(8, secure_);
      }
      if (httpOnly_ != false) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(9, httpOnly_);
      }
      memoizedSerializedSize = size;
      return size;
    }

    public static dev.cobalt.storage.StorageProto.Cookie parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data);
    }
    public static dev.cobalt.storage.StorageProto.Cookie parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.Cookie parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data);
    }
    public static dev.cobalt.storage.StorageProto.Cookie parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.Cookie parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.Cookie parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.Cookie parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.Cookie parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.Cookie parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.Cookie parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input, extensionRegistry);
    }

    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(dev.cobalt.storage.StorageProto.Cookie prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }

    /**
     * <pre>
     * A single cookie representation.
     * </pre>
     *
     * Protobuf type {@code cobalt.storage.Cookie}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageLite.Builder<
          dev.cobalt.storage.StorageProto.Cookie, Builder> implements
        // @@protoc_insertion_point(builder_implements:cobalt.storage.Cookie)
        dev.cobalt.storage.StorageProto.CookieOrBuilder {
      // Construct using dev.cobalt.storage.StorageProto.Cookie.newBuilder()
      private Builder() {
        super(DEFAULT_INSTANCE);
      }


      /**
       * <pre>
       * The name of the cookie.
       * </pre>
       *
       * <code>optional string name = 1;</code>
       */
      public java.lang.String getName() {
        return instance.getName();
      }
      /**
       * <pre>
       * The name of the cookie.
       * </pre>
       *
       * <code>optional string name = 1;</code>
       */
      public com.google.protobuf.ByteString
          getNameBytes() {
        return instance.getNameBytes();
      }
      /**
       * <pre>
       * The name of the cookie.
       * </pre>
       *
       * <code>optional string name = 1;</code>
       */
      public Builder setName(
          java.lang.String value) {
        copyOnWrite();
        instance.setName(value);
        return this;
      }
      /**
       * <pre>
       * The name of the cookie.
       * </pre>
       *
       * <code>optional string name = 1;</code>
       */
      public Builder clearName() {
        copyOnWrite();
        instance.clearName();
        return this;
      }
      /**
       * <pre>
       * The name of the cookie.
       * </pre>
       *
       * <code>optional string name = 1;</code>
       */
      public Builder setNameBytes(
          com.google.protobuf.ByteString value) {
        copyOnWrite();
        instance.setNameBytes(value);
        return this;
      }

      /**
       * <pre>
       * The value of the cookie.
       * </pre>
       *
       * <code>optional string value = 2;</code>
       */
      public java.lang.String getValue() {
        return instance.getValue();
      }
      /**
       * <pre>
       * The value of the cookie.
       * </pre>
       *
       * <code>optional string value = 2;</code>
       */
      public com.google.protobuf.ByteString
          getValueBytes() {
        return instance.getValueBytes();
      }
      /**
       * <pre>
       * The value of the cookie.
       * </pre>
       *
       * <code>optional string value = 2;</code>
       */
      public Builder setValue(
          java.lang.String value) {
        copyOnWrite();
        instance.setValue(value);
        return this;
      }
      /**
       * <pre>
       * The value of the cookie.
       * </pre>
       *
       * <code>optional string value = 2;</code>
       */
      public Builder clearValue() {
        copyOnWrite();
        instance.clearValue();
        return this;
      }
      /**
       * <pre>
       * The value of the cookie.
       * </pre>
       *
       * <code>optional string value = 2;</code>
       */
      public Builder setValueBytes(
          com.google.protobuf.ByteString value) {
        copyOnWrite();
        instance.setValueBytes(value);
        return this;
      }

      /**
       * <pre>
       * The domain of the url for which the cookie is store.
       * </pre>
       *
       * <code>optional string domain = 3;</code>
       */
      public java.lang.String getDomain() {
        return instance.getDomain();
      }
      /**
       * <pre>
       * The domain of the url for which the cookie is store.
       * </pre>
       *
       * <code>optional string domain = 3;</code>
       */
      public com.google.protobuf.ByteString
          getDomainBytes() {
        return instance.getDomainBytes();
      }
      /**
       * <pre>
       * The domain of the url for which the cookie is store.
       * </pre>
       *
       * <code>optional string domain = 3;</code>
       */
      public Builder setDomain(
          java.lang.String value) {
        copyOnWrite();
        instance.setDomain(value);
        return this;
      }
      /**
       * <pre>
       * The domain of the url for which the cookie is store.
       * </pre>
       *
       * <code>optional string domain = 3;</code>
       */
      public Builder clearDomain() {
        copyOnWrite();
        instance.clearDomain();
        return this;
      }
      /**
       * <pre>
       * The domain of the url for which the cookie is store.
       * </pre>
       *
       * <code>optional string domain = 3;</code>
       */
      public Builder setDomainBytes(
          com.google.protobuf.ByteString value) {
        copyOnWrite();
        instance.setDomainBytes(value);
        return this;
      }

      /**
       * <pre>
       * The path of the url for which the cookie is stored.
       * </pre>
       *
       * <code>optional string path = 4;</code>
       */
      public java.lang.String getPath() {
        return instance.getPath();
      }
      /**
       * <pre>
       * The path of the url for which the cookie is stored.
       * </pre>
       *
       * <code>optional string path = 4;</code>
       */
      public com.google.protobuf.ByteString
          getPathBytes() {
        return instance.getPathBytes();
      }
      /**
       * <pre>
       * The path of the url for which the cookie is stored.
       * </pre>
       *
       * <code>optional string path = 4;</code>
       */
      public Builder setPath(
          java.lang.String value) {
        copyOnWrite();
        instance.setPath(value);
        return this;
      }
      /**
       * <pre>
       * The path of the url for which the cookie is stored.
       * </pre>
       *
       * <code>optional string path = 4;</code>
       */
      public Builder clearPath() {
        copyOnWrite();
        instance.clearPath();
        return this;
      }
      /**
       * <pre>
       * The path of the url for which the cookie is stored.
       * </pre>
       *
       * <code>optional string path = 4;</code>
       */
      public Builder setPathBytes(
          com.google.protobuf.ByteString value) {
        copyOnWrite();
        instance.setPathBytes(value);
        return this;
      }

      /**
       * <pre>
       * The creation time for the cookie in microseconds since
       * Windows epoch - 1/1/1601 UTC.
       * </pre>
       *
       * <code>optional int64 creation_time_us = 5;</code>
       */
      public long getCreationTimeUs() {
        return instance.getCreationTimeUs();
      }
      /**
       * <pre>
       * The creation time for the cookie in microseconds since
       * Windows epoch - 1/1/1601 UTC.
       * </pre>
       *
       * <code>optional int64 creation_time_us = 5;</code>
       */
      public Builder setCreationTimeUs(long value) {
        copyOnWrite();
        instance.setCreationTimeUs(value);
        return this;
      }
      /**
       * <pre>
       * The creation time for the cookie in microseconds since
       * Windows epoch - 1/1/1601 UTC.
       * </pre>
       *
       * <code>optional int64 creation_time_us = 5;</code>
       */
      public Builder clearCreationTimeUs() {
        copyOnWrite();
        instance.clearCreationTimeUs();
        return this;
      }

      /**
       * <pre>
       * The expiration time for the cookie in microseconds since
       * Windows epoch - 1/1/1601 UTC.
       * </pre>
       *
       * <code>optional int64 expiration_time_us = 6;</code>
       */
      public long getExpirationTimeUs() {
        return instance.getExpirationTimeUs();
      }
      /**
       * <pre>
       * The expiration time for the cookie in microseconds since
       * Windows epoch - 1/1/1601 UTC.
       * </pre>
       *
       * <code>optional int64 expiration_time_us = 6;</code>
       */
      public Builder setExpirationTimeUs(long value) {
        copyOnWrite();
        instance.setExpirationTimeUs(value);
        return this;
      }
      /**
       * <pre>
       * The expiration time for the cookie in microseconds since
       * Windows epoch - 1/1/1601 UTC.
       * </pre>
       *
       * <code>optional int64 expiration_time_us = 6;</code>
       */
      public Builder clearExpirationTimeUs() {
        copyOnWrite();
        instance.clearExpirationTimeUs();
        return this;
      }

      /**
       * <pre>
       * The last access time in microseconds since
       * Windows epoch - 1/1/1601 UTC.
       * </pre>
       *
       * <code>optional int64 last_access_time_us = 7;</code>
       */
      public long getLastAccessTimeUs() {
        return instance.getLastAccessTimeUs();
      }
      /**
       * <pre>
       * The last access time in microseconds since
       * Windows epoch - 1/1/1601 UTC.
       * </pre>
       *
       * <code>optional int64 last_access_time_us = 7;</code>
       */
      public Builder setLastAccessTimeUs(long value) {
        copyOnWrite();
        instance.setLastAccessTimeUs(value);
        return this;
      }
      /**
       * <pre>
       * The last access time in microseconds since
       * Windows epoch - 1/1/1601 UTC.
       * </pre>
       *
       * <code>optional int64 last_access_time_us = 7;</code>
       */
      public Builder clearLastAccessTimeUs() {
        copyOnWrite();
        instance.clearLastAccessTimeUs();
        return this;
      }

      /**
       * <pre>
       * Whether the cookie should be transmitted only over secure connection.
       * Defaults to false.
       * </pre>
       *
       * <code>optional bool secure = 8;</code>
       */
      public boolean getSecure() {
        return instance.getSecure();
      }
      /**
       * <pre>
       * Whether the cookie should be transmitted only over secure connection.
       * Defaults to false.
       * </pre>
       *
       * <code>optional bool secure = 8;</code>
       */
      public Builder setSecure(boolean value) {
        copyOnWrite();
        instance.setSecure(value);
        return this;
      }
      /**
       * <pre>
       * Whether the cookie should be transmitted only over secure connection.
       * Defaults to false.
       * </pre>
       *
       * <code>optional bool secure = 8;</code>
       */
      public Builder clearSecure() {
        copyOnWrite();
        instance.clearSecure();
        return this;
      }

      /**
       * <pre>
       * Whether this is an HTTP-only cookie. Defaults to false.
       * </pre>
       *
       * <code>optional bool http_only = 9;</code>
       */
      public boolean getHttpOnly() {
        return instance.getHttpOnly();
      }
      /**
       * <pre>
       * Whether this is an HTTP-only cookie. Defaults to false.
       * </pre>
       *
       * <code>optional bool http_only = 9;</code>
       */
      public Builder setHttpOnly(boolean value) {
        copyOnWrite();
        instance.setHttpOnly(value);
        return this;
      }
      /**
       * <pre>
       * Whether this is an HTTP-only cookie. Defaults to false.
       * </pre>
       *
       * <code>optional bool http_only = 9;</code>
       */
      public Builder clearHttpOnly() {
        copyOnWrite();
        instance.clearHttpOnly();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:cobalt.storage.Cookie)
    }
    protected final Object dynamicMethod(
        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
        Object arg0, Object arg1) {
      switch (method) {
        case NEW_MUTABLE_INSTANCE: {
          return new dev.cobalt.storage.StorageProto.Cookie();
        }
        case IS_INITIALIZED: {
          return DEFAULT_INSTANCE;
        }
        case MAKE_IMMUTABLE: {
          return null;
        }
        case NEW_BUILDER: {
          return new Builder();
        }
        case VISIT: {
          Visitor visitor = (Visitor) arg0;
          dev.cobalt.storage.StorageProto.Cookie other = (dev.cobalt.storage.StorageProto.Cookie) arg1;
          name_ = visitor.visitString(!name_.isEmpty(), name_,
              !other.name_.isEmpty(), other.name_);
          value_ = visitor.visitString(!value_.isEmpty(), value_,
              !other.value_.isEmpty(), other.value_);
          domain_ = visitor.visitString(!domain_.isEmpty(), domain_,
              !other.domain_.isEmpty(), other.domain_);
          path_ = visitor.visitString(!path_.isEmpty(), path_,
              !other.path_.isEmpty(), other.path_);
          creationTimeUs_ = visitor.visitLong(creationTimeUs_ != 0L, creationTimeUs_,
              other.creationTimeUs_ != 0L, other.creationTimeUs_);
          expirationTimeUs_ = visitor.visitLong(expirationTimeUs_ != 0L, expirationTimeUs_,
              other.expirationTimeUs_ != 0L, other.expirationTimeUs_);
          lastAccessTimeUs_ = visitor.visitLong(lastAccessTimeUs_ != 0L, lastAccessTimeUs_,
              other.lastAccessTimeUs_ != 0L, other.lastAccessTimeUs_);
          secure_ = visitor.visitBoolean(secure_ != false, secure_,
              other.secure_ != false, other.secure_);
          httpOnly_ = visitor.visitBoolean(httpOnly_ != false, httpOnly_,
              other.httpOnly_ != false, other.httpOnly_);
          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor
              .INSTANCE) {
          }
          return this;
        }
        case MERGE_FROM_STREAM: {
          com.google.protobuf.CodedInputStream input =
              (com.google.protobuf.CodedInputStream) arg0;
          com.google.protobuf.ExtensionRegistryLite extensionRegistry =
              (com.google.protobuf.ExtensionRegistryLite) arg1;
          try {
            boolean done = false;
            while (!done) {
              int tag = input.readTag();
              switch (tag) {
                case 0:
                  done = true;
                  break;
                default: {
                  if (!input.skipField(tag)) {
                    done = true;
                  }
                  break;
                }
                case 10: {
                  String s = input.readStringRequireUtf8();

                  name_ = s;
                  break;
                }
                case 18: {
                  String s = input.readStringRequireUtf8();

                  value_ = s;
                  break;
                }
                case 26: {
                  String s = input.readStringRequireUtf8();

                  domain_ = s;
                  break;
                }
                case 34: {
                  String s = input.readStringRequireUtf8();

                  path_ = s;
                  break;
                }
                case 40: {

                  creationTimeUs_ = input.readInt64();
                  break;
                }
                case 48: {

                  expirationTimeUs_ = input.readInt64();
                  break;
                }
                case 56: {

                  lastAccessTimeUs_ = input.readInt64();
                  break;
                }
                case 64: {

                  secure_ = input.readBool();
                  break;
                }
                case 72: {

                  httpOnly_ = input.readBool();
                  break;
                }
              }
            }
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            throw new RuntimeException(e.setUnfinishedMessage(this));
          } catch (java.io.IOException e) {
            throw new RuntimeException(
                new com.google.protobuf.InvalidProtocolBufferException(
                    e.getMessage()).setUnfinishedMessage(this));
          } finally {
          }
        }
        case GET_DEFAULT_INSTANCE: {
          return DEFAULT_INSTANCE;
        }
        case GET_PARSER: {
          if (PARSER == null) {    synchronized (dev.cobalt.storage.StorageProto.Cookie.class) {
              if (PARSER == null) {
                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);
              }
            }
          }
          return PARSER;
        }
      }
      throw new UnsupportedOperationException();
    }


    // @@protoc_insertion_point(class_scope:cobalt.storage.Cookie)
    private static final dev.cobalt.storage.StorageProto.Cookie DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new Cookie();
      DEFAULT_INSTANCE.makeImmutable();
    }

    public static dev.cobalt.storage.StorageProto.Cookie getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static volatile com.google.protobuf.Parser<Cookie> PARSER;

    public static com.google.protobuf.Parser<Cookie> parser() {
      return DEFAULT_INSTANCE.getParserForType();
    }
  }

  public interface LocalStorageEntryOrBuilder extends
      // @@protoc_insertion_point(interface_extends:cobalt.storage.LocalStorageEntry)
      com.google.protobuf.MessageLiteOrBuilder {

    /**
     * <pre>
     * The key for the local storage entry.
     * </pre>
     *
     * <code>optional string key = 1;</code>
     */
    java.lang.String getKey();
    /**
     * <pre>
     * The key for the local storage entry.
     * </pre>
     *
     * <code>optional string key = 1;</code>
     */
    com.google.protobuf.ByteString
        getKeyBytes();

    /**
     * <pre>
     * The value of the local storage entry.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    java.lang.String getValue();
    /**
     * <pre>
     * The value of the local storage entry.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    com.google.protobuf.ByteString
        getValueBytes();
  }
  /**
   * <pre>
   * A single local storage entry.
   * </pre>
   *
   * Protobuf type {@code cobalt.storage.LocalStorageEntry}
   */
  public  static final class LocalStorageEntry extends
      com.google.protobuf.GeneratedMessageLite<
          LocalStorageEntry, LocalStorageEntry.Builder> implements
      // @@protoc_insertion_point(message_implements:cobalt.storage.LocalStorageEntry)
      LocalStorageEntryOrBuilder {
    private LocalStorageEntry() {
      key_ = "";
      value_ = "";
    }
    public static final int KEY_FIELD_NUMBER = 1;
    private java.lang.String key_;
    /**
     * <pre>
     * The key for the local storage entry.
     * </pre>
     *
     * <code>optional string key = 1;</code>
     */
    public java.lang.String getKey() {
      return key_;
    }
    /**
     * <pre>
     * The key for the local storage entry.
     * </pre>
     *
     * <code>optional string key = 1;</code>
     */
    public com.google.protobuf.ByteString
        getKeyBytes() {
      return com.google.protobuf.ByteString.copyFromUtf8(key_);
    }
    /**
     * <pre>
     * The key for the local storage entry.
     * </pre>
     *
     * <code>optional string key = 1;</code>
     */
    private void setKey(
        java.lang.String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  
      key_ = value;
    }
    /**
     * <pre>
     * The key for the local storage entry.
     * </pre>
     *
     * <code>optional string key = 1;</code>
     */
    private void clearKey() {
      
      key_ = getDefaultInstance().getKey();
    }
    /**
     * <pre>
     * The key for the local storage entry.
     * </pre>
     *
     * <code>optional string key = 1;</code>
     */
    private void setKeyBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
      
      key_ = value.toStringUtf8();
    }

    public static final int VALUE_FIELD_NUMBER = 2;
    private java.lang.String value_;
    /**
     * <pre>
     * The value of the local storage entry.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    public java.lang.String getValue() {
      return value_;
    }
    /**
     * <pre>
     * The value of the local storage entry.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    public com.google.protobuf.ByteString
        getValueBytes() {
      return com.google.protobuf.ByteString.copyFromUtf8(value_);
    }
    /**
     * <pre>
     * The value of the local storage entry.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    private void setValue(
        java.lang.String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  
      value_ = value;
    }
    /**
     * <pre>
     * The value of the local storage entry.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    private void clearValue() {
      
      value_ = getDefaultInstance().getValue();
    }
    /**
     * <pre>
     * The value of the local storage entry.
     * </pre>
     *
     * <code>optional string value = 2;</code>
     */
    private void setValueBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
      
      value_ = value.toStringUtf8();
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (!key_.isEmpty()) {
        output.writeString(1, getKey());
      }
      if (!value_.isEmpty()) {
        output.writeString(2, getValue());
      }
    }

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

      size = 0;
      if (!key_.isEmpty()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(1, getKey());
      }
      if (!value_.isEmpty()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(2, getValue());
      }
      memoizedSerializedSize = size;
      return size;
    }

    public static dev.cobalt.storage.StorageProto.LocalStorageEntry parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorageEntry parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorageEntry parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorageEntry parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorageEntry parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorageEntry parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorageEntry parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorageEntry parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorageEntry parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorageEntry parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input, extensionRegistry);
    }

    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(dev.cobalt.storage.StorageProto.LocalStorageEntry prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }

    /**
     * <pre>
     * A single local storage entry.
     * </pre>
     *
     * Protobuf type {@code cobalt.storage.LocalStorageEntry}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageLite.Builder<
          dev.cobalt.storage.StorageProto.LocalStorageEntry, Builder> implements
        // @@protoc_insertion_point(builder_implements:cobalt.storage.LocalStorageEntry)
        dev.cobalt.storage.StorageProto.LocalStorageEntryOrBuilder {
      // Construct using dev.cobalt.storage.StorageProto.LocalStorageEntry.newBuilder()
      private Builder() {
        super(DEFAULT_INSTANCE);
      }


      /**
       * <pre>
       * The key for the local storage entry.
       * </pre>
       *
       * <code>optional string key = 1;</code>
       */
      public java.lang.String getKey() {
        return instance.getKey();
      }
      /**
       * <pre>
       * The key for the local storage entry.
       * </pre>
       *
       * <code>optional string key = 1;</code>
       */
      public com.google.protobuf.ByteString
          getKeyBytes() {
        return instance.getKeyBytes();
      }
      /**
       * <pre>
       * The key for the local storage entry.
       * </pre>
       *
       * <code>optional string key = 1;</code>
       */
      public Builder setKey(
          java.lang.String value) {
        copyOnWrite();
        instance.setKey(value);
        return this;
      }
      /**
       * <pre>
       * The key for the local storage entry.
       * </pre>
       *
       * <code>optional string key = 1;</code>
       */
      public Builder clearKey() {
        copyOnWrite();
        instance.clearKey();
        return this;
      }
      /**
       * <pre>
       * The key for the local storage entry.
       * </pre>
       *
       * <code>optional string key = 1;</code>
       */
      public Builder setKeyBytes(
          com.google.protobuf.ByteString value) {
        copyOnWrite();
        instance.setKeyBytes(value);
        return this;
      }

      /**
       * <pre>
       * The value of the local storage entry.
       * </pre>
       *
       * <code>optional string value = 2;</code>
       */
      public java.lang.String getValue() {
        return instance.getValue();
      }
      /**
       * <pre>
       * The value of the local storage entry.
       * </pre>
       *
       * <code>optional string value = 2;</code>
       */
      public com.google.protobuf.ByteString
          getValueBytes() {
        return instance.getValueBytes();
      }
      /**
       * <pre>
       * The value of the local storage entry.
       * </pre>
       *
       * <code>optional string value = 2;</code>
       */
      public Builder setValue(
          java.lang.String value) {
        copyOnWrite();
        instance.setValue(value);
        return this;
      }
      /**
       * <pre>
       * The value of the local storage entry.
       * </pre>
       *
       * <code>optional string value = 2;</code>
       */
      public Builder clearValue() {
        copyOnWrite();
        instance.clearValue();
        return this;
      }
      /**
       * <pre>
       * The value of the local storage entry.
       * </pre>
       *
       * <code>optional string value = 2;</code>
       */
      public Builder setValueBytes(
          com.google.protobuf.ByteString value) {
        copyOnWrite();
        instance.setValueBytes(value);
        return this;
      }

      // @@protoc_insertion_point(builder_scope:cobalt.storage.LocalStorageEntry)
    }
    protected final Object dynamicMethod(
        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
        Object arg0, Object arg1) {
      switch (method) {
        case NEW_MUTABLE_INSTANCE: {
          return new dev.cobalt.storage.StorageProto.LocalStorageEntry();
        }
        case IS_INITIALIZED: {
          return DEFAULT_INSTANCE;
        }
        case MAKE_IMMUTABLE: {
          return null;
        }
        case NEW_BUILDER: {
          return new Builder();
        }
        case VISIT: {
          Visitor visitor = (Visitor) arg0;
          dev.cobalt.storage.StorageProto.LocalStorageEntry other = (dev.cobalt.storage.StorageProto.LocalStorageEntry) arg1;
          key_ = visitor.visitString(!key_.isEmpty(), key_,
              !other.key_.isEmpty(), other.key_);
          value_ = visitor.visitString(!value_.isEmpty(), value_,
              !other.value_.isEmpty(), other.value_);
          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor
              .INSTANCE) {
          }
          return this;
        }
        case MERGE_FROM_STREAM: {
          com.google.protobuf.CodedInputStream input =
              (com.google.protobuf.CodedInputStream) arg0;
          com.google.protobuf.ExtensionRegistryLite extensionRegistry =
              (com.google.protobuf.ExtensionRegistryLite) arg1;
          try {
            boolean done = false;
            while (!done) {
              int tag = input.readTag();
              switch (tag) {
                case 0:
                  done = true;
                  break;
                default: {
                  if (!input.skipField(tag)) {
                    done = true;
                  }
                  break;
                }
                case 10: {
                  String s = input.readStringRequireUtf8();

                  key_ = s;
                  break;
                }
                case 18: {
                  String s = input.readStringRequireUtf8();

                  value_ = s;
                  break;
                }
              }
            }
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            throw new RuntimeException(e.setUnfinishedMessage(this));
          } catch (java.io.IOException e) {
            throw new RuntimeException(
                new com.google.protobuf.InvalidProtocolBufferException(
                    e.getMessage()).setUnfinishedMessage(this));
          } finally {
          }
        }
        case GET_DEFAULT_INSTANCE: {
          return DEFAULT_INSTANCE;
        }
        case GET_PARSER: {
          if (PARSER == null) {    synchronized (dev.cobalt.storage.StorageProto.LocalStorageEntry.class) {
              if (PARSER == null) {
                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);
              }
            }
          }
          return PARSER;
        }
      }
      throw new UnsupportedOperationException();
    }


    // @@protoc_insertion_point(class_scope:cobalt.storage.LocalStorageEntry)
    private static final dev.cobalt.storage.StorageProto.LocalStorageEntry DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new LocalStorageEntry();
      DEFAULT_INSTANCE.makeImmutable();
    }

    public static dev.cobalt.storage.StorageProto.LocalStorageEntry getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static volatile com.google.protobuf.Parser<LocalStorageEntry> PARSER;

    public static com.google.protobuf.Parser<LocalStorageEntry> parser() {
      return DEFAULT_INSTANCE.getParserForType();
    }
  }

  public interface LocalStorageOrBuilder extends
      // @@protoc_insertion_point(interface_extends:cobalt.storage.LocalStorage)
      com.google.protobuf.MessageLiteOrBuilder {

    /**
     * <pre>
     * A serialzied origin as defined in:
     * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
     * For example: "https://www.youtube.com"
     * </pre>
     *
     * <code>optional string serialized_origin = 1;</code>
     */
    java.lang.String getSerializedOrigin();
    /**
     * <pre>
     * A serialzied origin as defined in:
     * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
     * For example: "https://www.youtube.com"
     * </pre>
     *
     * <code>optional string serialized_origin = 1;</code>
     */
    com.google.protobuf.ByteString
        getSerializedOriginBytes();

    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    java.util.List<dev.cobalt.storage.StorageProto.LocalStorageEntry> 
        getLocalStorageEntriesList();
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    dev.cobalt.storage.StorageProto.LocalStorageEntry getLocalStorageEntries(int index);
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    int getLocalStorageEntriesCount();
  }
  /**
   * <pre>
   * Multiple local storages identified by unique id.
   * </pre>
   *
   * Protobuf type {@code cobalt.storage.LocalStorage}
   */
  public  static final class LocalStorage extends
      com.google.protobuf.GeneratedMessageLite<
          LocalStorage, LocalStorage.Builder> implements
      // @@protoc_insertion_point(message_implements:cobalt.storage.LocalStorage)
      LocalStorageOrBuilder {
    private LocalStorage() {
      serializedOrigin_ = "";
      localStorageEntries_ = emptyProtobufList();
    }
    private int bitField0_;
    public static final int SERIALIZED_ORIGIN_FIELD_NUMBER = 1;
    private java.lang.String serializedOrigin_;
    /**
     * <pre>
     * A serialzied origin as defined in:
     * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
     * For example: "https://www.youtube.com"
     * </pre>
     *
     * <code>optional string serialized_origin = 1;</code>
     */
    public java.lang.String getSerializedOrigin() {
      return serializedOrigin_;
    }
    /**
     * <pre>
     * A serialzied origin as defined in:
     * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
     * For example: "https://www.youtube.com"
     * </pre>
     *
     * <code>optional string serialized_origin = 1;</code>
     */
    public com.google.protobuf.ByteString
        getSerializedOriginBytes() {
      return com.google.protobuf.ByteString.copyFromUtf8(serializedOrigin_);
    }
    /**
     * <pre>
     * A serialzied origin as defined in:
     * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
     * For example: "https://www.youtube.com"
     * </pre>
     *
     * <code>optional string serialized_origin = 1;</code>
     */
    private void setSerializedOrigin(
        java.lang.String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  
      serializedOrigin_ = value;
    }
    /**
     * <pre>
     * A serialzied origin as defined in:
     * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
     * For example: "https://www.youtube.com"
     * </pre>
     *
     * <code>optional string serialized_origin = 1;</code>
     */
    private void clearSerializedOrigin() {
      
      serializedOrigin_ = getDefaultInstance().getSerializedOrigin();
    }
    /**
     * <pre>
     * A serialzied origin as defined in:
     * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
     * For example: "https://www.youtube.com"
     * </pre>
     *
     * <code>optional string serialized_origin = 1;</code>
     */
    private void setSerializedOriginBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
      
      serializedOrigin_ = value.toStringUtf8();
    }

    public static final int LOCAL_STORAGE_ENTRIES_FIELD_NUMBER = 2;
    private com.google.protobuf.Internal.ProtobufList<dev.cobalt.storage.StorageProto.LocalStorageEntry> localStorageEntries_;
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    public java.util.List<dev.cobalt.storage.StorageProto.LocalStorageEntry> getLocalStorageEntriesList() {
      return localStorageEntries_;
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    public java.util.List<? extends dev.cobalt.storage.StorageProto.LocalStorageEntryOrBuilder> 
        getLocalStorageEntriesOrBuilderList() {
      return localStorageEntries_;
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    public int getLocalStorageEntriesCount() {
      return localStorageEntries_.size();
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    public dev.cobalt.storage.StorageProto.LocalStorageEntry getLocalStorageEntries(int index) {
      return localStorageEntries_.get(index);
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    public dev.cobalt.storage.StorageProto.LocalStorageEntryOrBuilder getLocalStorageEntriesOrBuilder(
        int index) {
      return localStorageEntries_.get(index);
    }
    private void ensureLocalStorageEntriesIsMutable() {
      if (!localStorageEntries_.isModifiable()) {
        localStorageEntries_ =
            com.google.protobuf.GeneratedMessageLite.mutableCopy(localStorageEntries_);
       }
    }

    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    private void setLocalStorageEntries(
        int index, dev.cobalt.storage.StorageProto.LocalStorageEntry value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureLocalStorageEntriesIsMutable();
      localStorageEntries_.set(index, value);
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    private void setLocalStorageEntries(
        int index, dev.cobalt.storage.StorageProto.LocalStorageEntry.Builder builderForValue) {
      ensureLocalStorageEntriesIsMutable();
      localStorageEntries_.set(index, builderForValue.build());
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    private void addLocalStorageEntries(dev.cobalt.storage.StorageProto.LocalStorageEntry value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureLocalStorageEntriesIsMutable();
      localStorageEntries_.add(value);
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    private void addLocalStorageEntries(
        int index, dev.cobalt.storage.StorageProto.LocalStorageEntry value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureLocalStorageEntriesIsMutable();
      localStorageEntries_.add(index, value);
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    private void addLocalStorageEntries(
        dev.cobalt.storage.StorageProto.LocalStorageEntry.Builder builderForValue) {
      ensureLocalStorageEntriesIsMutable();
      localStorageEntries_.add(builderForValue.build());
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    private void addLocalStorageEntries(
        int index, dev.cobalt.storage.StorageProto.LocalStorageEntry.Builder builderForValue) {
      ensureLocalStorageEntriesIsMutable();
      localStorageEntries_.add(index, builderForValue.build());
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    private void addAllLocalStorageEntries(
        java.lang.Iterable<? extends dev.cobalt.storage.StorageProto.LocalStorageEntry> values) {
      ensureLocalStorageEntriesIsMutable();
      com.google.protobuf.AbstractMessageLite.addAll(
          values, localStorageEntries_);
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    private void clearLocalStorageEntries() {
      localStorageEntries_ = emptyProtobufList();
    }
    /**
     * <pre>
     * The local storage entries for individual local storage.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
     */
    private void removeLocalStorageEntries(int index) {
      ensureLocalStorageEntriesIsMutable();
      localStorageEntries_.remove(index);
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (!serializedOrigin_.isEmpty()) {
        output.writeString(1, getSerializedOrigin());
      }
      for (int i = 0; i < localStorageEntries_.size(); i++) {
        output.writeMessage(2, localStorageEntries_.get(i));
      }
    }

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

      size = 0;
      if (!serializedOrigin_.isEmpty()) {
        size += com.google.protobuf.CodedOutputStream
          .computeStringSize(1, getSerializedOrigin());
      }
      for (int i = 0; i < localStorageEntries_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, localStorageEntries_.get(i));
      }
      memoizedSerializedSize = size;
      return size;
    }

    public static dev.cobalt.storage.StorageProto.LocalStorage parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorage parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorage parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorage parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorage parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorage parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorage parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorage parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorage parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.LocalStorage parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input, extensionRegistry);
    }

    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(dev.cobalt.storage.StorageProto.LocalStorage prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }

    /**
     * <pre>
     * Multiple local storages identified by unique id.
     * </pre>
     *
     * Protobuf type {@code cobalt.storage.LocalStorage}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageLite.Builder<
          dev.cobalt.storage.StorageProto.LocalStorage, Builder> implements
        // @@protoc_insertion_point(builder_implements:cobalt.storage.LocalStorage)
        dev.cobalt.storage.StorageProto.LocalStorageOrBuilder {
      // Construct using dev.cobalt.storage.StorageProto.LocalStorage.newBuilder()
      private Builder() {
        super(DEFAULT_INSTANCE);
      }


      /**
       * <pre>
       * A serialzied origin as defined in:
       * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
       * For example: "https://www.youtube.com"
       * </pre>
       *
       * <code>optional string serialized_origin = 1;</code>
       */
      public java.lang.String getSerializedOrigin() {
        return instance.getSerializedOrigin();
      }
      /**
       * <pre>
       * A serialzied origin as defined in:
       * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
       * For example: "https://www.youtube.com"
       * </pre>
       *
       * <code>optional string serialized_origin = 1;</code>
       */
      public com.google.protobuf.ByteString
          getSerializedOriginBytes() {
        return instance.getSerializedOriginBytes();
      }
      /**
       * <pre>
       * A serialzied origin as defined in:
       * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
       * For example: "https://www.youtube.com"
       * </pre>
       *
       * <code>optional string serialized_origin = 1;</code>
       */
      public Builder setSerializedOrigin(
          java.lang.String value) {
        copyOnWrite();
        instance.setSerializedOrigin(value);
        return this;
      }
      /**
       * <pre>
       * A serialzied origin as defined in:
       * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
       * For example: "https://www.youtube.com"
       * </pre>
       *
       * <code>optional string serialized_origin = 1;</code>
       */
      public Builder clearSerializedOrigin() {
        copyOnWrite();
        instance.clearSerializedOrigin();
        return this;
      }
      /**
       * <pre>
       * A serialzied origin as defined in:
       * https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin.
       * For example: "https://www.youtube.com"
       * </pre>
       *
       * <code>optional string serialized_origin = 1;</code>
       */
      public Builder setSerializedOriginBytes(
          com.google.protobuf.ByteString value) {
        copyOnWrite();
        instance.setSerializedOriginBytes(value);
        return this;
      }

      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public java.util.List<dev.cobalt.storage.StorageProto.LocalStorageEntry> getLocalStorageEntriesList() {
        return java.util.Collections.unmodifiableList(
            instance.getLocalStorageEntriesList());
      }
      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public int getLocalStorageEntriesCount() {
        return instance.getLocalStorageEntriesCount();
      }/**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public dev.cobalt.storage.StorageProto.LocalStorageEntry getLocalStorageEntries(int index) {
        return instance.getLocalStorageEntries(index);
      }
      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public Builder setLocalStorageEntries(
          int index, dev.cobalt.storage.StorageProto.LocalStorageEntry value) {
        copyOnWrite();
        instance.setLocalStorageEntries(index, value);
        return this;
      }
      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public Builder setLocalStorageEntries(
          int index, dev.cobalt.storage.StorageProto.LocalStorageEntry.Builder builderForValue) {
        copyOnWrite();
        instance.setLocalStorageEntries(index, builderForValue);
        return this;
      }
      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public Builder addLocalStorageEntries(dev.cobalt.storage.StorageProto.LocalStorageEntry value) {
        copyOnWrite();
        instance.addLocalStorageEntries(value);
        return this;
      }
      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public Builder addLocalStorageEntries(
          int index, dev.cobalt.storage.StorageProto.LocalStorageEntry value) {
        copyOnWrite();
        instance.addLocalStorageEntries(index, value);
        return this;
      }
      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public Builder addLocalStorageEntries(
          dev.cobalt.storage.StorageProto.LocalStorageEntry.Builder builderForValue) {
        copyOnWrite();
        instance.addLocalStorageEntries(builderForValue);
        return this;
      }
      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public Builder addLocalStorageEntries(
          int index, dev.cobalt.storage.StorageProto.LocalStorageEntry.Builder builderForValue) {
        copyOnWrite();
        instance.addLocalStorageEntries(index, builderForValue);
        return this;
      }
      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public Builder addAllLocalStorageEntries(
          java.lang.Iterable<? extends dev.cobalt.storage.StorageProto.LocalStorageEntry> values) {
        copyOnWrite();
        instance.addAllLocalStorageEntries(values);
        return this;
      }
      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public Builder clearLocalStorageEntries() {
        copyOnWrite();
        instance.clearLocalStorageEntries();
        return this;
      }
      /**
       * <pre>
       * The local storage entries for individual local storage.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorageEntry local_storage_entries = 2;</code>
       */
      public Builder removeLocalStorageEntries(int index) {
        copyOnWrite();
        instance.removeLocalStorageEntries(index);
        return this;
      }

      // @@protoc_insertion_point(builder_scope:cobalt.storage.LocalStorage)
    }
    protected final Object dynamicMethod(
        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
        Object arg0, Object arg1) {
      switch (method) {
        case NEW_MUTABLE_INSTANCE: {
          return new dev.cobalt.storage.StorageProto.LocalStorage();
        }
        case IS_INITIALIZED: {
          return DEFAULT_INSTANCE;
        }
        case MAKE_IMMUTABLE: {
          localStorageEntries_.makeImmutable();
          return null;
        }
        case NEW_BUILDER: {
          return new Builder();
        }
        case VISIT: {
          Visitor visitor = (Visitor) arg0;
          dev.cobalt.storage.StorageProto.LocalStorage other = (dev.cobalt.storage.StorageProto.LocalStorage) arg1;
          serializedOrigin_ = visitor.visitString(!serializedOrigin_.isEmpty(), serializedOrigin_,
              !other.serializedOrigin_.isEmpty(), other.serializedOrigin_);
          localStorageEntries_= visitor.visitList(localStorageEntries_, other.localStorageEntries_);
          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor
              .INSTANCE) {
            bitField0_ |= other.bitField0_;
          }
          return this;
        }
        case MERGE_FROM_STREAM: {
          com.google.protobuf.CodedInputStream input =
              (com.google.protobuf.CodedInputStream) arg0;
          com.google.protobuf.ExtensionRegistryLite extensionRegistry =
              (com.google.protobuf.ExtensionRegistryLite) arg1;
          try {
            boolean done = false;
            while (!done) {
              int tag = input.readTag();
              switch (tag) {
                case 0:
                  done = true;
                  break;
                default: {
                  if (!input.skipField(tag)) {
                    done = true;
                  }
                  break;
                }
                case 10: {
                  String s = input.readStringRequireUtf8();

                  serializedOrigin_ = s;
                  break;
                }
                case 18: {
                  if (!localStorageEntries_.isModifiable()) {
                    localStorageEntries_ =
                        com.google.protobuf.GeneratedMessageLite.mutableCopy(localStorageEntries_);
                  }
                  localStorageEntries_.add(
                      input.readMessage(dev.cobalt.storage.StorageProto.LocalStorageEntry.parser(), extensionRegistry));
                  break;
                }
              }
            }
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            throw new RuntimeException(e.setUnfinishedMessage(this));
          } catch (java.io.IOException e) {
            throw new RuntimeException(
                new com.google.protobuf.InvalidProtocolBufferException(
                    e.getMessage()).setUnfinishedMessage(this));
          } finally {
          }
        }
        case GET_DEFAULT_INSTANCE: {
          return DEFAULT_INSTANCE;
        }
        case GET_PARSER: {
          if (PARSER == null) {    synchronized (dev.cobalt.storage.StorageProto.LocalStorage.class) {
              if (PARSER == null) {
                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);
              }
            }
          }
          return PARSER;
        }
      }
      throw new UnsupportedOperationException();
    }


    // @@protoc_insertion_point(class_scope:cobalt.storage.LocalStorage)
    private static final dev.cobalt.storage.StorageProto.LocalStorage DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new LocalStorage();
      DEFAULT_INSTANCE.makeImmutable();
    }

    public static dev.cobalt.storage.StorageProto.LocalStorage getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static volatile com.google.protobuf.Parser<LocalStorage> PARSER;

    public static com.google.protobuf.Parser<LocalStorage> parser() {
      return DEFAULT_INSTANCE.getParserForType();
    }
  }

  public interface StorageOrBuilder extends
      // @@protoc_insertion_point(interface_extends:cobalt.storage.Storage)
      com.google.protobuf.MessageLiteOrBuilder {

    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    java.util.List<dev.cobalt.storage.StorageProto.Cookie> 
        getCookiesList();
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    dev.cobalt.storage.StorageProto.Cookie getCookies(int index);
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    int getCookiesCount();

    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    java.util.List<dev.cobalt.storage.StorageProto.LocalStorage> 
        getLocalStoragesList();
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    dev.cobalt.storage.StorageProto.LocalStorage getLocalStorages(int index);
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    int getLocalStoragesCount();
  }
  /**
   * <pre>
   * The full storage.
   * </pre>
   *
   * Protobuf type {@code cobalt.storage.Storage}
   */
  public  static final class Storage extends
      com.google.protobuf.GeneratedMessageLite<
          Storage, Storage.Builder> implements
      // @@protoc_insertion_point(message_implements:cobalt.storage.Storage)
      StorageOrBuilder {
    private Storage() {
      cookies_ = emptyProtobufList();
      localStorages_ = emptyProtobufList();
    }
    public static final int COOKIES_FIELD_NUMBER = 1;
    private com.google.protobuf.Internal.ProtobufList<dev.cobalt.storage.StorageProto.Cookie> cookies_;
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    public java.util.List<dev.cobalt.storage.StorageProto.Cookie> getCookiesList() {
      return cookies_;
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    public java.util.List<? extends dev.cobalt.storage.StorageProto.CookieOrBuilder> 
        getCookiesOrBuilderList() {
      return cookies_;
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    public int getCookiesCount() {
      return cookies_.size();
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    public dev.cobalt.storage.StorageProto.Cookie getCookies(int index) {
      return cookies_.get(index);
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    public dev.cobalt.storage.StorageProto.CookieOrBuilder getCookiesOrBuilder(
        int index) {
      return cookies_.get(index);
    }
    private void ensureCookiesIsMutable() {
      if (!cookies_.isModifiable()) {
        cookies_ =
            com.google.protobuf.GeneratedMessageLite.mutableCopy(cookies_);
       }
    }

    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    private void setCookies(
        int index, dev.cobalt.storage.StorageProto.Cookie value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureCookiesIsMutable();
      cookies_.set(index, value);
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    private void setCookies(
        int index, dev.cobalt.storage.StorageProto.Cookie.Builder builderForValue) {
      ensureCookiesIsMutable();
      cookies_.set(index, builderForValue.build());
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    private void addCookies(dev.cobalt.storage.StorageProto.Cookie value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureCookiesIsMutable();
      cookies_.add(value);
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    private void addCookies(
        int index, dev.cobalt.storage.StorageProto.Cookie value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureCookiesIsMutable();
      cookies_.add(index, value);
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    private void addCookies(
        dev.cobalt.storage.StorageProto.Cookie.Builder builderForValue) {
      ensureCookiesIsMutable();
      cookies_.add(builderForValue.build());
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    private void addCookies(
        int index, dev.cobalt.storage.StorageProto.Cookie.Builder builderForValue) {
      ensureCookiesIsMutable();
      cookies_.add(index, builderForValue.build());
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    private void addAllCookies(
        java.lang.Iterable<? extends dev.cobalt.storage.StorageProto.Cookie> values) {
      ensureCookiesIsMutable();
      com.google.protobuf.AbstractMessageLite.addAll(
          values, cookies_);
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    private void clearCookies() {
      cookies_ = emptyProtobufList();
    }
    /**
     * <pre>
     * All the cookies.
     * </pre>
     *
     * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
     */
    private void removeCookies(int index) {
      ensureCookiesIsMutable();
      cookies_.remove(index);
    }

    public static final int LOCAL_STORAGES_FIELD_NUMBER = 2;
    private com.google.protobuf.Internal.ProtobufList<dev.cobalt.storage.StorageProto.LocalStorage> localStorages_;
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    public java.util.List<dev.cobalt.storage.StorageProto.LocalStorage> getLocalStoragesList() {
      return localStorages_;
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    public java.util.List<? extends dev.cobalt.storage.StorageProto.LocalStorageOrBuilder> 
        getLocalStoragesOrBuilderList() {
      return localStorages_;
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    public int getLocalStoragesCount() {
      return localStorages_.size();
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    public dev.cobalt.storage.StorageProto.LocalStorage getLocalStorages(int index) {
      return localStorages_.get(index);
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    public dev.cobalt.storage.StorageProto.LocalStorageOrBuilder getLocalStoragesOrBuilder(
        int index) {
      return localStorages_.get(index);
    }
    private void ensureLocalStoragesIsMutable() {
      if (!localStorages_.isModifiable()) {
        localStorages_ =
            com.google.protobuf.GeneratedMessageLite.mutableCopy(localStorages_);
       }
    }

    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    private void setLocalStorages(
        int index, dev.cobalt.storage.StorageProto.LocalStorage value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureLocalStoragesIsMutable();
      localStorages_.set(index, value);
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    private void setLocalStorages(
        int index, dev.cobalt.storage.StorageProto.LocalStorage.Builder builderForValue) {
      ensureLocalStoragesIsMutable();
      localStorages_.set(index, builderForValue.build());
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    private void addLocalStorages(dev.cobalt.storage.StorageProto.LocalStorage value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureLocalStoragesIsMutable();
      localStorages_.add(value);
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    private void addLocalStorages(
        int index, dev.cobalt.storage.StorageProto.LocalStorage value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureLocalStoragesIsMutable();
      localStorages_.add(index, value);
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    private void addLocalStorages(
        dev.cobalt.storage.StorageProto.LocalStorage.Builder builderForValue) {
      ensureLocalStoragesIsMutable();
      localStorages_.add(builderForValue.build());
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    private void addLocalStorages(
        int index, dev.cobalt.storage.StorageProto.LocalStorage.Builder builderForValue) {
      ensureLocalStoragesIsMutable();
      localStorages_.add(index, builderForValue.build());
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    private void addAllLocalStorages(
        java.lang.Iterable<? extends dev.cobalt.storage.StorageProto.LocalStorage> values) {
      ensureLocalStoragesIsMutable();
      com.google.protobuf.AbstractMessageLite.addAll(
          values, localStorages_);
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    private void clearLocalStorages() {
      localStorages_ = emptyProtobufList();
    }
    /**
     * <pre>
     * All local storages.
     * </pre>
     *
     * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
     */
    private void removeLocalStorages(int index) {
      ensureLocalStoragesIsMutable();
      localStorages_.remove(index);
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      for (int i = 0; i < cookies_.size(); i++) {
        output.writeMessage(1, cookies_.get(i));
      }
      for (int i = 0; i < localStorages_.size(); i++) {
        output.writeMessage(2, localStorages_.get(i));
      }
    }

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

      size = 0;
      for (int i = 0; i < cookies_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, cookies_.get(i));
      }
      for (int i = 0; i < localStorages_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, localStorages_.get(i));
      }
      memoizedSerializedSize = size;
      return size;
    }

    public static dev.cobalt.storage.StorageProto.Storage parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data);
    }
    public static dev.cobalt.storage.StorageProto.Storage parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.Storage parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data);
    }
    public static dev.cobalt.storage.StorageProto.Storage parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, data, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.Storage parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.Storage parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.Storage parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return parseDelimitedFrom(DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.Storage parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);
    }
    public static dev.cobalt.storage.StorageProto.Storage parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input);
    }
    public static dev.cobalt.storage.StorageProto.Storage parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageLite.parseFrom(
          DEFAULT_INSTANCE, input, extensionRegistry);
    }

    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(dev.cobalt.storage.StorageProto.Storage prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }

    /**
     * <pre>
     * The full storage.
     * </pre>
     *
     * Protobuf type {@code cobalt.storage.Storage}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageLite.Builder<
          dev.cobalt.storage.StorageProto.Storage, Builder> implements
        // @@protoc_insertion_point(builder_implements:cobalt.storage.Storage)
        dev.cobalt.storage.StorageProto.StorageOrBuilder {
      // Construct using dev.cobalt.storage.StorageProto.Storage.newBuilder()
      private Builder() {
        super(DEFAULT_INSTANCE);
      }


      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public java.util.List<dev.cobalt.storage.StorageProto.Cookie> getCookiesList() {
        return java.util.Collections.unmodifiableList(
            instance.getCookiesList());
      }
      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public int getCookiesCount() {
        return instance.getCookiesCount();
      }/**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public dev.cobalt.storage.StorageProto.Cookie getCookies(int index) {
        return instance.getCookies(index);
      }
      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public Builder setCookies(
          int index, dev.cobalt.storage.StorageProto.Cookie value) {
        copyOnWrite();
        instance.setCookies(index, value);
        return this;
      }
      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public Builder setCookies(
          int index, dev.cobalt.storage.StorageProto.Cookie.Builder builderForValue) {
        copyOnWrite();
        instance.setCookies(index, builderForValue);
        return this;
      }
      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public Builder addCookies(dev.cobalt.storage.StorageProto.Cookie value) {
        copyOnWrite();
        instance.addCookies(value);
        return this;
      }
      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public Builder addCookies(
          int index, dev.cobalt.storage.StorageProto.Cookie value) {
        copyOnWrite();
        instance.addCookies(index, value);
        return this;
      }
      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public Builder addCookies(
          dev.cobalt.storage.StorageProto.Cookie.Builder builderForValue) {
        copyOnWrite();
        instance.addCookies(builderForValue);
        return this;
      }
      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public Builder addCookies(
          int index, dev.cobalt.storage.StorageProto.Cookie.Builder builderForValue) {
        copyOnWrite();
        instance.addCookies(index, builderForValue);
        return this;
      }
      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public Builder addAllCookies(
          java.lang.Iterable<? extends dev.cobalt.storage.StorageProto.Cookie> values) {
        copyOnWrite();
        instance.addAllCookies(values);
        return this;
      }
      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public Builder clearCookies() {
        copyOnWrite();
        instance.clearCookies();
        return this;
      }
      /**
       * <pre>
       * All the cookies.
       * </pre>
       *
       * <code>repeated .cobalt.storage.Cookie cookies = 1;</code>
       */
      public Builder removeCookies(int index) {
        copyOnWrite();
        instance.removeCookies(index);
        return this;
      }

      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public java.util.List<dev.cobalt.storage.StorageProto.LocalStorage> getLocalStoragesList() {
        return java.util.Collections.unmodifiableList(
            instance.getLocalStoragesList());
      }
      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public int getLocalStoragesCount() {
        return instance.getLocalStoragesCount();
      }/**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public dev.cobalt.storage.StorageProto.LocalStorage getLocalStorages(int index) {
        return instance.getLocalStorages(index);
      }
      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public Builder setLocalStorages(
          int index, dev.cobalt.storage.StorageProto.LocalStorage value) {
        copyOnWrite();
        instance.setLocalStorages(index, value);
        return this;
      }
      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public Builder setLocalStorages(
          int index, dev.cobalt.storage.StorageProto.LocalStorage.Builder builderForValue) {
        copyOnWrite();
        instance.setLocalStorages(index, builderForValue);
        return this;
      }
      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public Builder addLocalStorages(dev.cobalt.storage.StorageProto.LocalStorage value) {
        copyOnWrite();
        instance.addLocalStorages(value);
        return this;
      }
      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public Builder addLocalStorages(
          int index, dev.cobalt.storage.StorageProto.LocalStorage value) {
        copyOnWrite();
        instance.addLocalStorages(index, value);
        return this;
      }
      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public Builder addLocalStorages(
          dev.cobalt.storage.StorageProto.LocalStorage.Builder builderForValue) {
        copyOnWrite();
        instance.addLocalStorages(builderForValue);
        return this;
      }
      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public Builder addLocalStorages(
          int index, dev.cobalt.storage.StorageProto.LocalStorage.Builder builderForValue) {
        copyOnWrite();
        instance.addLocalStorages(index, builderForValue);
        return this;
      }
      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public Builder addAllLocalStorages(
          java.lang.Iterable<? extends dev.cobalt.storage.StorageProto.LocalStorage> values) {
        copyOnWrite();
        instance.addAllLocalStorages(values);
        return this;
      }
      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public Builder clearLocalStorages() {
        copyOnWrite();
        instance.clearLocalStorages();
        return this;
      }
      /**
       * <pre>
       * All local storages.
       * </pre>
       *
       * <code>repeated .cobalt.storage.LocalStorage local_storages = 2;</code>
       */
      public Builder removeLocalStorages(int index) {
        copyOnWrite();
        instance.removeLocalStorages(index);
        return this;
      }

      // @@protoc_insertion_point(builder_scope:cobalt.storage.Storage)
    }
    protected final Object dynamicMethod(
        com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
        Object arg0, Object arg1) {
      switch (method) {
        case NEW_MUTABLE_INSTANCE: {
          return new dev.cobalt.storage.StorageProto.Storage();
        }
        case IS_INITIALIZED: {
          return DEFAULT_INSTANCE;
        }
        case MAKE_IMMUTABLE: {
          cookies_.makeImmutable();
          localStorages_.makeImmutable();
          return null;
        }
        case NEW_BUILDER: {
          return new Builder();
        }
        case VISIT: {
          Visitor visitor = (Visitor) arg0;
          dev.cobalt.storage.StorageProto.Storage other = (dev.cobalt.storage.StorageProto.Storage) arg1;
          cookies_= visitor.visitList(cookies_, other.cookies_);
          localStorages_= visitor.visitList(localStorages_, other.localStorages_);
          if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor
              .INSTANCE) {
          }
          return this;
        }
        case MERGE_FROM_STREAM: {
          com.google.protobuf.CodedInputStream input =
              (com.google.protobuf.CodedInputStream) arg0;
          com.google.protobuf.ExtensionRegistryLite extensionRegistry =
              (com.google.protobuf.ExtensionRegistryLite) arg1;
          try {
            boolean done = false;
            while (!done) {
              int tag = input.readTag();
              switch (tag) {
                case 0:
                  done = true;
                  break;
                default: {
                  if (!input.skipField(tag)) {
                    done = true;
                  }
                  break;
                }
                case 10: {
                  if (!cookies_.isModifiable()) {
                    cookies_ =
                        com.google.protobuf.GeneratedMessageLite.mutableCopy(cookies_);
                  }
                  cookies_.add(
                      input.readMessage(dev.cobalt.storage.StorageProto.Cookie.parser(), extensionRegistry));
                  break;
                }
                case 18: {
                  if (!localStorages_.isModifiable()) {
                    localStorages_ =
                        com.google.protobuf.GeneratedMessageLite.mutableCopy(localStorages_);
                  }
                  localStorages_.add(
                      input.readMessage(dev.cobalt.storage.StorageProto.LocalStorage.parser(), extensionRegistry));
                  break;
                }
              }
            }
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            throw new RuntimeException(e.setUnfinishedMessage(this));
          } catch (java.io.IOException e) {
            throw new RuntimeException(
                new com.google.protobuf.InvalidProtocolBufferException(
                    e.getMessage()).setUnfinishedMessage(this));
          } finally {
          }
        }
        case GET_DEFAULT_INSTANCE: {
          return DEFAULT_INSTANCE;
        }
        case GET_PARSER: {
          if (PARSER == null) {    synchronized (dev.cobalt.storage.StorageProto.Storage.class) {
              if (PARSER == null) {
                PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);
              }
            }
          }
          return PARSER;
        }
      }
      throw new UnsupportedOperationException();
    }


    // @@protoc_insertion_point(class_scope:cobalt.storage.Storage)
    private static final dev.cobalt.storage.StorageProto.Storage DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new Storage();
      DEFAULT_INSTANCE.makeImmutable();
    }

    public static dev.cobalt.storage.StorageProto.Storage getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static volatile com.google.protobuf.Parser<Storage> PARSER;

    public static com.google.protobuf.Parser<Storage> parser() {
      return DEFAULT_INSTANCE.getParserForType();
    }
  }


  static {
  }

  // @@protoc_insertion_point(outer_class_scope)
}
