All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.signalfx.shaded.google.protobuf.MapFieldBuilder Maven / Gradle / Ivy

// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

package com.signalfx.shaded.google.protobuf;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Internal representation of map fields in generated builders.
 *
 * 

This class supports accessing the map field as a {@link Map} to be used in generated API and * also supports accessing the field as a {@link List} to be used in reflection API. It keeps track * of where the data is currently stored and do necessary conversions between map and list. * *

This class is a protobuf implementation detail. Users shouldn't use this class directly. */ public class MapFieldBuilder< KeyT, MessageOrBuilderT extends MessageOrBuilder, MessageT extends MessageOrBuilderT, BuilderT extends MessageOrBuilderT> extends MapFieldReflectionAccessor { // Only one of the three fields may be non-null at any time. /** nullable */ Map builderMap = new LinkedHashMap<>(); /** nullable */ Map messageMap = null; // We need a List for reflection. // // messageList elements are always MapEntry, where SomeT and MessageT // have the same descriptor (i.e. SomeT can be DynamicMessage) /** nullable */ List messageList = null; Converter converter; /** Convert a MessageOrBuilder to a Message regardless of which it holds. */ public interface Converter< KeyT, MessageOrBuilderT extends MessageOrBuilder, MessageT extends MessageOrBuilderT> { MessageT build(MessageOrBuilderT val); MapEntry defaultEntry(); } public MapFieldBuilder(Converter converter) { this.converter = converter; } @SuppressWarnings("unchecked") private List> getMapEntryList() { ArrayList> list = new ArrayList<>(messageList.size()); Class valueClass = converter.defaultEntry().getValue().getClass(); for (Message entry : messageList) { MapEntry typedEntry = (MapEntry) entry; if (valueClass.isInstance(typedEntry.getValue())) { list.add((MapEntry) typedEntry); } else { // This needs to use mergeFrom to allow MapEntry to be used. list.add(converter.defaultEntry().toBuilder().mergeFrom(entry).build()); } } return list; } public Map ensureBuilderMap() { if (builderMap != null) { return builderMap; } if (messageMap != null) { builderMap = new LinkedHashMap<>(messageMap.size()); for (Map.Entry entry : messageMap.entrySet()) { builderMap.put(entry.getKey(), entry.getValue()); } messageMap = null; return builderMap; } builderMap = new LinkedHashMap<>(messageList.size()); for (MapEntry entry : getMapEntryList()) { builderMap.put(entry.getKey(), entry.getValue()); } messageList = null; return builderMap; } public List ensureMessageList() { if (messageList != null) { return messageList; } if (builderMap != null) { messageList = new ArrayList<>(builderMap.size()); for (Map.Entry entry : builderMap.entrySet()) { messageList.add( converter.defaultEntry().toBuilder() .setKey(entry.getKey()) .setValue(converter.build(entry.getValue())) .build()); } builderMap = null; return messageList; } messageList = new ArrayList<>(messageMap.size()); for (Map.Entry entry : messageMap.entrySet()) { messageList.add( converter.defaultEntry().toBuilder() .setKey(entry.getKey()) .setValue(entry.getValue()) .build()); } messageMap = null; return messageList; } public Map ensureMessageMap() { messageMap = populateMutableMap(); builderMap = null; messageList = null; return messageMap; } public Map getImmutableMap() { return new MapField.MutabilityAwareMap<>(MutabilityOracle.IMMUTABLE, populateMutableMap()); } private Map populateMutableMap() { if (messageMap != null) { return messageMap; } if (builderMap != null) { Map toReturn = new LinkedHashMap<>(builderMap.size()); for (Map.Entry entry : builderMap.entrySet()) { toReturn.put(entry.getKey(), converter.build(entry.getValue())); } return toReturn; } Map toReturn = new LinkedHashMap<>(messageList.size()); for (MapEntry entry : getMapEntryList()) { toReturn.put(entry.getKey(), entry.getValue()); } return toReturn; } public void mergeFrom(MapField other) { ensureBuilderMap().putAll(MapFieldLite.copy(other.getMap())); } public void clear() { builderMap = new LinkedHashMap<>(); messageMap = null; messageList = null; } private boolean typedEquals(MapFieldBuilder other) { return MapFieldLite.equals( ensureBuilderMap(), other.ensureBuilderMap()); } @SuppressWarnings("unchecked") @Override public boolean equals(Object object) { if (!(object instanceof MapFieldBuilder)) { return false; } return typedEquals((MapFieldBuilder) object); } @Override public int hashCode() { return MapFieldLite.calculateHashCodeForMap(ensureBuilderMap()); } /** Returns a deep copy of this MapFieldBuilder. */ public MapFieldBuilder copy() { MapFieldBuilder clone = new MapFieldBuilder<>(converter); clone.ensureBuilderMap().putAll(ensureBuilderMap()); return clone; } /** Converts this MapFieldBuilder to a MapField. */ public MapField build(MapEntry defaultEntry) { MapField mapField = MapField.newMapField(defaultEntry); Map map = mapField.getMutableMap(); for (Map.Entry entry : ensureBuilderMap().entrySet()) { map.put(entry.getKey(), converter.build(entry.getValue())); } mapField.makeImmutable(); return mapField; } // MapFieldReflectionAccessor implementation. /** Gets the content of this MapField as a read-only List. */ @Override List getList() { return ensureMessageList(); } /** Gets a mutable List view of this MapField. */ @Override List getMutableList() { return ensureMessageList(); } /** Gets the default instance of the message stored in the list view of this map field. */ @Override Message getMapEntryMessageDefaultInstance() { return converter.defaultEntry(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy