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

com.google.protobuf.MapEntry Maven / Gradle / Ivy

There is a newer version: 4.0.0.4
Show newest version
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package com.google.protobuf;

import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
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 extends AbstractMessage { private static final class Metadata extends MapEntryLite.Metadata { public final Descriptor descriptor; public final Parser> parser; public Metadata( Descriptor descriptor, MapEntry defaultInstance, WireFormat.FieldType keyType, WireFormat.FieldType valueType) { super(keyType, defaultInstance.key, valueType, defaultInstance.value); this.descriptor = descriptor; this.parser = new AbstractParser>() { @Override public MapEntry parsePartialFrom( CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { return new MapEntry(Metadata.this, input, extensionRegistry); } }; } } private final K key; private final V value; private final Metadata metadata; /** Create a default MapEntry instance. */ private MapEntry( Descriptor descriptor, WireFormat.FieldType keyType, K defaultKey, WireFormat.FieldType valueType, V defaultValue) { this.key = defaultKey; this.value = defaultValue; this.metadata = new Metadata(descriptor, this, keyType, valueType); } /** Create a MapEntry with the provided key and value. */ @SuppressWarnings("unchecked") private MapEntry(Metadata metadata, K key, V value) { this.key = key; this.value = value; this.metadata = metadata; } /** Parsing constructor. */ private MapEntry( Metadata metadata, CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { try { this.metadata = metadata; Map.Entry 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. */ public static MapEntry newDefaultInstance( Descriptor descriptor, WireFormat.FieldType keyType, K defaultKey, WireFormat.FieldType valueType, V defaultValue) { return new MapEntry(descriptor, keyType, defaultKey, valueType, defaultValue); } public K getKey() { return key; } public V getValue() { return value; } private volatile int cachedSerializedSize = -1; @Override public int 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 { MapEntryLite.writeTo(output, metadata, key, value); } @Override public boolean isInitialized() { return isInitialized(metadata, value); } @Override public Parser> getParserForType() { return metadata.parser; } @Override public Builder newBuilderForType() { return new Builder(metadata); } @Override public Builder toBuilder() { return new Builder(metadata, key, value, true, true); } @Override public MapEntry getDefaultInstanceForType() { return new MapEntry(metadata, metadata.defaultKey, metadata.defaultValue); } @Override public Descriptor getDescriptorForType() { return metadata.descriptor; } @Override public Map getAllFields() { TreeMap result = new TreeMap(); for (final FieldDescriptor field : metadata.descriptor.getFields()) { if (hasField(field)) { result.put(field, getField(field)); } } 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()); } } @Override public boolean hasField(FieldDescriptor field) { checkFieldDescriptor(field); ; // A MapEntry always contains two fields. return true; } @Override public Object getField(FieldDescriptor field) { checkFieldDescriptor(field); 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); } return result; } @Override public int getRepeatedFieldCount(FieldDescriptor field) { 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(); } /** Builder to create {@link MapEntry} messages. */ public static class Builder extends AbstractMessage.Builder> { private final Metadata metadata; private K key; private V value; private boolean hasKey; private boolean hasValue; private Builder(Metadata metadata) { this(metadata, metadata.defaultKey, metadata.defaultValue, false, false); } private Builder(Metadata metadata, K key, V value, boolean hasKey, boolean hasValue) { this.metadata = metadata; this.key = key; this.value = value; this.hasKey = hasKey; this.hasValue = hasValue; } public K getKey() { return key; } public V getValue() { return value; } public Builder setKey(K key) { this.key = key; this.hasKey = true; return this; } public Builder clearKey() { this.key = metadata.defaultKey; this.hasKey = false; return this; } public Builder setValue(V value) { this.value = value; this.hasValue = true; return this; } public Builder clearValue() { this.value = metadata.defaultValue; this.hasValue = false; return this; } @Override public MapEntry build() { MapEntry result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } @Override public MapEntry buildPartial() { return new MapEntry(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()); } } @Override 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. if (field.getNumber() != 2 || field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { throw new RuntimeException("\"" + field.getFullName() + "\" is not a message value field."); } return ((Message) value).newBuilderForType(); } @SuppressWarnings("unchecked") @Override public Builder setField(FieldDescriptor field, Object value) { checkFieldDescriptor(field); if (field.getNumber() == 1) { setKey((K) value); } 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); } return this; } @Override public Builder clearField(FieldDescriptor field) { checkFieldDescriptor(field); if (field.getNumber() == 1) { clearKey(); } else { clearValue(); } return this; } @Override public Builder setRepeatedField(FieldDescriptor field, int index, Object value) { throw new RuntimeException("There is no repeated field in a map entry message."); } @Override public Builder addRepeatedField(FieldDescriptor field, Object value) { throw new RuntimeException("There is no repeated field in a map entry message."); } @Override public Builder setUnknownFields(UnknownFieldSet unknownFields) { // Unknown fields are discarded for MapEntry message. return this; } @Override public MapEntry getDefaultInstanceForType() { return new MapEntry(metadata, metadata.defaultKey, metadata.defaultValue); } @Override public boolean isInitialized() { return MapEntry.isInitialized(metadata, value); } @Override public Map getAllFields() { final TreeMap result = new TreeMap(); for (final FieldDescriptor field : metadata.descriptor.getFields()) { if (hasField(field)) { result.put(field, getField(field)); } } return Collections.unmodifiableMap(result); } @Override public boolean hasField(FieldDescriptor field) { checkFieldDescriptor(field); return field.getNumber() == 1 ? hasKey : hasValue; } @Override public Object getField(FieldDescriptor field) { checkFieldDescriptor(field); Object result = field.getNumber() == 1 ? getKey() : getValue(); // Convert enums to EnumValueDescriptor. if (field.getType() == FieldDescriptor.Type.ENUM) { result = field.getEnumType().findValueByNumberCreatingIfUnknown((Integer) result); } return result; } @Override public int getRepeatedFieldCount(FieldDescriptor field) { 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(); } @Override @SuppressWarnings("unchecked") public Builder clone() { return new Builder<>(metadata, key, value, hasKey, hasValue); } } private static boolean isInitialized(Metadata metadata, V value) { if (metadata.valueType.getJavaType() == WireFormat.JavaType.MESSAGE) { return ((MessageLite) value).isInitialized(); } return true; } /** Returns the metadata only for experimental runtime. */ final Metadata getMetadata() { return metadata; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy