@Override
 public String toString() {
   StringBuilder builder = new StringBuilder();
   builder.append("TYPE => THROTTLE");
   if (proto.hasType()) {
     builder.append(", THROTTLE_TYPE => ");
     builder.append(proto.getType().toString());
   }
   if (proto.hasTimedQuota()) {
     QuotaProtos.TimedQuota timedQuota = proto.getTimedQuota();
     builder.append(", LIMIT => ");
     if (timedQuota.hasSoftLimit()) {
       switch (getThrottleType()) {
         case REQUEST_NUMBER:
         case WRITE_NUMBER:
         case READ_NUMBER:
           builder.append(String.format("%dreq", timedQuota.getSoftLimit()));
           break;
         case REQUEST_SIZE:
         case WRITE_SIZE:
         case READ_SIZE:
           builder.append(sizeToString(timedQuota.getSoftLimit()));
           break;
       }
     } else if (timedQuota.hasShare()) {
       builder.append(String.format("%.2f%%", timedQuota.getShare()));
     }
     builder.append('/');
     builder.append(timeToString(ProtobufUtil.toTimeUnit(timedQuota.getTimeUnit())));
     if (timedQuota.hasScope()) {
       builder.append(", SCOPE => ");
       builder.append(timedQuota.getScope().toString());
     }
   } else {
     builder.append(", LIMIT => NONE");
   }
   return builder.toString();
 }
 private static void setFromTimedQuota(final RateLimiter limiter, final TimedQuota timedQuota) {
   limiter.set(timedQuota.getSoftLimit(), ProtobufUtil.toTimeUnit(timedQuota.getTimeUnit()));
 }
 public TimeUnit getTimeUnit() {
   return proto.hasTimedQuota()
       ? ProtobufUtil.toTimeUnit(proto.getTimedQuota().getTimeUnit())
       : null;
 }