Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
// 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.LazyField.LazyIterator;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* A class which represents an arbitrary set of fields of some message type.
* This is used to implement {@link DynamicMessage}, and also to represent
* extensions in {@link GeneratedMessage}. This class is package-private,
* since outside users should probably be using {@link DynamicMessage}.
*
* @author [email protected] Kenton Varda
*/
final class FieldSet> {
/**
* Interface for a FieldDescriptor or lite extension descriptor. This
* prevents FieldSet from depending on {@link Descriptors.FieldDescriptor}.
*/
public interface FieldDescriptorLite>
extends Comparable {
int getNumber();
WireFormat.FieldType getLiteType();
WireFormat.JavaType getLiteJavaType();
boolean isRepeated();
boolean isPacked();
Internal.EnumLiteMap> getEnumType();
// If getLiteJavaType() == MESSAGE, this merges a message object of the
// type into a builder of the type. Returns {@code to}.
MessageLite.Builder internalMergeFrom(
MessageLite.Builder to, MessageLite from);
}
private final SmallSortedMap fields;
private boolean isImmutable;
private boolean hasLazyField = false;
/** Construct a new FieldSet. */
private FieldSet() {
this.fields = SmallSortedMap.newFieldMap(16);
}
/**
* Construct an empty FieldSet. This is only used to initialize
* DEFAULT_INSTANCE.
*/
private FieldSet(final boolean dummy) {
this.fields = SmallSortedMap.newFieldMap(0);
makeImmutable();
}
/** Construct a new FieldSet. */
public static >
FieldSet newFieldSet() {
return new FieldSet();
}
/** Get an immutable empty FieldSet. */
@SuppressWarnings("unchecked")
public static >
FieldSet emptySet() {
return DEFAULT_INSTANCE;
}
@SuppressWarnings("rawtypes")
private static final FieldSet DEFAULT_INSTANCE = new FieldSet(true);
/** Make this FieldSet immutable from this point forward. */
@SuppressWarnings("unchecked")
public void makeImmutable() {
if (isImmutable) {
return;
}
fields.makeImmutable();
isImmutable = true;
}
/**
* Returns whether the FieldSet is immutable. This is true if it is the
* {@link #emptySet} or if {@link #makeImmutable} were called.
*
* @return whether the FieldSet is immutable.
*/
public boolean isImmutable() {
return isImmutable;
}
/**
* Clones the FieldSet. The returned FieldSet will be mutable even if the
* original FieldSet was immutable.
*
* @return the newly cloned FieldSet
*/
@Override
public FieldSet clone() {
// We can't just call fields.clone because List objects in the map
// should not be shared.
FieldSet clone = FieldSet.newFieldSet();
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
Map.Entry entry = fields.getArrayEntryAt(i);
FieldDescriptorType descriptor = entry.getKey();
clone.setField(descriptor, entry.getValue());
}
for (Map.Entry entry :
fields.getOverflowEntries()) {
FieldDescriptorType descriptor = entry.getKey();
clone.setField(descriptor, entry.getValue());
}
clone.hasLazyField = hasLazyField;
return clone;
}
// =================================================================
/** See {@link Message.Builder#clear()}. */
public void clear() {
fields.clear();
hasLazyField = false;
}
/**
* Get a simple map containing all the fields.
*/
public Map getAllFields() {
if (hasLazyField) {
SmallSortedMap result =
SmallSortedMap.newFieldMap(16);
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
cloneFieldEntry(result, fields.getArrayEntryAt(i));
}
for (Map.Entry entry :
fields.getOverflowEntries()) {
cloneFieldEntry(result, entry);
}
if (fields.isImmutable()) {
result.makeImmutable();
}
return result;
}
return fields.isImmutable() ? fields : Collections.unmodifiableMap(fields);
}
private void cloneFieldEntry(Map map,
Map.Entry entry) {
FieldDescriptorType key = entry.getKey();
Object value = entry.getValue();
if (value instanceof LazyField) {
map.put(key, ((LazyField) value).getValue());
} else {
map.put(key, value);
}
}
/**
* Get an iterator to the field map. This iterator should not be leaked out
* of the protobuf library as it is not protected from mutation when fields
* is not immutable.
*/
public Iterator> iterator() {
if (hasLazyField) {
return new LazyIterator(
fields.entrySet().iterator());
}
return fields.entrySet().iterator();
}
/**
* Useful for implementing
* {@link Message#hasField(Descriptors.FieldDescriptor)}.
*/
public boolean hasField(final FieldDescriptorType descriptor) {
if (descriptor.isRepeated()) {
throw new IllegalArgumentException(
"hasField() can only be called on non-repeated fields.");
}
return fields.get(descriptor) != null;
}
/**
* Useful for implementing
* {@link Message#getField(Descriptors.FieldDescriptor)}. This method
* returns {@code null} if the field is not set; in this case it is up
* to the caller to fetch the field's default value.
*/
public Object getField(final FieldDescriptorType descriptor) {
Object o = fields.get(descriptor);
if (o instanceof LazyField) {
return ((LazyField) o).getValue();
}
return o;
}
/**
* Useful for implementing
* {@link Message.Builder#setField(Descriptors.FieldDescriptor,Object)}.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public void setField(final FieldDescriptorType descriptor,
Object value) {
if (descriptor.isRepeated()) {
if (!(value instanceof List)) {
throw new IllegalArgumentException(
"Wrong object type used with protocol message reflection.");
}
// Wrap the contents in a new list so that the caller cannot change
// the list's contents after setting it.
final List newList = new ArrayList();
newList.addAll((List) value);
for (final Object element : newList) {
verifyType(descriptor.getLiteType(), element);
}
value = newList;
} else {
verifyType(descriptor.getLiteType(), value);
}
if (value instanceof LazyField) {
hasLazyField = true;
}
fields.put(descriptor, value);
}
/**
* Useful for implementing
* {@link Message.Builder#clearField(Descriptors.FieldDescriptor)}.
*/
public void clearField(final FieldDescriptorType descriptor) {
fields.remove(descriptor);
if (fields.isEmpty()) {
hasLazyField = false;
}
}
/**
* Useful for implementing
* {@link Message#getRepeatedFieldCount(Descriptors.FieldDescriptor)}.
*/
public int getRepeatedFieldCount(final FieldDescriptorType descriptor) {
if (!descriptor.isRepeated()) {
throw new IllegalArgumentException(
"getRepeatedField() can only be called on repeated fields.");
}
final Object value = getField(descriptor);
if (value == null) {
return 0;
} else {
return ((List>) value).size();
}
}
/**
* Useful for implementing
* {@link Message#getRepeatedField(Descriptors.FieldDescriptor,int)}.
*/
public Object getRepeatedField(final FieldDescriptorType descriptor,
final int index) {
if (!descriptor.isRepeated()) {
throw new IllegalArgumentException(
"getRepeatedField() can only be called on repeated fields.");
}
final Object value = getField(descriptor);
if (value == null) {
throw new IndexOutOfBoundsException();
} else {
return ((List>) value).get(index);
}
}
/**
* Useful for implementing
* {@link Message.Builder#setRepeatedField(Descriptors.FieldDescriptor,int,Object)}.
*/
@SuppressWarnings("unchecked")
public void setRepeatedField(final FieldDescriptorType descriptor,
final int index,
final Object value) {
if (!descriptor.isRepeated()) {
throw new IllegalArgumentException(
"getRepeatedField() can only be called on repeated fields.");
}
final Object list = getField(descriptor);
if (list == null) {
throw new IndexOutOfBoundsException();
}
verifyType(descriptor.getLiteType(), value);
((List