| 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..179c3348a1e097f00279d3b59ebc433bf5b7a25d 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).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;
 | 
| +  }
 | 
|  }
 | 
| 
 |