| Index: third_party/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
|
| diff --git a/third_party/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java b/third_party/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0024f79143de6862909c4649b85e4fc990073fdc
|
| --- /dev/null
|
| +++ b/third_party/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
|
| @@ -0,0 +1,696 @@
|
| +// Protocol Buffers - Google's data interchange format
|
| +// Copyright 2008 Google Inc. All rights reserved.
|
| +// http://code.google.com/p/protobuf/
|
| +//
|
| +// 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 java.util.AbstractList;
|
| +import java.util.ArrayList;
|
| +import java.util.Collection;
|
| +import java.util.Collections;
|
| +import java.util.List;
|
| +
|
| +/**
|
| + * <code>RepeatedFieldBuilder</code> implements a structure that a protocol
|
| + * message uses to hold a repeated field of other protocol messages. It supports
|
| + * the classical use case of adding immutable {@link Message}'s to the
|
| + * repeated field and is highly optimized around this (no extra memory
|
| + * allocations and sharing of immutable arrays).
|
| + * <br>
|
| + * It also supports the additional use case of adding a {@link Message.Builder}
|
| + * to the repeated field and deferring conversion of that <code>Builder</code>
|
| + * to an immutable <code>Message</code>. In this way, it's possible to maintain
|
| + * a tree of <code>Builder</code>'s that acts as a fully read/write data
|
| + * structure.
|
| + * <br>
|
| + * Logically, one can think of a tree of builders as converting the entire tree
|
| + * to messages when build is called on the root or when any method is called
|
| + * that desires a Message instead of a Builder. In terms of the implementation,
|
| + * the <code>SingleFieldBuilder</code> and <code>RepeatedFieldBuilder</code>
|
| + * classes cache messages that were created so that messages only need to be
|
| + * created when some change occured in its builder or a builder for one of its
|
| + * descendants.
|
| + *
|
| + * @param <MType> the type of message for the field
|
| + * @param <BType> the type of builder for the field
|
| + * @param <IType> the common interface for the message and the builder
|
| + *
|
| + * @author jonp@google.com (Jon Perlow)
|
| + */
|
| +public class RepeatedFieldBuilder
|
| + <MType extends GeneratedMessage,
|
| + BType extends GeneratedMessage.Builder,
|
| + IType extends MessageOrBuilder>
|
| + implements GeneratedMessage.BuilderParent {
|
| +
|
| + // Parent to send changes to.
|
| + private GeneratedMessage.BuilderParent parent;
|
| +
|
| + // List of messages. Never null. It may be immutable, in which case
|
| + // isMessagesListImmutable will be true. See note below.
|
| + private List<MType> messages;
|
| +
|
| + // Whether messages is an mutable array that can be modified.
|
| + private boolean isMessagesListMutable;
|
| +
|
| + // List of builders. May be null, in which case, no nested builders were
|
| + // created. If not null, entries represent the builder for that index.
|
| + private List<SingleFieldBuilder<MType, BType, IType>> builders;
|
| +
|
| + // Here are the invariants for messages and builders:
|
| + // 1. messages is never null and its count corresponds to the number of items
|
| + // in the repeated field.
|
| + // 2. If builders is non-null, messages and builders MUST always
|
| + // contain the same number of items.
|
| + // 3. Entries in either array can be null, but for any index, there MUST be
|
| + // either a Message in messages or a builder in builders.
|
| + // 4. If the builder at an index is non-null, the builder is
|
| + // authoritative. This is the case where a Builder was set on the index.
|
| + // Any message in the messages array MUST be ignored.
|
| + // t. If the builder at an index is null, the message in the messages
|
| + // list is authoritative. This is the case where a Message (not a Builder)
|
| + // was set directly for an index.
|
| +
|
| + // Indicates that we've built a message and so we are now obligated
|
| + // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener.
|
| + private boolean isClean;
|
| +
|
| + // A view of this builder that exposes a List interface of messages. This is
|
| + // initialized on demand. This is fully backed by this object and all changes
|
| + // are reflected in it. Access to any item converts it to a message if it
|
| + // was a builder.
|
| + private MessageExternalList<MType, BType, IType> externalMessageList;
|
| +
|
| + // A view of this builder that exposes a List interface of builders. This is
|
| + // initialized on demand. This is fully backed by this object and all changes
|
| + // are reflected in it. Access to any item converts it to a builder if it
|
| + // was a message.
|
| + private BuilderExternalList<MType, BType, IType> externalBuilderList;
|
| +
|
| + // A view of this builder that exposes a List interface of the interface
|
| + // implemented by messages and builders. This is initialized on demand. This
|
| + // is fully backed by this object and all changes are reflected in it.
|
| + // Access to any item returns either a builder or message depending on
|
| + // what is most efficient.
|
| + private MessageOrBuilderExternalList<MType, BType, IType>
|
| + externalMessageOrBuilderList;
|
| +
|
| + /**
|
| + * Constructs a new builder with an empty list of messages.
|
| + *
|
| + * @param messages the current list of messages
|
| + * @param isMessagesListMutable Whether the messages list is mutable
|
| + * @param parent a listener to notify of changes
|
| + * @param isClean whether the builder is initially marked clean
|
| + */
|
| + public RepeatedFieldBuilder(
|
| + List<MType> messages,
|
| + boolean isMessagesListMutable,
|
| + GeneratedMessage.BuilderParent parent,
|
| + boolean isClean) {
|
| + this.messages = messages;
|
| + this.isMessagesListMutable = isMessagesListMutable;
|
| + this.parent = parent;
|
| + this.isClean = isClean;
|
| + }
|
| +
|
| + public void dispose() {
|
| + // Null out parent so we stop sending it invalidations.
|
| + parent = null;
|
| + }
|
| +
|
| + /**
|
| + * Ensures that the list of messages is mutable so it can be updated. If it's
|
| + * immutable, a copy is made.
|
| + */
|
| + private void ensureMutableMessageList() {
|
| + if (!isMessagesListMutable) {
|
| + messages = new ArrayList<MType>(messages);
|
| + isMessagesListMutable = true;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Ensures that the list of builders is not null. If it's null, the list is
|
| + * created and initialized to be the same size as the messages list with
|
| + * null entries.
|
| + */
|
| + private void ensureBuilders() {
|
| + if (this.builders == null) {
|
| + this.builders =
|
| + new ArrayList<SingleFieldBuilder<MType, BType, IType>>(
|
| + messages.size());
|
| + for (int i = 0; i < messages.size(); i++) {
|
| + builders.add(null);
|
| + }
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Gets the count of items in the list.
|
| + *
|
| + * @return the count of items in the list.
|
| + */
|
| + public int getCount() {
|
| + return messages.size();
|
| + }
|
| +
|
| + /**
|
| + * Gets whether the list is empty.
|
| + *
|
| + * @return whether the list is empty
|
| + */
|
| + public boolean isEmpty() {
|
| + return messages.isEmpty();
|
| + }
|
| +
|
| + /**
|
| + * Get the message at the specified index. If the message is currently stored
|
| + * as a <code>Builder</code>, it is converted to a <code>Message</code> by
|
| + * calling {@link Message.Builder#buildPartial} on it.
|
| + *
|
| + * @param index the index of the message to get
|
| + * @return the message for the specified index
|
| + */
|
| + public MType getMessage(int index) {
|
| + return getMessage(index, false);
|
| + }
|
| +
|
| + /**
|
| + * Get the message at the specified index. If the message is currently stored
|
| + * as a <code>Builder</code>, it is converted to a <code>Message</code> by
|
| + * calling {@link Message.Builder#buildPartial} on it.
|
| + *
|
| + * @param index the index of the message to get
|
| + * @param forBuild this is being called for build so we want to make sure
|
| + * we SingleFieldBuilder.build to send dirty invalidations
|
| + * @return the message for the specified index
|
| + */
|
| + private MType getMessage(int index, boolean forBuild) {
|
| + if (this.builders == null) {
|
| + // We don't have any builders -- return the current Message.
|
| + // This is the case where no builder was created, so we MUST have a
|
| + // Message.
|
| + return messages.get(index);
|
| + }
|
| +
|
| + SingleFieldBuilder<MType, BType, IType> builder = builders.get(index);
|
| + if (builder == null) {
|
| + // We don't have a builder -- return the current message.
|
| + // This is the case where no builder was created for the entry at index,
|
| + // so we MUST have a message.
|
| + return messages.get(index);
|
| +
|
| + } else {
|
| + return forBuild ? builder.build() : builder.getMessage();
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Gets a builder for the specified index. If no builder has been created for
|
| + * that index, a builder is created on demand by calling
|
| + * {@link Message#toBuilder}.
|
| + *
|
| + * @param index the index of the message to get
|
| + * @return The builder for that index
|
| + */
|
| + public BType getBuilder(int index) {
|
| + ensureBuilders();
|
| + SingleFieldBuilder<MType, BType, IType> builder = builders.get(index);
|
| + if (builder == null) {
|
| + MType message = messages.get(index);
|
| + builder = new SingleFieldBuilder<MType, BType, IType>(
|
| + message, this, isClean);
|
| + builders.set(index, builder);
|
| + }
|
| + return builder.getBuilder();
|
| + }
|
| +
|
| + /**
|
| + * Gets the base class interface for the specified index. This may either be
|
| + * a builder or a message. It will return whatever is more efficient.
|
| + *
|
| + * @param index the index of the message to get
|
| + * @return the message or builder for the index as the base class interface
|
| + */
|
| + @SuppressWarnings("unchecked")
|
| + public IType getMessageOrBuilder(int index) {
|
| + if (this.builders == null) {
|
| + // We don't have any builders -- return the current Message.
|
| + // This is the case where no builder was created, so we MUST have a
|
| + // Message.
|
| + return (IType) messages.get(index);
|
| + }
|
| +
|
| + SingleFieldBuilder<MType, BType, IType> builder = builders.get(index);
|
| + if (builder == null) {
|
| + // We don't have a builder -- return the current message.
|
| + // This is the case where no builder was created for the entry at index,
|
| + // so we MUST have a message.
|
| + return (IType) messages.get(index);
|
| +
|
| + } else {
|
| + return builder.getMessageOrBuilder();
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Sets a message at the specified index replacing the existing item at
|
| + * that index.
|
| + *
|
| + * @param index the index to set.
|
| + * @param message the message to set
|
| + * @return the builder
|
| + */
|
| + public RepeatedFieldBuilder<MType, BType, IType> setMessage(
|
| + int index, MType message) {
|
| + if (message == null) {
|
| + throw new NullPointerException();
|
| + }
|
| + ensureMutableMessageList();
|
| + messages.set(index, message);
|
| + if (builders != null) {
|
| + SingleFieldBuilder<MType, BType, IType> entry =
|
| + builders.set(index, null);
|
| + if (entry != null) {
|
| + entry.dispose();
|
| + }
|
| + }
|
| + onChanged();
|
| + incrementModCounts();
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Appends the specified element to the end of this list.
|
| + *
|
| + * @param message the message to add
|
| + * @return the builder
|
| + */
|
| + public RepeatedFieldBuilder<MType, BType, IType> addMessage(
|
| + MType message) {
|
| + if (message == null) {
|
| + throw new NullPointerException();
|
| + }
|
| + ensureMutableMessageList();
|
| + messages.add(message);
|
| + if (builders != null) {
|
| + builders.add(null);
|
| + }
|
| + onChanged();
|
| + incrementModCounts();
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Inserts the specified message at the specified position in this list.
|
| + * Shifts the element currently at that position (if any) and any subsequent
|
| + * elements to the right (adds one to their indices).
|
| + *
|
| + * @param index the index at which to insert the message
|
| + * @param message the message to add
|
| + * @return the builder
|
| + */
|
| + public RepeatedFieldBuilder<MType, BType, IType> addMessage(
|
| + int index, MType message) {
|
| + if (message == null) {
|
| + throw new NullPointerException();
|
| + }
|
| + ensureMutableMessageList();
|
| + messages.add(index, message);
|
| + if (builders != null) {
|
| + builders.add(index, null);
|
| + }
|
| + onChanged();
|
| + incrementModCounts();
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Appends all of the messages in the specified collection to the end of
|
| + * this list, in the order that they are returned by the specified
|
| + * collection's iterator.
|
| + *
|
| + * @param values the messages to add
|
| + * @return the builder
|
| + */
|
| + public RepeatedFieldBuilder<MType, BType, IType> addAllMessages(
|
| + Iterable<? extends MType> values) {
|
| + for (final MType value : values) {
|
| + if (value == null) {
|
| + throw new NullPointerException();
|
| + }
|
| + }
|
| + if (values instanceof Collection) {
|
| + @SuppressWarnings("unchecked") final
|
| + Collection<MType> collection = (Collection<MType>) values;
|
| + if (collection.size() == 0) {
|
| + return this;
|
| + }
|
| + ensureMutableMessageList();
|
| + for (MType value : values) {
|
| + addMessage(value);
|
| + }
|
| + } else {
|
| + ensureMutableMessageList();
|
| + for (MType value : values) {
|
| + addMessage(value);
|
| + }
|
| + }
|
| + onChanged();
|
| + incrementModCounts();
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Appends a new builder to the end of this list and returns the builder.
|
| + *
|
| + * @param message the message to add which is the basis of the builder
|
| + * @return the new builder
|
| + */
|
| + public BType addBuilder(MType message) {
|
| + ensureMutableMessageList();
|
| + ensureBuilders();
|
| + SingleFieldBuilder<MType, BType, IType> builder =
|
| + new SingleFieldBuilder<MType, BType, IType>(
|
| + message, this, isClean);
|
| + messages.add(null);
|
| + builders.add(builder);
|
| + onChanged();
|
| + incrementModCounts();
|
| + return builder.getBuilder();
|
| + }
|
| +
|
| + /**
|
| + * Inserts a new builder at the specified position in this list.
|
| + * Shifts the element currently at that position (if any) and any subsequent
|
| + * elements to the right (adds one to their indices).
|
| + *
|
| + * @param index the index at which to insert the builder
|
| + * @param message the message to add which is the basis of the builder
|
| + * @return the builder
|
| + */
|
| + public BType addBuilder(int index, MType message) {
|
| + ensureMutableMessageList();
|
| + ensureBuilders();
|
| + SingleFieldBuilder<MType, BType, IType> builder =
|
| + new SingleFieldBuilder<MType, BType, IType>(
|
| + message, this, isClean);
|
| + messages.add(index, null);
|
| + builders.add(index, builder);
|
| + onChanged();
|
| + incrementModCounts();
|
| + return builder.getBuilder();
|
| + }
|
| +
|
| + /**
|
| + * Removes the element at the specified position in this list. Shifts any
|
| + * subsequent elements to the left (subtracts one from their indices).
|
| + * Returns the element that was removed from the list.
|
| + *
|
| + * @param index the index at which to remove the message
|
| + */
|
| + public void remove(int index) {
|
| + ensureMutableMessageList();
|
| + messages.remove(index);
|
| + if (builders != null) {
|
| + SingleFieldBuilder<MType, BType, IType> entry =
|
| + builders.remove(index);
|
| + if (entry != null) {
|
| + entry.dispose();
|
| + }
|
| + }
|
| + onChanged();
|
| + incrementModCounts();
|
| + }
|
| +
|
| + /**
|
| + * Removes all of the elements from this list.
|
| + * The list will be empty after this call returns.
|
| + */
|
| + public void clear() {
|
| + messages = Collections.emptyList();
|
| + isMessagesListMutable = false;
|
| + if (builders != null) {
|
| + for (SingleFieldBuilder<MType, BType, IType> entry :
|
| + builders) {
|
| + if (entry != null) {
|
| + entry.dispose();
|
| + }
|
| + }
|
| + builders = null;
|
| + }
|
| + onChanged();
|
| + incrementModCounts();
|
| + }
|
| +
|
| + /**
|
| + * Builds the list of messages from the builder and returns them.
|
| + *
|
| + * @return an immutable list of messages
|
| + */
|
| + public List<MType> build() {
|
| + // Now that build has been called, we are required to dispatch
|
| + // invalidations.
|
| + isClean = true;
|
| +
|
| + if (!isMessagesListMutable && builders == null) {
|
| + // We still have an immutable list and we never created a builder.
|
| + return messages;
|
| + }
|
| +
|
| + boolean allMessagesInSync = true;
|
| + if (!isMessagesListMutable) {
|
| + // We still have an immutable list. Let's see if any of them are out
|
| + // of sync with their builders.
|
| + for (int i = 0; i < messages.size(); i++) {
|
| + Message message = messages.get(i);
|
| + SingleFieldBuilder<MType, BType, IType> builder = builders.get(i);
|
| + if (builder != null) {
|
| + if (builder.build() != message) {
|
| + allMessagesInSync = false;
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + if (allMessagesInSync) {
|
| + // Immutable list is still in sync.
|
| + return messages;
|
| + }
|
| + }
|
| +
|
| + // Need to make sure messages is up to date
|
| + ensureMutableMessageList();
|
| + for (int i = 0; i < messages.size(); i++) {
|
| + messages.set(i, getMessage(i, true));
|
| + }
|
| +
|
| + // We're going to return our list as immutable so we mark that we can
|
| + // no longer update it.
|
| + messages = Collections.unmodifiableList(messages);
|
| + isMessagesListMutable = false;
|
| + return messages;
|
| + }
|
| +
|
| + /**
|
| + * Gets a view of the builder as a list of messages. The returned list is live
|
| + * and will reflect any changes to the underlying builder.
|
| + *
|
| + * @return the messages in the list
|
| + */
|
| + public List<MType> getMessageList() {
|
| + if (externalMessageList == null) {
|
| + externalMessageList =
|
| + new MessageExternalList<MType, BType, IType>(this);
|
| + }
|
| + return externalMessageList;
|
| + }
|
| +
|
| + /**
|
| + * Gets a view of the builder as a list of builders. This returned list is
|
| + * live and will reflect any changes to the underlying builder.
|
| + *
|
| + * @return the builders in the list
|
| + */
|
| + public List<BType> getBuilderList() {
|
| + if (externalBuilderList == null) {
|
| + externalBuilderList =
|
| + new BuilderExternalList<MType, BType, IType>(this);
|
| + }
|
| + return externalBuilderList;
|
| + }
|
| +
|
| + /**
|
| + * Gets a view of the builder as a list of MessageOrBuilders. This returned
|
| + * list is live and will reflect any changes to the underlying builder.
|
| + *
|
| + * @return the builders in the list
|
| + */
|
| + public List<IType> getMessageOrBuilderList() {
|
| + if (externalMessageOrBuilderList == null) {
|
| + externalMessageOrBuilderList =
|
| + new MessageOrBuilderExternalList<MType, BType, IType>(this);
|
| + }
|
| + return externalMessageOrBuilderList;
|
| + }
|
| +
|
| + /**
|
| + * Called when a the builder or one of its nested children has changed
|
| + * and any parent should be notified of its invalidation.
|
| + */
|
| + private void onChanged() {
|
| + if (isClean && parent != null) {
|
| + parent.markDirty();
|
| +
|
| + // Don't keep dispatching invalidations until build is called again.
|
| + isClean = false;
|
| + }
|
| + }
|
| +
|
| + //@Override (Java 1.6 override semantics, but we must support 1.5)
|
| + public void markDirty() {
|
| + onChanged();
|
| + }
|
| +
|
| + /**
|
| + * Increments the mod counts so that an ConcurrentModificationException can
|
| + * be thrown if calling code tries to modify the builder while its iterating
|
| + * the list.
|
| + */
|
| + private void incrementModCounts() {
|
| + if (externalMessageList != null) {
|
| + externalMessageList.incrementModCount();
|
| + }
|
| + if (externalBuilderList != null) {
|
| + externalBuilderList.incrementModCount();
|
| + }
|
| + if (externalMessageOrBuilderList != null) {
|
| + externalMessageOrBuilderList.incrementModCount();
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Provides a live view of the builder as a list of messages.
|
| + *
|
| + * @param <MType> the type of message for the field
|
| + * @param <BType> the type of builder for the field
|
| + * @param <IType> the common interface for the message and the builder
|
| + */
|
| + private static class MessageExternalList<
|
| + MType extends GeneratedMessage,
|
| + BType extends GeneratedMessage.Builder,
|
| + IType extends MessageOrBuilder>
|
| + extends AbstractList<MType> implements List<MType> {
|
| +
|
| + RepeatedFieldBuilder<MType, BType, IType> builder;
|
| +
|
| + MessageExternalList(
|
| + RepeatedFieldBuilder<MType, BType, IType> builder) {
|
| + this.builder = builder;
|
| + }
|
| +
|
| + public int size() {
|
| + return this.builder.getCount();
|
| + }
|
| +
|
| + public MType get(int index) {
|
| + return builder.getMessage(index);
|
| + }
|
| +
|
| + void incrementModCount() {
|
| + modCount++;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Provides a live view of the builder as a list of builders.
|
| + *
|
| + * @param <MType> the type of message for the field
|
| + * @param <BType> the type of builder for the field
|
| + * @param <IType> the common interface for the message and the builder
|
| + */
|
| + private static class BuilderExternalList<
|
| + MType extends GeneratedMessage,
|
| + BType extends GeneratedMessage.Builder,
|
| + IType extends MessageOrBuilder>
|
| + extends AbstractList<BType> implements List<BType> {
|
| +
|
| + RepeatedFieldBuilder<MType, BType, IType> builder;
|
| +
|
| + BuilderExternalList(
|
| + RepeatedFieldBuilder<MType, BType, IType> builder) {
|
| + this.builder = builder;
|
| + }
|
| +
|
| + public int size() {
|
| + return this.builder.getCount();
|
| + }
|
| +
|
| + public BType get(int index) {
|
| + return builder.getBuilder(index);
|
| + }
|
| +
|
| + void incrementModCount() {
|
| + modCount++;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Provides a live view of the builder as a list of builders.
|
| + *
|
| + * @param <MType> the type of message for the field
|
| + * @param <BType> the type of builder for the field
|
| + * @param <IType> the common interface for the message and the builder
|
| + */
|
| + private static class MessageOrBuilderExternalList<
|
| + MType extends GeneratedMessage,
|
| + BType extends GeneratedMessage.Builder,
|
| + IType extends MessageOrBuilder>
|
| + extends AbstractList<IType> implements List<IType> {
|
| +
|
| + RepeatedFieldBuilder<MType, BType, IType> builder;
|
| +
|
| + MessageOrBuilderExternalList(
|
| + RepeatedFieldBuilder<MType, BType, IType> builder) {
|
| + this.builder = builder;
|
| + }
|
| +
|
| + public int size() {
|
| + return this.builder.getCount();
|
| + }
|
| +
|
| + public IType get(int index) {
|
| + return builder.getMessageOrBuilder(index);
|
| + }
|
| +
|
| + void incrementModCount() {
|
| + modCount++;
|
| + }
|
| + }
|
| +}
|
|
|