blob: 6b53d1fbf2851a00403cf331197ab133ad993191 [file] [log] [blame]
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of protobuf;
typedef CheckFunc<E> = void Function(E? x);
class FrozenPbList<E> extends PbListBase<E> {
FrozenPbList._(List<E> wrappedList) : super._(wrappedList);
factory FrozenPbList.from(PbList<E> other) =>
FrozenPbList._(other._wrappedList);
UnsupportedError _unsupported(String method) =>
UnsupportedError('Cannot call $method on an unmodifiable list');
@override
void operator []=(int index, E value) => throw _unsupported('set');
@override
set length(int newLength) => throw _unsupported('set length');
@override
void setAll(int index, Iterable<E> iterable) => throw _unsupported('setAll');
@override
void add(E? element) => throw _unsupported('add');
@override
void addAll(Iterable<E> iterable) => throw _unsupported('addAll');
@override
void insert(int index, E element) => throw _unsupported('insert');
@override
void insertAll(int index, Iterable<E> iterable) =>
throw _unsupported('insertAll');
@override
bool remove(Object? element) => throw _unsupported('remove');
@override
void removeWhere(bool Function(E element) test) =>
throw _unsupported('removeWhere');
@override
void retainWhere(bool Function(E element) test) =>
throw _unsupported('retainWhere');
@override
void sort([Comparator<E>? compare]) => throw _unsupported('sort');
@override
void shuffle([math.Random? random]) => throw _unsupported('shuffle');
@override
void clear() => throw _unsupported('clear');
@override
E removeAt(int index) => throw _unsupported('removeAt');
@override
E removeLast() => throw _unsupported('removeLast');
@override
void setRange(int start, int end, Iterable<E> iterable,
[int skipCount = 0]) =>
throw _unsupported('setRange');
@override
void removeRange(int start, int end) => throw _unsupported('removeRange');
@override
void replaceRange(int start, int end, Iterable<E> newContents) =>
throw _unsupported('replaceRange');
@override
void fillRange(int start, int end, [E? fill]) =>
throw _unsupported('fillRange');
}
class PbList<E> extends PbListBase<E> {
PbList({CheckFunc<E> check = _checkNotNull}) : super._noList(check: check);
PbList.from(List from) : super._from(from);
@Deprecated('Instead use the default constructor with a check function.'
'This constructor will be removed in the next major version.')
PbList.forFieldType(int fieldType)
: super._noList(check: getCheckFunction(fieldType));
/// Freezes the list by converting to [FrozenPbList].
FrozenPbList<E> toFrozenPbList() => FrozenPbList<E>.from(this);
@override
void add(E element) {
check(element);
_wrappedList.add(element);
}
@override
void addAll(Iterable<E> iterable) {
iterable.forEach(check);
_wrappedList.addAll(iterable);
}
@override
Iterable<E> get reversed => _wrappedList.reversed;
@override
void sort([int Function(E a, E b)? compare]) => _wrappedList.sort(compare);
@override
void shuffle([math.Random? random]) => _wrappedList.shuffle(random);
@override
void clear() => _wrappedList.clear();
@override
void insert(int index, E element) {
check(element);
_wrappedList.insert(index, element);
}
@override
void insertAll(int index, Iterable<E> iterable) {
iterable.forEach(check);
_wrappedList.insertAll(index, iterable);
}
@override
void setAll(int index, Iterable<E> iterable) {
iterable.forEach(check);
_wrappedList.setAll(index, iterable);
}
@override
bool remove(Object? element) => _wrappedList.remove(element);
@override
E removeAt(int index) => _wrappedList.removeAt(index);
@override
E removeLast() => _wrappedList.removeLast();
@override
void removeWhere(bool Function(E element) test) =>
_wrappedList.removeWhere(test);
@override
void retainWhere(bool Function(E element) test) =>
_wrappedList.retainWhere(test);
@override
void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
// NOTE: In case `take()` returns less than `end - start` elements, the
// _wrappedList will fail with a `StateError`.
iterable.skip(skipCount).take(end - start).forEach(check);
_wrappedList.setRange(start, end, iterable, skipCount);
}
@override
void removeRange(int start, int end) => _wrappedList.removeRange(start, end);
@override
void fillRange(int start, int end, [E? fill]) {
check(fill);
_wrappedList.fillRange(start, end, fill);
}
@override
void replaceRange(int start, int end, Iterable<E> newContents) {
final values = newContents.toList();
newContents.forEach(check);
_wrappedList.replaceRange(start, end, values);
}
}
abstract class PbListBase<E> extends ListBase<E> {
final List<E> _wrappedList;
final CheckFunc<E> check;
PbListBase._(this._wrappedList, {this.check = _checkNotNull});
PbListBase._noList({this.check = _checkNotNull}) : _wrappedList = <E>[] {
ArgumentError.checkNotNull(check, 'check');
}
PbListBase._from(List from)
// TODO(sra): Should this be validated?
: _wrappedList = List<E>.from(from),
check = _checkNotNull;
@override
bool operator ==(other) =>
(other is PbListBase) && _areListsEqual(other, this);
@override
int get hashCode => _HashUtils._hashObjects(_wrappedList);
@override
Iterator<E> get iterator => _wrappedList.iterator;
@override
Iterable<T> map<T>(T Function(E e) f) => _wrappedList.map<T>(f);
@override
Iterable<E> where(bool Function(E element) test) => _wrappedList.where(test);
@override
Iterable<T> expand<T>(Iterable<T> Function(E element) f) =>
_wrappedList.expand(f);
@override
bool contains(Object? element) => _wrappedList.contains(element);
@override
void forEach(void Function(E element) action) {
_wrappedList.forEach(action);
}
@override
E reduce(E Function(E value, E element) combine) =>
_wrappedList.reduce(combine);
@override
T fold<T>(T initialValue, T Function(T previousValue, E element) combine) =>
_wrappedList.fold(initialValue, combine);
@override
bool every(bool Function(E element) test) => _wrappedList.every(test);
@override
String join([String separator = '']) => _wrappedList.join(separator);
@override
bool any(bool Function(E element) test) => _wrappedList.any(test);
@override
List<E> toList({bool growable = true}) =>
_wrappedList.toList(growable: growable);
@override
Set<E> toSet() => _wrappedList.toSet();
@override
bool get isEmpty => _wrappedList.isEmpty;
@override
bool get isNotEmpty => _wrappedList.isNotEmpty;
@override
Iterable<E> take(int count) => _wrappedList.take(count);
@override
Iterable<E> takeWhile(bool Function(E value) test) =>
_wrappedList.takeWhile(test);
@override
Iterable<E> skip(int count) => _wrappedList.skip(count);
@override
Iterable<E> skipWhile(bool Function(E value) test) =>
_wrappedList.skipWhile(test);
@override
E get first => _wrappedList.first;
@override
E get last => _wrappedList.last;
@override
E get single => _wrappedList.single;
@override
E firstWhere(bool Function(E element) test, {E Function()? orElse}) =>
_wrappedList.firstWhere(test, orElse: orElse);
@override
E lastWhere(bool Function(E element) test, {E Function()? orElse}) =>
_wrappedList.lastWhere(test, orElse: orElse);
@override
E elementAt(int index) => _wrappedList.elementAt(index);
@override
String toString() => _wrappedList.toString();
@override
E operator [](int index) => _wrappedList[index];
@override
int get length => _wrappedList.length;
// TODO(jakobr): E instead of Object once dart-lang/sdk#31311 is fixed.
@override
int indexOf(Object? element, [int start = 0]) =>
_wrappedList.indexOf(element as E, start);
// TODO(jakobr): E instead of Object once dart-lang/sdk#31311 is fixed.
@override
int lastIndexOf(Object? element, [int? start]) =>
_wrappedList.lastIndexOf(element as E, start);
@override
List<E> sublist(int start, [int? end]) => _wrappedList.sublist(start, end);
@override
Iterable<E> getRange(int start, int end) => _wrappedList.getRange(start, end);
@override
Map<int, E> asMap() => _wrappedList.asMap();
@override
void operator []=(int index, E value) {
check(value);
_wrappedList[index] = value;
}
/// Unsupported -- violated non-null constraint imposed by protobufs.
///
/// Changes the length of the list. If [newLength] is greater than the current
/// [length], entries are initialized to [:null:]. Throws an
/// [UnsupportedError] if the list is not extendable.
@override
set length(int newLength) {
if (newLength > length) {
throw UnsupportedError('Extending protobuf lists is not supported');
}
_wrappedList.length = newLength;
}
}