Hide PbList and PbMap constructors (#1072)

`PbList` and `PbMap` can't be constructed by the users properly, because the
constructor arguments are private:

- `PbList` element check function
- `PbMap` key and value field type arguments

Internally we had just one `PbMap` constructor call (with random field type
arguments) which we replaced with `{}`, and a few `PbList` constructor calls
(without a check function) which we replaced with `[]`.

To prevent confusion and incorrect uses of these types, hide the constructors.

Some of the `PbList` element validation tests are removed: they would need to
be moved to `protoc_plugin/test` as we no longer have access to `PbList`
constructors (but we can get `PbList`s from messages), but the tests are also
duplicates of the tests in `protoc_plugin/test/validate_fail_test.dart`. So
removed them instead.
diff --git a/protobuf/CHANGELOG.md b/protobuf/CHANGELOG.md
index d2f12ba..64dc4c3 100644
--- a/protobuf/CHANGELOG.md
+++ b/protobuf/CHANGELOG.md
@@ -1,4 +1,4 @@
-## 5.2.0
+## 6.0.0
 
 * New `GeneratedMessage` extension methods `toTextFormat` and `writeTextFormat`
   added to convert the message into the [official protocol buffers text
@@ -7,11 +7,19 @@
 * Add [well-known proto types][wkts] as libraries. This change is required for
   protoc_plugin-25.0.0. ([#1081])
 
+* **Breaking:** Hide `PbList` and `PbMap` constructors. It is not possible to
+  construct these values correctly in user code, so the constructors are now
+  private. Existing uses of `PbList` can be replaced by `List` and `PbMap` can
+  be replaced by `Map`.
+
+  For immutable lists and maps, you can use `built_value`. ([#1072])
+
 [text format]: https://protobuf.dev/reference/protobuf/textformat-spec/
 [#1080]: https://github.com/google/protobuf.dart/pull/1080
 [#125]: https://github.com/google/protobuf.dart/issues/125
 [wkts]: https://protobuf.dev/reference/protobuf/google.protobuf
 [#1081]: https://github.com/google/protobuf.dart/pull/1081
+[#1072]: https://github.com/google/protobuf.dart/pull/1072
 
 ## 5.1.0
 
diff --git a/protobuf/lib/src/protobuf/field_info.dart b/protobuf/lib/src/protobuf/field_info.dart
index 775b3c0..59c709f 100644
--- a/protobuf/lib/src/protobuf/field_info.dart
+++ b/protobuf/lib/src/protobuf/field_info.dart
@@ -144,7 +144,7 @@
     this.enumValues,
     this.defaultEnumValue,
     String? protoName,
-  }) : makeDefault = (() => PbList<T>(check: check)),
+  }) : makeDefault = (() => newPbList<T>(check: check)),
        _protoName = protoName,
        assert(PbFieldType.isRepeated(type)),
        assert(!PbFieldType.isEnum(type) || valueOf != null);
@@ -169,7 +169,7 @@
   /// [GeneratedMessage.getField], doesn't create a repeated field.
   dynamic get readonlyDefault {
     if (isRepeated) {
-      return _emptyList ??= PbList.unmodifiable();
+      return _emptyList ??= newUnmodifiablePbList();
     }
     return makeDefault!();
   }
@@ -232,13 +232,13 @@
   /// Creates a repeated field.
   PbList<T> _createRepeatedField() {
     assert(isRepeated);
-    return PbList<T>(check: check);
+    return newPbList<T>(check: check);
   }
 
   /// Same as above, but allow a tighter typed [PbList] to be created.
   PbList<S> _createRepeatedFieldWithType<S extends T>() {
     assert(isRepeated);
-    return PbList<S>(check: check);
+    return newPbList<S>(check: check);
   }
 
   /// Convenience method to thread this FieldInfo's reified type parameter to
@@ -303,7 +303,7 @@
          tagNumber,
          index,
          type,
-         defaultOrMaker: () => PbMap<K, V>(keyFieldType, valueFieldType),
+         defaultOrMaker: () => newPbMap<K, V>(keyFieldType, valueFieldType),
          defaultEnumValue: defaultEnumValue,
          protoName: protoName,
        ) {
@@ -319,7 +319,7 @@
 
   PbMap<K, V> _createMapField() {
     assert(isMapField);
-    return PbMap<K, V>(keyFieldType, valueFieldType);
+    return newPbMap<K, V>(keyFieldType, valueFieldType);
   }
 }
 
diff --git a/protobuf/lib/src/protobuf/field_set.dart b/protobuf/lib/src/protobuf/field_set.dart
index 6677da0..89bae3d 100644
--- a/protobuf/lib/src/protobuf/field_set.dart
+++ b/protobuf/lib/src/protobuf/field_set.dart
@@ -402,7 +402,7 @@
     assert(fi.isMapField);
 
     if (_isReadOnly) {
-      return PbMap<K, V>.unmodifiable(fi.keyFieldType, fi.valueFieldType);
+      return newUnmodifiablePbMap<K, V>(fi.keyFieldType, fi.valueFieldType);
     }
 
     final map = fi._createMapField();
diff --git a/protobuf/lib/src/protobuf/pb_list.dart b/protobuf/lib/src/protobuf/pb_list.dart
index eed80e2..137ad55 100644
--- a/protobuf/lib/src/protobuf/pb_list.dart
+++ b/protobuf/lib/src/protobuf/pb_list.dart
@@ -13,6 +13,17 @@
 /// Throws [ArgumentError] or [RangeError] when the item is not valid.
 typedef CheckFunc<E> = void Function(E? x);
 
+@pragma('dart2js:tryInline')
+@pragma('vm:prefer-inline')
+@pragma('wasm:prefer-inline')
+PbList<E> newPbList<E>({CheckFunc<E>? check}) => PbList._(check: check);
+
+@pragma('dart2js:tryInline')
+@pragma('vm:prefer-inline')
+@pragma('wasm:prefer-inline')
+PbList<E> newUnmodifiablePbList<E>({CheckFunc<E>? check}) =>
+    PbList._unmodifiable();
+
 /// A [ListBase] implementation used for protobuf `repeated` fields.
 class PbList<E> extends ListBase<E> {
   /// The actual list storing the elements.
@@ -35,17 +46,13 @@
 
   bool get isFrozen => _isReadOnly;
 
-  PbList({CheckFunc<E>? check}) : _wrappedList = <E>[], _check = check;
+  PbList._({CheckFunc<E>? check}) : _wrappedList = <E>[], _check = check;
 
-  PbList.unmodifiable()
+  PbList._unmodifiable()
     : _wrappedList = _emptyList,
       _check = checkNotNull,
       _isReadOnly = true;
 
-  PbList.from(Iterable<E> from)
-    : _wrappedList = List<E>.of(from),
-      _check = checkNotNull;
-
   @override
   @pragma('dart2js:never-inline')
   void add(E element) {
@@ -288,7 +295,7 @@
   }
 
   PbList<E> _deepCopy() {
-    final newList = PbList<E>(check: _check);
+    final newList = PbList<E>._(check: _check);
     final wrappedList = _wrappedList;
     final newWrappedList = newList._wrappedList;
     if (wrappedList.isNotEmpty) {
diff --git a/protobuf/lib/src/protobuf/pb_map.dart b/protobuf/lib/src/protobuf/pb_map.dart
index 0051333..0200f4a 100644
--- a/protobuf/lib/src/protobuf/pb_map.dart
+++ b/protobuf/lib/src/protobuf/pb_map.dart
@@ -10,6 +10,18 @@
 const mapKeyFieldNumber = 1;
 const mapValueFieldNumber = 2;
 
+@pragma('dart2js:tryInline')
+@pragma('vm:prefer-inline')
+@pragma('wasm:prefer-inline')
+PbMap<K, V> newPbMap<K, V>(int keyFieldType, int valueFieldType) =>
+    PbMap<K, V>._(keyFieldType, valueFieldType);
+
+@pragma('dart2js:tryInline')
+@pragma('vm:prefer-inline')
+@pragma('wasm:prefer-inline')
+PbMap<K, V> newUnmodifiablePbMap<K, V>(int keyFieldType, int valueFieldType) =>
+    PbMap<K, V>._unmodifiable(keyFieldType, valueFieldType);
+
 /// A [MapBase] implementation used for protobuf `map` fields.
 class PbMap<K, V> extends MapBase<K, V> {
   /// Key type of the map. Per proto2 and proto3 specs, this needs to be an
@@ -34,9 +46,9 @@
 
   bool _isReadOnly = false;
 
-  PbMap(this.keyFieldType, this.valueFieldType) : _wrappedMap = <K, V>{};
+  PbMap._(this.keyFieldType, this.valueFieldType) : _wrappedMap = <K, V>{};
 
-  PbMap.unmodifiable(this.keyFieldType, this.valueFieldType)
+  PbMap._unmodifiable(this.keyFieldType, this.valueFieldType)
     : _wrappedMap = <K, V>{},
       _isReadOnly = true;
 
@@ -114,7 +126,7 @@
   }
 
   PbMap<K, V> _deepCopy() {
-    final newMap = PbMap<K, V>(keyFieldType, valueFieldType);
+    final newMap = PbMap<K, V>._(keyFieldType, valueFieldType);
     final wrappedMap = _wrappedMap;
     final newWrappedMap = newMap._wrappedMap;
     if (PbFieldType.isGroupOrMessage(valueFieldType)) {
diff --git a/protobuf/pubspec.yaml b/protobuf/pubspec.yaml
index e508c44..b2fa5d5 100644
--- a/protobuf/pubspec.yaml
+++ b/protobuf/pubspec.yaml
@@ -1,5 +1,5 @@
 name: protobuf
-version: 5.2.0
+version: 6.0.0
 description: >-
   Runtime library for protocol buffers support. Use with package:protoc_plugin
   to generate Dart code for your '.proto' files.
diff --git a/protobuf/test/list_test.dart b/protobuf/test/list_test.dart
index 23e9951..ea95cc8 100644
--- a/protobuf/test/list_test.dart
+++ b/protobuf/test/list_test.dart
@@ -2,22 +2,13 @@
 // 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.
 
-import 'package:fixnum/fixnum.dart';
-import 'package:protobuf/protobuf.dart';
 import 'package:test/test.dart';
 
-// [ArgumentError] in production mode, [TypeError] in checked.
-final invalidArgumentException = predicate(
-  (e) => e is ArgumentError || e is TypeError,
-);
-final badArgument = throwsA(invalidArgumentException);
-
-// Suppress an analyzer warning for a deliberate type mismatch.
-T cast<T>(Object? x) => x as T;
+import 'mock_util.dart';
 
 void main() {
   test('testPbList handles basic operations', () {
-    final lb1 = PbList<int>();
+    final lb1 = T().int32s;
     expect(lb1, []);
 
     lb1.add(1);
@@ -63,7 +54,7 @@
   });
 
   test('PbList handles range operations', () {
-    final lb2 = PbList<int>();
+    final lb2 = T().int32s;
 
     lb2.addAll([1, 2, 3, 4, 5, 6, 7, 8, 9]);
     expect(lb2.sublist(3, 7), [4, 5, 6, 7]);
@@ -89,168 +80,4 @@
     lb2.setRange(5, 6, [88, 99].take(2), 1);
     expect(lb2, [1, 2, 3, 9, 8, 99]);
   });
-
-  test('PbList validates items', () {
-    expect(() {
-      // ignore: unnecessary_cast
-      (PbList<int>() as List).add('hello');
-    }, throwsA(TypeMatcher<TypeError>()));
-  });
-
-  test('PbList for signed int32 validates items', () {
-    final List<int> list = PbList(check: getCheckFunction(PbFieldType.P3));
-
-    expect(() {
-      list.add(-2147483649);
-    }, throwsArgumentError);
-
-    expect(
-      () {
-        list.add(-2147483648);
-      },
-      returnsNormally,
-      reason: 'could not add min signed int32 to a PbList',
-    );
-
-    expect(() {
-      list.add(2147483648);
-    }, throwsArgumentError);
-
-    expect(
-      () {
-        list.add(2147483647);
-      },
-      returnsNormally,
-      reason: 'could not add max signed int32 to a PbList',
-    );
-  });
-
-  test('PBList for unsigned int32 validates items', () {
-    final List<int> list = PbList(check: getCheckFunction(PbFieldType.PU3));
-
-    expect(() {
-      list.add(-1);
-    }, throwsArgumentError);
-
-    expect(
-      () {
-        list.add(0);
-      },
-      returnsNormally,
-      reason: 'could not add zero to a PbList',
-    );
-
-    expect(() {
-      list.add(4294967296);
-    }, throwsArgumentError);
-
-    expect(
-      () {
-        list.add(4294967295);
-      },
-      returnsNormally,
-      reason: 'could not add max unsigned int32 to a PbList',
-    );
-  });
-
-  test('PbList for float validates items', () {
-    final List<double> list = PbList(check: getCheckFunction(PbFieldType.PF));
-
-    expect(() {
-      list.add(3.4028234663852886E39);
-    }, throwsArgumentError);
-
-    expect(() {
-      list.add(-3.4028234663852886E39);
-    }, throwsArgumentError);
-
-    expect(
-      () {
-        list.add(3.4028234663852886E38);
-      },
-      returnsNormally,
-      reason: 'could not add max float to a PbList',
-    );
-
-    expect(
-      () {
-        list.add(-3.4028234663852886E38);
-      },
-      returnsNormally,
-      reason: 'could not add min float to a PbList',
-    );
-  });
-
-  test('PbList for signed Int64 validates items', () {
-    final List<Int64> list = PbList();
-    expect(() {
-      list.add(cast(0)); // not an Int64
-    }, badArgument);
-
-    expect(
-      () {
-        list.add(Int64(0));
-      },
-      returnsNormally,
-      reason: 'could not add Int64(0) to a PbList',
-    );
-
-    expect(
-      () {
-        list.add(Int64.MAX_VALUE);
-      },
-      returnsNormally,
-      reason: 'could not add max Int64 to a PbList',
-    );
-
-    expect(
-      () {
-        list.add(Int64.MIN_VALUE);
-      },
-      returnsNormally,
-      reason: 'could not add min Int64 to PbList',
-    );
-  });
-
-  test('PbList for unsigned Int64 validates items', () {
-    final List<Int64> list = PbList();
-    expect(() {
-      list.add(cast(0)); // not an Int64
-    }, badArgument);
-
-    expect(
-      () {
-        list.add(Int64(0));
-      },
-      returnsNormally,
-      reason: 'could not add Int64(0) to a PbList',
-    );
-
-    // Adding -1 should work because we are storing the bits as-is.
-    // (It will be interpreted as a positive number.)
-    // See: https://github.com/google/protobuf.dart/issues/44
-    expect(
-      () {
-        list.add(Int64(-1));
-      },
-      returnsNormally,
-      reason: 'could not add Int64(-1) to a PbList',
-    );
-
-    expect(
-      () {
-        list.add(Int64.MAX_VALUE);
-      },
-      returnsNormally,
-      reason: 'could not add max Int64 to a PbList',
-    );
-
-    expect(
-      () {
-        list.add(Int64.MIN_VALUE);
-      },
-      returnsNormally,
-      reason: 'could not add min Int64 to a PbList',
-    );
-  });
 }
diff --git a/protoc_plugin/pubspec.yaml b/protoc_plugin/pubspec.yaml
index 6e55b50..662d385 100644
--- a/protoc_plugin/pubspec.yaml
+++ b/protoc_plugin/pubspec.yaml
@@ -14,7 +14,7 @@
   dart_style: ^3.0.0
   fixnum: ^1.0.0
   path: ^1.8.0
-  protobuf: ^5.2.0
+  protobuf: ^6.0.0
   pub_semver: ^2.2.0
 
 dev_dependencies: