| Index: third_party/protobuf/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java | 
| diff --git a/third_party/protobuf/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java b/third_party/protobuf/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java | 
| index 0fbf4d401c404ebd8c4c759cb8c4fd88030a70aa..878c77581663e7d4c2ea40811f43e38d0dd5c0a2 100644 | 
| --- a/third_party/protobuf/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java | 
| +++ b/third_party/protobuf/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java | 
| @@ -42,6 +42,23 @@ import java.nio.ByteBuffer; | 
| * guaranteed that the buffer backing the {@link ByteString} will never change! Mutation of a | 
| * {@link ByteString} can lead to unexpected and undesirable consequences in your application, | 
| * and will likely be difficult to debug. Proceed with caution! | 
| + * | 
| + * <p>This can have a number of significant side affects that have | 
| + * spooky-action-at-a-distance-like behavior. In particular, if the bytes value changes out from | 
| + * under a Protocol Buffer: | 
| + * <ul> | 
| + * <li>serialization may throw | 
| + * <li>serialization may succeed but the wrong bytes may be written out | 
| + * <li>messages are no longer threadsafe | 
| + * <li>hashCode may be incorrect | 
| + *   <ul> | 
| + *   <li>can result in a permanent memory leak when used as a key in a long-lived HashMap | 
| + *   <li> the semantics of many programs may be violated if this is the case | 
| + *   </ul> | 
| + * </ul> | 
| + * Each of these issues will occur in parts of the code base that are entirely distinct from the | 
| + * parts of the code base modifying the buffer. In fact, both parts of the code base may be correct | 
| + * - it is the bridging with the unsafe operations that was in error! | 
| */ | 
| @ExperimentalApi | 
| public final class UnsafeByteOperations { | 
| @@ -50,16 +67,34 @@ public final class UnsafeByteOperations { | 
| /** | 
| * An unsafe operation that returns a {@link ByteString} that is backed by the provided buffer. | 
| * | 
| +   * @param buffer the buffer to be wrapped | 
| +   * @return a {@link ByteString} backed by the provided buffer | 
| +   */ | 
| +  public static ByteString unsafeWrap(byte[] buffer) { | 
| +    return ByteString.wrap(buffer); | 
| +  } | 
| + | 
| +  /** | 
| +   * An unsafe operation that returns a {@link ByteString} that is backed by a subregion of the | 
| +   * provided buffer. | 
| +   * | 
| +   * @param buffer the buffer to be wrapped | 
| +   * @param offset the offset of the wrapped region | 
| +   * @param length the number of bytes of the wrapped region | 
| +   * @return a {@link ByteString} backed by the provided buffer | 
| +   */ | 
| +  public static ByteString unsafeWrap(byte[] buffer, int offset, int length) { | 
| +    return ByteString.wrap(buffer, offset, length); | 
| +  } | 
| + | 
| +  /** | 
| +   * An unsafe operation that returns a {@link ByteString} that is backed by the provided buffer. | 
| +   * | 
| * @param buffer the Java NIO buffer to be wrapped | 
| * @return a {@link ByteString} backed by the provided buffer | 
| */ | 
| public static ByteString unsafeWrap(ByteBuffer buffer) { | 
| -    if (buffer.hasArray()) { | 
| -      final int offset = buffer.arrayOffset(); | 
| -      return ByteString.wrap(buffer.array(), offset + buffer.position(), buffer.remaining()); | 
| -    } else { | 
| -      return new NioByteString(buffer); | 
| -    } | 
| +    return ByteString.wrap(buffer); | 
| } | 
|  | 
| /** | 
| @@ -81,4 +116,5 @@ public final class UnsafeByteOperations { | 
| public static void unsafeWriteTo(ByteString bytes, ByteOutput output) throws IOException { | 
| bytes.writeTo(output); | 
| } | 
| + | 
| } | 
|  |