| Index: third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapEntry.java | 
| diff --git a/third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapEntry.java b/third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapEntry.java | 
| index 31414bb49abb09d44b72933c6e4b5dd2df919f60..4f0351f4813accf11175a9f3ce9df5a42570539a 100644 | 
| --- a/third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapEntry.java | 
| +++ b/third_party/protobuf/java/core/src/main/java/com/google/protobuf/MapEntry.java | 
| @@ -41,63 +41,83 @@ import java.util.TreeMap; | 
|  | 
| /** | 
| * Implements MapEntry messages. | 
| - * | 
| + * | 
| * In reflection API, map fields will be treated as repeated message fields and | 
| * each map entry is accessed as a message. This MapEntry class is used to | 
| * represent these map entry messages in reflection API. | 
| - * | 
| + * | 
| * Protobuf internal. Users shouldn't use this class. | 
| */ | 
| public final class MapEntry<K, V> extends AbstractMessage { | 
| -  private static class Metadata<K, V> { | 
| -    public final Descriptor descriptor; | 
| -    public final MapEntry<K, V> defaultInstance; | 
| -    public final AbstractParser<MapEntry<K, V>> parser; | 
| - | 
| + | 
| +  private static final class Metadata<K, V> extends MapEntryLite.Metadata<K, V> { | 
| + | 
| +    public final Descriptor descriptor; | 
| +    public final Parser<MapEntry<K, V>> parser; | 
| + | 
| public Metadata( | 
| -        final Descriptor descriptor, final MapEntry<K, V> defaultInstance) { | 
| +        Descriptor descriptor, | 
| +        MapEntry<K, V> defaultInstance, | 
| +        WireFormat.FieldType keyType, | 
| +        WireFormat.FieldType valueType) { | 
| +      super(keyType, defaultInstance.key, valueType, defaultInstance.value); | 
| this.descriptor = descriptor; | 
| -      this.defaultInstance = defaultInstance; | 
| -      final Metadata<K, V> thisMetadata = this; | 
| this.parser = new AbstractParser<MapEntry<K, V>>() { | 
| -        private final Parser<MapEntryLite<K, V>> dataParser = | 
| -            defaultInstance.data.getParserForType(); | 
| + | 
| @Override | 
| public MapEntry<K, V> parsePartialFrom( | 
| CodedInputStream input, ExtensionRegistryLite extensionRegistry) | 
| throws InvalidProtocolBufferException { | 
| -          MapEntryLite<K, V> data = | 
| -              dataParser.parsePartialFrom(input, extensionRegistry); | 
| -          return new MapEntry<K, V>(thisMetadata, data); | 
| +          return new MapEntry<K, V>(Metadata.this, input, extensionRegistry); | 
| } | 
| - | 
| }; | 
| } | 
| } | 
| - | 
| + | 
| +  private final K key; | 
| +  private final V value; | 
| private final Metadata<K, V> metadata; | 
| -  private final MapEntryLite<K, V> data; | 
| - | 
| + | 
| /** Create a default MapEntry instance. */ | 
| -  private MapEntry(Descriptor descriptor, | 
| +  private MapEntry( | 
| +      Descriptor descriptor, | 
| WireFormat.FieldType keyType, K defaultKey, | 
| WireFormat.FieldType valueType, V defaultValue) { | 
| -    this.data = MapEntryLite.newDefaultInstance( | 
| -        keyType, defaultKey, valueType, defaultValue); | 
| -    this.metadata = new Metadata<K, V>(descriptor, this); | 
| +    this.key = defaultKey; | 
| +    this.value = defaultValue; | 
| +    this.metadata = new Metadata<K, V>(descriptor, this, keyType, valueType); | 
| } | 
| - | 
| -  /** Create a new MapEntry message. */ | 
| -  private MapEntry(Metadata<K, V> metadata, MapEntryLite<K, V> data) { | 
| + | 
| +  /** Create a MapEntry with the provided key and value. */ | 
| +  private MapEntry(Metadata metadata, K key, V value) { | 
| +    this.key = key; | 
| +    this.value = value; | 
| this.metadata = metadata; | 
| -    this.data = data; | 
| } | 
| - | 
| + | 
| +  /** Parsing constructor. */ | 
| +  private MapEntry( | 
| +      Metadata<K, V> metadata, | 
| +      CodedInputStream input, | 
| +      ExtensionRegistryLite extensionRegistry) | 
| +      throws InvalidProtocolBufferException { | 
| +    try { | 
| +      this.metadata = metadata; | 
| +      Map.Entry<K, V> entry = MapEntryLite.parseEntry(input, metadata, extensionRegistry); | 
| +      this.key = entry.getKey(); | 
| +      this.value = entry.getValue(); | 
| +    } catch (InvalidProtocolBufferException e) { | 
| +      throw e.setUnfinishedMessage(this); | 
| +    } catch (IOException e) { | 
| +      throw new InvalidProtocolBufferException(e.getMessage()).setUnfinishedMessage(this); | 
| +    } | 
| +  } | 
| + | 
| /** | 
| * Create a default MapEntry instance. A default MapEntry instance should be | 
| * created only once for each map entry message type. Generated code should | 
| * store the created default instance and use it later to create new MapEntry | 
| -   * messages of the same type. | 
| +   * messages of the same type. | 
| */ | 
| public static <K, V> MapEntry<K, V> newDefaultInstance( | 
| Descriptor descriptor, | 
| @@ -106,30 +126,38 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
| return new MapEntry<K, V>( | 
| descriptor, keyType, defaultKey, valueType, defaultValue); | 
| } | 
| - | 
| + | 
| public K getKey() { | 
| -    return data.getKey(); | 
| +    return key; | 
| } | 
| - | 
| + | 
| public V getValue() { | 
| -    return data.getValue(); | 
| +    return value; | 
| } | 
| - | 
| + | 
| +  private volatile int cachedSerializedSize = -1; | 
| + | 
| @Override | 
| public int getSerializedSize() { | 
| -    return data.getSerializedSize(); | 
| +    if (cachedSerializedSize != -1) { | 
| +      return cachedSerializedSize; | 
| +    } | 
| + | 
| +    int size = MapEntryLite.computeSerializedSize(metadata, key, value); | 
| +    cachedSerializedSize = size; | 
| +    return size; | 
| } | 
| - | 
| + | 
| @Override | 
| public void writeTo(CodedOutputStream output) throws IOException { | 
| -    data.writeTo(output); | 
| +    MapEntryLite.writeTo(output, metadata, key, value); | 
| } | 
| - | 
| + | 
| @Override | 
| public boolean isInitialized() { | 
| -    return data.isInitialized(); | 
| +    return isInitialized(metadata, value); | 
| } | 
| - | 
| + | 
| @Override | 
| public Parser<MapEntry<K, V>> getParserForType() { | 
| return metadata.parser; | 
| @@ -139,15 +167,15 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
| public Builder<K, V> newBuilderForType() { | 
| return new Builder<K, V>(metadata); | 
| } | 
| - | 
| + | 
| @Override | 
| public Builder<K, V> toBuilder() { | 
| -    return new Builder<K, V>(metadata, data); | 
| +    return new Builder<K, V>(metadata, key, value); | 
| } | 
|  | 
| @Override | 
| public MapEntry<K, V> getDefaultInstanceForType() { | 
| -    return metadata.defaultInstance; | 
| +    return new MapEntry<K, V>(metadata, metadata.defaultKey, metadata.defaultValue); | 
| } | 
|  | 
| @Override | 
| @@ -157,8 +185,7 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
|  | 
| @Override | 
| public Map<FieldDescriptor, Object> getAllFields() { | 
| -    final TreeMap<FieldDescriptor, Object> result = | 
| -        new TreeMap<FieldDescriptor, Object>(); | 
| +    TreeMap<FieldDescriptor, Object> result = new TreeMap<FieldDescriptor, Object>(); | 
| for (final FieldDescriptor field : metadata.descriptor.getFields()) { | 
| if (hasField(field)) { | 
| result.put(field, getField(field)); | 
| @@ -166,12 +193,12 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
| } | 
| return Collections.unmodifiableMap(result); | 
| } | 
| - | 
| + | 
| private void checkFieldDescriptor(FieldDescriptor field) { | 
| if (field.getContainingType() != metadata.descriptor) { | 
| throw new RuntimeException( | 
| "Wrong FieldDescriptor \"" + field.getFullName() | 
| -          + "\" used in message \"" + metadata.descriptor.getFullName()); | 
| +          + "\" used in message \"" + metadata.descriptor.getFullName()); | 
| } | 
| } | 
|  | 
| @@ -217,56 +244,44 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
| public static class Builder<K, V> | 
| extends AbstractMessage.Builder<Builder<K, V>> { | 
| private final Metadata<K, V> metadata; | 
| -    private MapEntryLite<K, V> data; | 
| -    private MapEntryLite.Builder<K, V> dataBuilder; | 
| - | 
| +    private K key; | 
| +    private V value; | 
| + | 
| private Builder(Metadata<K, V> metadata) { | 
| -      this.metadata = metadata; | 
| -      this.data = metadata.defaultInstance.data; | 
| -      this.dataBuilder = null; | 
| +      this(metadata, metadata.defaultKey, metadata.defaultValue); | 
| } | 
| - | 
| -    private Builder(Metadata<K, V> metadata, MapEntryLite<K, V> data) { | 
| + | 
| +    private Builder(Metadata<K, V> metadata, K key, V value) { | 
| this.metadata = metadata; | 
| -      this.data = data; | 
| -      this.dataBuilder = null; | 
| +      this.key = key; | 
| +      this.value = value; | 
| } | 
| - | 
| + | 
| public K getKey() { | 
| -      return dataBuilder == null ? data.getKey() : dataBuilder.getKey(); | 
| +      return key; | 
| } | 
| - | 
| + | 
| public V getValue() { | 
| -      return dataBuilder == null ? data.getValue() : dataBuilder.getValue(); | 
| -    } | 
| - | 
| -    private void ensureMutable() { | 
| -      if (dataBuilder == null) { | 
| -        dataBuilder = data.toBuilder(); | 
| -      } | 
| +      return value; | 
| } | 
| - | 
| + | 
| public Builder<K, V> setKey(K key) { | 
| -      ensureMutable(); | 
| -      dataBuilder.setKey(key); | 
| +      this.key = key; | 
| return this; | 
| } | 
| - | 
| + | 
| public Builder<K, V> clearKey() { | 
| -      ensureMutable(); | 
| -      dataBuilder.clearKey(); | 
| +      this.key = metadata.defaultKey; | 
| return this; | 
| } | 
| - | 
| + | 
| public Builder<K, V> setValue(V value) { | 
| -      ensureMutable(); | 
| -      dataBuilder.setValue(value); | 
| +      this.value = value; | 
| return this; | 
| } | 
| - | 
| + | 
| public Builder<K, V> clearValue() { | 
| -      ensureMutable(); | 
| -      dataBuilder.clearValue(); | 
| +      this.value = metadata.defaultValue; | 
| return this; | 
| } | 
|  | 
| @@ -281,29 +296,24 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
|  | 
| @Override | 
| public MapEntry<K, V> buildPartial() { | 
| -      if (dataBuilder != null) { | 
| -        data = dataBuilder.buildPartial(); | 
| -        dataBuilder = null; | 
| -      } | 
| -      return new MapEntry<K, V>(metadata, data); | 
| +      return new MapEntry<K, V>(metadata, key, value); | 
| } | 
|  | 
| @Override | 
| public Descriptor getDescriptorForType() { | 
| return metadata.descriptor; | 
| } | 
| - | 
| + | 
| private void checkFieldDescriptor(FieldDescriptor field) { | 
| if (field.getContainingType() != metadata.descriptor) { | 
| throw new RuntimeException( | 
| "Wrong FieldDescriptor \"" + field.getFullName() | 
| -            + "\" used in message \"" + metadata.descriptor.getFullName()); | 
| +            + "\" used in message \"" + metadata.descriptor.getFullName()); | 
| } | 
| } | 
|  | 
| @Override | 
| -    public com.google.protobuf.Message.Builder newBuilderForField( | 
| -        FieldDescriptor field) { | 
| +    public Message.Builder newBuilderForField(FieldDescriptor field) { | 
| checkFieldDescriptor(field);; | 
| // This method should be called for message fields and in a MapEntry | 
| // message only the value field can possibly be a message field. | 
| @@ -312,7 +322,7 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
| throw new RuntimeException( | 
| "\"" + field.getFullName() + "\" is not a message value field."); | 
| } | 
| -      return ((Message) data.getValue()).newBuilderForType(); | 
| +      return ((Message) value).newBuilderForType(); | 
| } | 
|  | 
| @SuppressWarnings("unchecked") | 
| @@ -324,6 +334,15 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
| } else { | 
| if (field.getType() == FieldDescriptor.Type.ENUM) { | 
| value = ((EnumValueDescriptor) value).getNumber(); | 
| +        } else if (field.getType() == FieldDescriptor.Type.MESSAGE) { | 
| +          if (value != null && !metadata.defaultValue.getClass().isInstance(value)) { | 
| +            // The value is not the exact right message type.  However, if it | 
| +            // is an alternative implementation of the same type -- e.g. a | 
| +            // DynamicMessage -- we should accept it.  In this case we can make | 
| +            // a copy of the message. | 
| +            value = | 
| +                ((Message) metadata.defaultValue).toBuilder().mergeFrom((Message) value).build(); | 
| +          } | 
| } | 
| setValue((V) value); | 
| } | 
| @@ -362,22 +381,17 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
|  | 
| @Override | 
| public MapEntry<K, V> getDefaultInstanceForType() { | 
| -      return metadata.defaultInstance; | 
| +      return new MapEntry<K, V>(metadata, metadata.defaultKey, metadata.defaultValue); | 
| } | 
|  | 
| @Override | 
| public boolean isInitialized() { | 
| -      if (dataBuilder != null) { | 
| -        return dataBuilder.isInitialized(); | 
| -      } else { | 
| -        return data.isInitialized(); | 
| -      } | 
| +      return MapEntry.isInitialized(metadata, value); | 
| } | 
|  | 
| @Override | 
| public Map<FieldDescriptor, Object> getAllFields() { | 
| -      final TreeMap<FieldDescriptor, Object> result = | 
| -          new TreeMap<FieldDescriptor, Object>(); | 
| +      final TreeMap<FieldDescriptor, Object> result = new TreeMap<FieldDescriptor, Object>(); | 
| for (final FieldDescriptor field : metadata.descriptor.getFields()) { | 
| if (hasField(field)) { | 
| result.put(field, getField(field)); | 
| @@ -398,8 +412,7 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
| Object result = field.getNumber() == 1 ? getKey() : getValue(); | 
| // Convert enums to EnumValueDescriptor. | 
| if (field.getType() == FieldDescriptor.Type.ENUM) { | 
| -        result = field.getEnumType().findValueByNumberCreatingIfUnknown( | 
| -            (java.lang.Integer) result); | 
| +        result = field.getEnumType().findValueByNumberCreatingIfUnknown((Integer) result); | 
| } | 
| return result; | 
| } | 
| @@ -409,13 +422,13 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
| throw new RuntimeException( | 
| "There is no repeated field in a map entry message."); | 
| } | 
| - | 
| + | 
| @Override | 
| public Object getRepeatedField(FieldDescriptor field, int index) { | 
| throw new RuntimeException( | 
| "There is no repeated field in a map entry message."); | 
| } | 
| - | 
| + | 
| @Override | 
| public UnknownFieldSet getUnknownFields() { | 
| return UnknownFieldSet.getDefaultInstance(); | 
| @@ -423,11 +436,14 @@ public final class MapEntry<K, V> extends AbstractMessage { | 
|  | 
| @Override | 
| public Builder<K, V> clone() { | 
| -      if (dataBuilder == null) { | 
| -        return new Builder<K, V>(metadata, data); | 
| -      } else { | 
| -        return new Builder<K, V>(metadata, dataBuilder.build()); | 
| -      } | 
| +      return new Builder(metadata, key, value); | 
| } | 
| } | 
| + | 
| +  private static <V> boolean isInitialized(Metadata metadata, V value) { | 
| +    if (metadata.valueType.getJavaType() == WireFormat.JavaType.MESSAGE) { | 
| +      return ((MessageLite) value).isInitialized(); | 
| +    } | 
| +    return true; | 
| +  } | 
| } | 
|  |