2 * Copyright 2011 Google Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.google.ipc.invalidation.ticl;
19 import com.google.common.base.Preconditions;
20 import com.google.protobuf.AbstractMessageLite;
22 import java.util.Arrays;
25 * Wraps a Lite protobuf type and provides appropriate {@link #equals} and {@link #hashCode}
26 * implementations so the wrapped object can be stored in a Java collection and/or compared to other
27 * wrapped proto instances of the same type for equality. This is necessary because protobuf classes
28 * generated with the {@code LITE_RUNTIME} optimization do not have custom implementations of these
29 * methods (so only support simple object equivalence).
31 * @param <P> the protobuf message lite type that is being wrapped.
33 public class ProtoWrapper<P extends AbstractMessageLite> {
35 /** The wrapped proto object */
36 private final P proto;
38 /** The serialized byte representation of the wrapped object */
39 private final byte [] protoBytes;
41 /** The hash code of the serialized representation */
42 private final int hashCode;
44 /** Returns a ProtoWrapper that wraps the provided object */
45 public static <M extends AbstractMessageLite> ProtoWrapper<M> of(M proto) {
46 return new ProtoWrapper<M>(proto);
49 // Internal constructor that savees the object and computes serialized state and hash code.
50 private ProtoWrapper(P proto) {
51 this.proto = Preconditions.checkNotNull(proto);
52 this.protoBytes = proto.toByteArray();
53 this.hashCode = Arrays.hashCode(protoBytes);
56 /** Returns the wrapped proto object */
61 /** Returns the hash code of the serialized state representation of the protobuf object */
63 public int hashCode() {
68 * Returns {@code true} if the provided object is a proto wrapper of an object of the same
69 * protobuf type that has the same serialized state representation.
72 public boolean equals(Object o) {
73 Class<?> msgClass = proto.getClass();
74 if (!(o instanceof ProtoWrapper)) {
77 @SuppressWarnings("rawtypes")
78 ProtoWrapper<?> wrapper = (ProtoWrapper) o;
79 if (proto.getClass() != wrapper.proto.getClass()) {
82 if (hashCode != wrapper.hashCode) {
85 return Arrays.equals(protoBytes, wrapper.protoBytes);
89 public String toString() {
90 // Don't print exactly the protocol buffer because that could be extremely confusing when
91 // debugging, since this object isn't actually a protocol buffer.
92 return "PW-" + proto.toString();