OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 part of protobuf; | |
6 | |
7 // Used by the protoc plugin to avoid name conflicts. | |
8 // TODO: extract names automatically somehow? | |
9 const PbMapMixin_reservedNames = const [ | |
10 'addAll', 'containsKey', 'containsValue', 'forEach', 'putIfAbsent', | |
11 'remove', 'isEmpty', 'isNotEmpty', 'keys', 'length', 'values', | |
12 'getMapValue', 'mustGetMapValue', 'setMapValue' | |
13 ]; | |
14 | |
15 /// A PbMapMixin provides an experimental implementation of the | |
Siggi Cherem (dart-lang)
2015/06/22 19:45:37
since your new protoc is more pluggable, I wonder
skybrian
2015/06/22 21:53:50
I'd like to keep it in the open source code as an
Siggi Cherem (dart-lang)
2015/06/22 22:22:25
Totally, we could still include an example in the
| |
16 /// Map interface for a GeneratedMessage. | |
17 /// | |
18 /// This mixin is enabled via an option in | |
19 /// dart_options.proto in dart-protoc-plugin. | |
20 class PbMapMixin implements Map<String, dynamic> { | |
Søren Gjesse
2015/06/22 07:25:01
Just for context here. Is this supposed to replace
skybrian
2015/06/22 21:53:50
Yes.
| |
21 | |
22 // GeneratedMessage properties and methods used by this mixin. | |
23 | |
24 BuilderInfo info_; | |
25 void clear(); | |
26 int getTagNumber(String fieldName); | |
27 getField(int tagNumber); | |
28 void setField(int tagNumber, var value, [int fieldType = null]); | |
29 | |
30 @override | |
31 operator [] (key) { | |
32 if (key is !String) return null; | |
33 var tag = getTagNumber(key); | |
34 if (tag == null) return null; | |
35 return getField(tag); | |
36 } | |
37 | |
38 @override | |
39 operator []= (String key, val) { | |
40 var tag = getTagNumber(key); | |
41 if (tag == null) { | |
42 throw new ArgumentError( | |
43 "field '${key}' not found in ${info_.messageName}"); | |
44 } | |
45 setField(tag, val); | |
46 } | |
47 | |
48 @override | |
49 get keys => info_.byName.keys; | |
50 | |
51 @override | |
52 bool containsKey(Object key) => info_.byName.containsKey(key); | |
53 | |
54 @override | |
55 get length => info_.byName.length; | |
56 | |
57 @override | |
58 remove(key) { | |
59 throw new UnsupportedError( | |
60 "remove() not supported by ${info_.messageName}"); | |
61 } | |
62 | |
63 // methods copied from MapMixin (since mixins cannot mix in other mixins). | |
Søren Gjesse
2015/06/22 07:25:01
Could another option be that whenever PbMapMixin i
skybrian
2015/06/22 21:53:50
Good idea. I can implement a simple form of inheri
| |
64 | |
65 @override | |
66 void forEach(void action(String key, value)) { | |
67 for (String key in keys) { | |
68 action(key, this[key]); | |
69 } | |
70 } | |
71 | |
72 @override | |
73 void addAll(Map<String, dynamic> other) { | |
74 for (String key in other.keys) { | |
75 this[key] = other[key]; | |
76 } | |
77 } | |
78 | |
79 @override | |
80 bool containsValue(value) { | |
81 for (String key in keys) { | |
82 if (this[key] == value) return true; | |
83 } | |
84 return false; | |
85 } | |
86 | |
87 @override | |
88 putIfAbsent(String key, ifAbsent()) { | |
89 if (keys.contains(key)) { | |
90 return this[key]; | |
91 } | |
92 return this[key] = ifAbsent(); | |
93 } | |
94 | |
95 bool get isEmpty => keys.isEmpty; | |
96 bool get isNotEmpty => keys.isNotEmpty; | |
97 Iterable get values => new _PbMapMixinValues(this); | |
98 } | |
99 | |
100 class _PbMapMixinValues extends Iterable { | |
101 final PbMapMixin _map; | |
102 _PbMapMixinValues(this._map); | |
103 | |
104 int get length => _map.length; | |
105 bool get isEmpty => _map.isEmpty; | |
106 bool get isNotEmpty => _map.isNotEmpty; | |
107 get first => _map[_map.keys.first]; | |
108 get single => _map[_map.keys.single]; | |
109 get last => _map[_map.keys.last]; | |
110 | |
111 Iterator get iterator => new _PbMapMixinValueIterator(_map); | |
112 } | |
113 | |
114 class _PbMapMixinValueIterator implements Iterator { | |
115 final Iterator _keys; | |
116 final PbMapMixin _map; | |
117 var _current = null; | |
118 | |
119 _PbMapMixinValueIterator(PbMapMixin map) : | |
120 _map = map, | |
121 _keys = map.keys.iterator; | |
122 | |
123 bool moveNext() { | |
124 if (_keys.moveNext()) { | |
125 _current = _map[_keys.current]; | |
126 return true; | |
127 } | |
128 _current = null; | |
129 return false; | |
130 } | |
131 | |
132 get current => _current; | |
133 } | |
OLD | NEW |