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

com.baidu.bjf.remoting.protobuf.MapEntry Maven / Gradle / Ivy

There is a newer version: 2.4.23
Show newest version
/*
 * Copyright (c) Baidu Inc. All rights reserved.
 * 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.baidu.bjf.remoting.protobuf;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;

import com.google.protobuf.AbstractMessage;
import com.google.protobuf.AbstractParser;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.Parser;
import com.google.protobuf.UnknownFieldSet;
import com.google.protobuf.WireFormat;
import com.google.protobuf.MessageLite;

/**
 * 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 value != null; } return true; } /** Returns the metadata only for experimental runtime. */ final Metadata getMetadata() { return metadata; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy