OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011, 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 typedef Builder CreateBuilderFunc(); |
| 6 typedef Object MakeDefaultFunc(); |
| 7 typedef ProtobufEnum ValueOfFunc(int value); |
| 8 |
| 9 class Builder implements ChangeListener { |
| 10 static final int _REQUIRED_BIT = 0x1; |
| 11 static final int _REPEATED_BIT = 0x2; |
| 12 static final int _PACKED_BIT = 0x4; |
| 13 |
| 14 static final int _BOOL_BIT = 0x10; |
| 15 static final int _BYTES_BIT = 0x20; |
| 16 static final int _STRING_BIT = 0x40; |
| 17 static final int _DOUBLE_BIT = 0x80; |
| 18 static final int _FLOAT_BIT = 0x100; |
| 19 static final int _ENUM_BIT = 0x200; |
| 20 static final int _GROUP_BIT = 0x400; |
| 21 static final int _INT32_BIT = 0x800; |
| 22 static final int _INT64_BIT = 0x1000; |
| 23 static final int _SINT32_BIT = 0x2000; |
| 24 static final int _SINT64_BIT = 0x4000; |
| 25 static final int _UINT32_BIT = 0x8000; |
| 26 static final int _UINT64_BIT = 0x10000; |
| 27 static final int _FIXED32_BIT = 0x20000; |
| 28 static final int _FIXED64_BIT = 0x40000; |
| 29 static final int _SFIXED32_BIT = 0x80000; |
| 30 static final int _SFIXED64_BIT = 0x100000; |
| 31 static final int _MESSAGE_BIT = 0x200000; |
| 32 |
| 33 static final int _OPTIONAL_BOOL = _BOOL_BIT; |
| 34 static final int _OPTIONAL_BYTES = _BYTES_BIT; |
| 35 static final int _OPTIONAL_STRING = _STRING_BIT; |
| 36 static final int _OPTIONAL_FLOAT = _FLOAT_BIT; |
| 37 static final int _OPTIONAL_DOUBLE = _DOUBLE_BIT; |
| 38 static final int _OPTIONAL_ENUM = _ENUM_BIT; |
| 39 static final int _OPTIONAL_GROUP = _GROUP_BIT; |
| 40 static final int _OPTIONAL_INT32 = _INT32_BIT; |
| 41 static final int _OPTIONAL_INT64 = _INT64_BIT; |
| 42 static final int _OPTIONAL_SINT32 = _SINT32_BIT; |
| 43 static final int _OPTIONAL_SINT64 = _SINT64_BIT; |
| 44 static final int _OPTIONAL_UINT32 = _UINT32_BIT; |
| 45 static final int _OPTIONAL_UINT64 = _UINT64_BIT; |
| 46 static final int _OPTIONAL_FIXED32 = _FIXED32_BIT; |
| 47 static final int _OPTIONAL_FIXED64 = _FIXED64_BIT; |
| 48 static final int _OPTIONAL_SFIXED32 = _SFIXED32_BIT; |
| 49 static final int _OPTIONAL_SFIXED64 = _SFIXED64_BIT; |
| 50 static final int _OPTIONAL_MESSAGE = _MESSAGE_BIT; |
| 51 |
| 52 static final int _REQUIRED_BOOL = _REQUIRED_BIT | _BOOL_BIT; |
| 53 static final int _REQUIRED_BYTES = _REQUIRED_BIT | _BYTES_BIT; |
| 54 static final int _REQUIRED_STRING = _REQUIRED_BIT | _STRING_BIT; |
| 55 static final int _REQUIRED_FLOAT = _REQUIRED_BIT | _FLOAT_BIT; |
| 56 static final int _REQUIRED_DOUBLE = _REQUIRED_BIT | _DOUBLE_BIT; |
| 57 static final int _REQUIRED_ENUM = _REQUIRED_BIT | _ENUM_BIT; |
| 58 static final int _REQUIRED_GROUP = _REQUIRED_BIT | _GROUP_BIT; |
| 59 static final int _REQUIRED_INT32 = _REQUIRED_BIT | _INT32_BIT; |
| 60 static final int _REQUIRED_INT64 = _REQUIRED_BIT | _INT64_BIT; |
| 61 static final int _REQUIRED_SINT32 = _REQUIRED_BIT | _SINT32_BIT; |
| 62 static final int _REQUIRED_SINT64 = _REQUIRED_BIT | _SINT64_BIT; |
| 63 static final int _REQUIRED_UINT32 = _REQUIRED_BIT | _UINT32_BIT; |
| 64 static final int _REQUIRED_UINT64 = _REQUIRED_BIT | _UINT64_BIT; |
| 65 static final int _REQUIRED_FIXED32 = _REQUIRED_BIT | _FIXED32_BIT; |
| 66 static final int _REQUIRED_FIXED64 = _REQUIRED_BIT | _FIXED64_BIT; |
| 67 static final int _REQUIRED_SFIXED32 = _REQUIRED_BIT | _SFIXED32_BIT; |
| 68 static final int _REQUIRED_SFIXED64 = _REQUIRED_BIT | _SFIXED64_BIT; |
| 69 static final int _REQUIRED_MESSAGE = _REQUIRED_BIT | _MESSAGE_BIT; |
| 70 |
| 71 static final int _REPEATED_BOOL = _REPEATED_BIT | _BOOL_BIT; |
| 72 static final int _REPEATED_BYTES = _REPEATED_BIT | _BYTES_BIT; |
| 73 static final int _REPEATED_STRING = _REPEATED_BIT | _STRING_BIT; |
| 74 static final int _REPEATED_FLOAT = _REPEATED_BIT | _FLOAT_BIT; |
| 75 static final int _REPEATED_DOUBLE = _REPEATED_BIT | _DOUBLE_BIT; |
| 76 static final int _REPEATED_ENUM = _REPEATED_BIT | _ENUM_BIT; |
| 77 static final int _REPEATED_GROUP = _REPEATED_BIT | _GROUP_BIT; |
| 78 static final int _REPEATED_INT32 = _REPEATED_BIT | _INT32_BIT; |
| 79 static final int _REPEATED_INT64 = _REPEATED_BIT | _INT64_BIT; |
| 80 static final int _REPEATED_SINT32 = _REPEATED_BIT | _SINT32_BIT; |
| 81 static final int _REPEATED_SINT64 = _REPEATED_BIT | _SINT64_BIT; |
| 82 static final int _REPEATED_UINT32 = _REPEATED_BIT | _UINT32_BIT; |
| 83 static final int _REPEATED_UINT64 = _REPEATED_BIT | _UINT64_BIT; |
| 84 static final int _REPEATED_FIXED32 = _REPEATED_BIT | _FIXED32_BIT; |
| 85 static final int _REPEATED_FIXED64 = _REPEATED_BIT | _FIXED64_BIT; |
| 86 static final int _REPEATED_SFIXED32 = _REPEATED_BIT | _SFIXED32_BIT; |
| 87 static final int _REPEATED_SFIXED64 = _REPEATED_BIT | _SFIXED64_BIT; |
| 88 static final int _REPEATED_MESSAGE = _REPEATED_BIT | _MESSAGE_BIT; |
| 89 |
| 90 static final int _PACKED_BOOL = _REPEATED_BIT | _PACKED_BIT | _BOOL_BIT; |
| 91 static final int _PACKED_FLOAT = _REPEATED_BIT | _PACKED_BIT | _FLOAT_BIT; |
| 92 static final int _PACKED_DOUBLE = _REPEATED_BIT | _PACKED_BIT | _DOUBLE_BIT; |
| 93 static final int _PACKED_ENUM = _REPEATED_BIT | _PACKED_BIT | _ENUM_BIT; |
| 94 static final int _PACKED_INT32 = _REPEATED_BIT | _PACKED_BIT | _INT32_BIT; |
| 95 static final int _PACKED_INT64 = _REPEATED_BIT | _PACKED_BIT | _INT64_BIT; |
| 96 static final int _PACKED_SINT32 = _REPEATED_BIT | _PACKED_BIT | _SINT32_BIT; |
| 97 static final int _PACKED_SINT64 = _REPEATED_BIT | _PACKED_BIT | _SINT64_BIT; |
| 98 static final int _PACKED_UINT32 = _REPEATED_BIT | _PACKED_BIT | _UINT32_BIT; |
| 99 static final int _PACKED_UINT64 = _REPEATED_BIT | _PACKED_BIT | _UINT64_BIT; |
| 100 static final int _PACKED_FIXED32 = _REPEATED_BIT | _PACKED_BIT | _FIXED32_BIT; |
| 101 static final int _PACKED_FIXED64 = _REPEATED_BIT | _PACKED_BIT | _FIXED64_BIT; |
| 102 static final int _PACKED_SFIXED32 = _REPEATED_BIT | _PACKED_BIT | |
| 103 _SFIXED32_BIT; |
| 104 static final int _PACKED_SFIXED64 = _REPEATED_BIT | _PACKED_BIT | |
| 105 _SFIXED64_BIT; |
| 106 |
| 107 // Short names for use in generated code |
| 108 |
| 109 // _O_ptional |
| 110 static final int OB = _OPTIONAL_BOOL; |
| 111 static final int OY = _OPTIONAL_BYTES; |
| 112 static final int OS = _OPTIONAL_STRING; |
| 113 static final int OF = _OPTIONAL_FLOAT; |
| 114 static final int OD = _OPTIONAL_DOUBLE; |
| 115 static final int OE = _OPTIONAL_ENUM; |
| 116 static final int OG = _OPTIONAL_GROUP; |
| 117 static final int O3 = _OPTIONAL_INT32; |
| 118 static final int O6 = _OPTIONAL_INT64; |
| 119 static final int OS3 = _OPTIONAL_SINT32; |
| 120 static final int OS6 = _OPTIONAL_SINT64; |
| 121 static final int OU3 = _OPTIONAL_UINT32; |
| 122 static final int OU6 = _OPTIONAL_UINT64; |
| 123 static final int OF3 = _OPTIONAL_FIXED32; |
| 124 static final int OF6 = _OPTIONAL_FIXED64; |
| 125 static final int OSF3 = _OPTIONAL_SFIXED32; |
| 126 static final int OSF6 = _OPTIONAL_SFIXED64; |
| 127 static final int OM = _OPTIONAL_MESSAGE; |
| 128 |
| 129 // re_Q_uired |
| 130 static final int QB = _REQUIRED_BOOL; |
| 131 static final int QY = _REQUIRED_BYTES; |
| 132 static final int QS = _REQUIRED_STRING; |
| 133 static final int QF = _REQUIRED_FLOAT; |
| 134 static final int QD = _REQUIRED_DOUBLE; |
| 135 static final int QE = _REQUIRED_ENUM; |
| 136 static final int QG = _REQUIRED_GROUP; |
| 137 static final int Q3 = _REQUIRED_INT32; |
| 138 static final int Q6 = _REQUIRED_INT64; |
| 139 static final int QS3 = _REQUIRED_SINT32; |
| 140 static final int QS6 = _REQUIRED_SINT64; |
| 141 static final int QU3 = _REQUIRED_UINT32; |
| 142 static final int QU6 = _REQUIRED_UINT64; |
| 143 static final int QF3 = _REQUIRED_FIXED32; |
| 144 static final int QF6 = _REQUIRED_FIXED64; |
| 145 static final int QSF3 = _REQUIRED_SFIXED32; |
| 146 static final int QSF6 = _REQUIRED_SFIXED64; |
| 147 static final int QM = _REQUIRED_MESSAGE; |
| 148 |
| 149 // re_P_eated |
| 150 static final int PB = _REPEATED_BOOL; |
| 151 static final int PY = _REPEATED_BYTES; |
| 152 static final int PS = _REPEATED_STRING; |
| 153 static final int PF = _REPEATED_FLOAT; |
| 154 static final int PD = _REPEATED_DOUBLE; |
| 155 static final int PE = _REPEATED_ENUM; |
| 156 static final int PG = _REPEATED_GROUP; |
| 157 static final int P3 = _REPEATED_INT32; |
| 158 static final int P6 = _REPEATED_INT64; |
| 159 static final int PS3 = _REPEATED_SINT32; |
| 160 static final int PS6 = _REPEATED_SINT64; |
| 161 static final int PU3 = _REPEATED_UINT32; |
| 162 static final int PU6 = _REPEATED_UINT64; |
| 163 static final int PF3 = _REPEATED_FIXED32; |
| 164 static final int PF6 = _REPEATED_FIXED64; |
| 165 static final int PSF3 = _REPEATED_SFIXED32; |
| 166 static final int PSF6 = _REPEATED_SFIXED64; |
| 167 static final int PM = _REPEATED_MESSAGE; |
| 168 |
| 169 // pac_K_ed |
| 170 static final int KB = _PACKED_BOOL; |
| 171 static final int KE = _PACKED_ENUM; |
| 172 static final int KF = _PACKED_FLOAT; |
| 173 static final int KD = _PACKED_DOUBLE; |
| 174 static final int K3 = _PACKED_INT32; |
| 175 static final int K6 = _PACKED_INT64; |
| 176 static final int KS3 = _PACKED_SINT32; |
| 177 static final int KS6 = _PACKED_SINT64; |
| 178 static final int KU3 = _PACKED_UINT32; |
| 179 static final int KU6 = _PACKED_UINT64; |
| 180 static final int KF3 = _PACKED_FIXED32; |
| 181 static final int KF6 = _PACKED_FIXED64; |
| 182 static final int KSF3 = _PACKED_SFIXED32; |
| 183 static final int KSF6 = _PACKED_SFIXED64; |
| 184 |
| 185 // Closures commonly used by initializers |
| 186 static MakeDefaultFunc __STRING_EMPTY; // () => '' |
| 187 static MakeDefaultFunc __BYTES_EMPTY; // () => <int>[] |
| 188 static MakeDefaultFunc __BOOL_FALSE; // () => false |
| 189 static MakeDefaultFunc __INT_ZERO; // () => 0 |
| 190 static MakeDefaultFunc __DOUBLE_ZERO; // () => 0.0 |
| 191 |
| 192 static MakeDefaultFunc get _STRING_EMPTY() { |
| 193 if (__STRING_EMPTY === null) { |
| 194 __STRING_EMPTY = () => ''; |
| 195 } |
| 196 return __STRING_EMPTY; |
| 197 } |
| 198 |
| 199 static MakeDefaultFunc get _BYTES_EMPTY() { |
| 200 if (__BYTES_EMPTY === null) { |
| 201 __BYTES_EMPTY = () => <int>[]; |
| 202 } |
| 203 return __BYTES_EMPTY; |
| 204 } |
| 205 |
| 206 static MakeDefaultFunc get _BOOL_FALSE() { |
| 207 if (__BOOL_FALSE === null) { |
| 208 __BOOL_FALSE = () => false; |
| 209 } |
| 210 return __BOOL_FALSE; |
| 211 } |
| 212 |
| 213 static MakeDefaultFunc get _INT_ZERO() { |
| 214 if (__INT_ZERO === null) { |
| 215 __INT_ZERO = () => 0; |
| 216 } |
| 217 return __INT_ZERO; |
| 218 } |
| 219 |
| 220 static MakeDefaultFunc get _DOUBLE_ZERO() { |
| 221 if (__DOUBLE_ZERO === null) { |
| 222 __DOUBLE_ZERO = () => 0.0; |
| 223 } |
| 224 return __DOUBLE_ZERO; |
| 225 } |
| 226 |
| 227 static MakeDefaultFunc _defaultForType(int type) { |
| 228 switch (type) { |
| 229 case _OPTIONAL_BOOL: case _REQUIRED_BOOL: |
| 230 return _BOOL_FALSE; |
| 231 case _OPTIONAL_BYTES: case _REQUIRED_BYTES: |
| 232 return _BYTES_EMPTY; |
| 233 case _OPTIONAL_STRING: case _REQUIRED_STRING: |
| 234 return _STRING_EMPTY; |
| 235 case _OPTIONAL_FLOAT: case _REQUIRED_FLOAT: |
| 236 case _OPTIONAL_DOUBLE: case _REQUIRED_DOUBLE: |
| 237 return _DOUBLE_ZERO; |
| 238 case _OPTIONAL_INT32: case _REQUIRED_INT32: |
| 239 case _OPTIONAL_INT64: case _REQUIRED_INT64: |
| 240 case _OPTIONAL_SINT32: case _REQUIRED_SINT32: |
| 241 case _OPTIONAL_SINT64: case _REQUIRED_SINT64: |
| 242 case _OPTIONAL_UINT32: case _REQUIRED_UINT32: |
| 243 case _OPTIONAL_UINT64: case _REQUIRED_UINT64: |
| 244 case _OPTIONAL_FIXED32: case _REQUIRED_FIXED32: |
| 245 case _OPTIONAL_FIXED64: case _REQUIRED_FIXED64: |
| 246 case _OPTIONAL_SFIXED32: case _REQUIRED_SFIXED32: |
| 247 case _OPTIONAL_SFIXED64: case _REQUIRED_SFIXED64: |
| 248 return _INT_ZERO; |
| 249 default: |
| 250 return null; |
| 251 } |
| 252 } |
| 253 |
| 254 static Function _converterForType(int type) { |
| 255 if (((type & _REPEATED_BIT) != 0) || ((type & _PACKED_BIT) != 0)) { |
| 256 return ((type & _BYTES_BIT) != 0) ? |
| 257 _toImmutableListNonGrowable : _toImmutableListIdentity; |
| 258 } else { |
| 259 return ((type & _BYTES_BIT) != 0) ? _toNonGrowableList : _identity; |
| 260 } |
| 261 } |
| 262 |
| 263 static Object _identity(Object source) => source; |
| 264 |
| 265 static List _toNonGrowableList(List source) { |
| 266 if (source is PbImmutableList) { |
| 267 return source; |
| 268 } else { |
| 269 return new PbImmutableList.from(source); |
| 270 } |
| 271 } |
| 272 |
| 273 static List _toImmutableListIdentity(PbList source) { |
| 274 return source.asImmutable(); |
| 275 } |
| 276 |
| 277 static List _toImmutableListNonGrowable(PbList source) { |
| 278 return source.asImmutable(_toNonGrowableList); |
| 279 } |
| 280 |
| 281 Map<int, Dynamic> _fieldValues; |
| 282 bool _isClean; |
| 283 UnknownFieldSet _unknownFields; |
| 284 Map<int, Extension> _extensions; |
| 285 |
| 286 Builder() |
| 287 : _unknownFields = UnknownFieldSet.defaultInstance, |
| 288 _fieldValues = new Map<int, Dynamic>() { |
| 289 initialize_(); |
| 290 } |
| 291 |
| 292 /** |
| 293 * Add an extension field value to a repeated field. The backing |
| 294 * [List] will be created if necessary. |
| 295 */ |
| 296 void addExtension(Extension extension, var value) { |
| 297 _checkExtension(extension); |
| 298 if ((extension.type & _REPEATED_BIT) == 0) { |
| 299 throw new PbException( |
| 300 "Cannot add to a non-repeated field (use 'setExtension()')"); |
| 301 } |
| 302 // Validate type and range |
| 303 value = _validate(extension.tagNumber, extension.type & ~0x7, value); |
| 304 |
| 305 var list = _fieldValues[extension.tagNumber]; |
| 306 if (list == null) { |
| 307 list = extension.makeDefault(); |
| 308 _setExtension(extension, list); |
| 309 } |
| 310 |
| 311 list.add(value); |
| 312 onChanged(); |
| 313 } |
| 314 |
| 315 Message build() { |
| 316 Message result = buildPartial(); |
| 317 if (!isInitialized()) { |
| 318 List<String> invalidFields = <String>[]; |
| 319 _findInvalidFields(invalidFields); |
| 320 throw new UninitializedMessageException(invalidFields); |
| 321 } |
| 322 return result; |
| 323 } |
| 324 |
| 325 Message buildParsed() { |
| 326 Message result = buildPartial(); |
| 327 if (!isInitialized()) { |
| 328 List<String> invalidFields = <String>[]; |
| 329 _findInvalidFields(invalidFields); |
| 330 throw new UninitializedMessageException(invalidFields); |
| 331 } |
| 332 return result; |
| 333 } |
| 334 |
| 335 abstract Message buildPartial(); |
| 336 |
| 337 // Shorthand for clearField |
| 338 void c_(int tagNumber) { |
| 339 clearField(tagNumber); |
| 340 } |
| 341 |
| 342 void clear() { |
| 343 _unknownFields = UnknownFieldSet.defaultInstance; |
| 344 _fieldValues = new Map<int, Dynamic>(); |
| 345 _isClean = true; |
| 346 } |
| 347 |
| 348 void clearExtension(Extension extension) { |
| 349 _checkExtension(extension); |
| 350 _fieldValues.remove(extension.tagNumber); |
| 351 Object value = extension.makeDefault(); |
| 352 if (value is List) { |
| 353 _setExtension(extension, value); |
| 354 } else { |
| 355 _extensions.remove(extension.tagNumber); |
| 356 } |
| 357 } |
| 358 |
| 359 void clearField(int tagNumber) { |
| 360 _fieldValues.remove(tagNumber); |
| 361 // Restore the default value for the field |
| 362 // For repeated fields, the default is an empty list |
| 363 // For required/optional fields, the BuilderInfo contains the initializer |
| 364 int fieldType = _getFieldType(tagNumber); |
| 365 if ((fieldType & _REPEATED_BIT) != 0) { |
| 366 _fieldValues[tagNumber] = new PbList(this); |
| 367 } else { |
| 368 Object defaultValue = info_.defaultValue(tagNumber); |
| 369 if (defaultValue !== null) { |
| 370 _fieldValues[tagNumber] = defaultValue; |
| 371 } |
| 372 } |
| 373 } |
| 374 |
| 375 bool extensionsAreInitialized() { |
| 376 if (_extensions == null) { |
| 377 return true; |
| 378 } |
| 379 return _extensions.getKeys().every(bool _(int tagNumber) { |
| 380 return info_._isFieldInitialized(_fieldValues, tagNumber, |
| 381 _extensions[tagNumber].type); |
| 382 }); |
| 383 } |
| 384 |
| 385 // Allow the contents of each map or set to be changed, but not its reference |
| 386 Map<int, Object> get fieldValues() { |
| 387 // Force initialization of field values to defaults |
| 388 if (info_ !== null) { |
| 389 for (FieldInfo i in info_.fieldInfo.getValues()) { |
| 390 if (i.makeDefault != null) fieldValues [i.tagNumber] = i.makeDefault(); |
| 391 } |
| 392 } |
| 393 return _fieldValues; |
| 394 } |
| 395 |
| 396 /** |
| 397 * Shorthand for [:getField(tagNumber):]. |
| 398 */ |
| 399 Dynamic g_(int tagNumber) => getField(tagNumber); |
| 400 |
| 401 /** |
| 402 * Returns the value of the given extension. For repeated fields that have |
| 403 * not been set previously, [:null:] is returned. |
| 404 */ |
| 405 Dynamic getExtension(Extension extension) { |
| 406 _checkExtension(extension); |
| 407 return getField(extension.tagNumber); |
| 408 } |
| 409 |
| 410 /** |
| 411 * Returns the number of elements in the given extension. For repeated fields |
| 412 * that have not been set previously, or for non-repeated fields, [:0:] is |
| 413 * returned. |
| 414 */ |
| 415 int getExtensionCount(Extension extension) { |
| 416 _checkExtension(extension); |
| 417 List list = _fieldValues[extension.tagNumber]; |
| 418 return (list === null || list is! List) ? 0 : list.length; |
| 419 } |
| 420 |
| 421 Object getField(int tagNumber) { |
| 422 var value = _fieldValues[tagNumber]; |
| 423 // Initialize the field |
| 424 if (value === null) { |
| 425 MakeDefaultFunc makeDefaultFunc = info_.makeDefault(tagNumber); |
| 426 if (makeDefaultFunc == null) { |
| 427 makeDefaultFunc = _extensions[tagNumber].makeDefault; |
| 428 if (makeDefaultFunc == null) { |
| 429 throw new PbException("Can't make default for field " |
| 430 "${info_.fieldName(tagNumber)} in message ${info_.messageName}"); |
| 431 } |
| 432 } |
| 433 value = makeDefaultFunc(); |
| 434 _fieldValues[tagNumber] = value; |
| 435 } |
| 436 return value; |
| 437 } |
| 438 |
| 439 // Shorthand for hasField |
| 440 bool h_(int tagNumber) => hasField(tagNumber); |
| 441 |
| 442 /** |
| 443 * Return [:true:] if a value of the given extension is present. |
| 444 */ |
| 445 bool hasExtension(Extension extension) { |
| 446 _checkExtension(extension); |
| 447 return hasField(extension.tagNumber); |
| 448 } |
| 449 |
| 450 bool hasField(int tagNumber) { |
| 451 int fieldType = info_.fieldType(tagNumber); |
| 452 if (!_fieldValues.containsKey(tagNumber)) { |
| 453 return false; |
| 454 } |
| 455 var value = _fieldValues[tagNumber]; |
| 456 if (value is List && value.isEmpty()) { |
| 457 return false; |
| 458 } |
| 459 return true; |
| 460 } |
| 461 |
| 462 // Overriden by subclasses |
| 463 abstract BuilderInfo get info_(); |
| 464 |
| 465 abstract void initialize_(); |
| 466 |
| 467 bool isInitialized() { |
| 468 if (!info_.hasRequiredFields) { |
| 469 return true; |
| 470 } |
| 471 return info_.isInitialized(_fieldValues) && extensionsAreInitialized(); |
| 472 } |
| 473 |
| 474 Builder mergeFromBuffer(List<int> input, |
| 475 [ExtensionRegistry extensionRegistry]) { |
| 476 CodedBufferReader codedInput = new CodedBufferReader.fromBuffer(input); |
| 477 extensionRegistry = extensionRegistry == null ? |
| 478 ExtensionRegistry.EMPTY_REGISTRY : extensionRegistry; |
| 479 mergeFromCodedBufferReader(codedInput, extensionRegistry); |
| 480 codedInput.checkLastTagWas(0); |
| 481 return this; |
| 482 } |
| 483 |
| 484 Builder mergeFromCodedBufferReader(CodedBufferReader input, |
| 485 [ExtensionRegistry extensionRegistry]) { |
| 486 UnknownFieldSet_Builder unknownFieldSetBuilder = |
| 487 new UnknownFieldSet_Builder(unknownFields); |
| 488 extensionRegistry = extensionRegistry == null ? |
| 489 ExtensionRegistry.EMPTY_REGISTRY : extensionRegistry; |
| 490 |
| 491 void readPackableIoc(int wireType, int tagNumber, var iocReadFunc) { |
| 492 List list = getField(tagNumber); |
| 493 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { |
| 494 // Packed |
| 495 int length = input.readInt32(); |
| 496 int limit = input._pushLimit(length); |
| 497 while (input.getBytesUntilLimit() > 0) { |
| 498 iocReadFunc((var v) => list.add(v)); |
| 499 } |
| 500 input._popLimit(limit); |
| 501 } else { |
| 502 // Not-packed |
| 503 iocReadFunc((var v) => list.add(v)); |
| 504 } |
| 505 } |
| 506 |
| 507 void readPackable(int wireType, int tagNumber, var readFunc) { |
| 508 readPackableIoc(wireType, tagNumber, |
| 509 (var assigner) => assigner(readFunc())); |
| 510 } |
| 511 |
| 512 bool wireTypeMatch(int tagNumber, int fieldType, int wireType) { |
| 513 int fieldDataType = fieldType & |
| 514 ~(_REQUIRED_BIT | _REPEATED_BIT | _PACKED_BIT); |
| 515 switch (fieldDataType) { |
| 516 case _BOOL_BIT: |
| 517 case _ENUM_BIT: |
| 518 case _INT32_BIT: |
| 519 case _INT64_BIT: |
| 520 case _SINT32_BIT: |
| 521 case _SINT64_BIT: |
| 522 case _UINT32_BIT: |
| 523 case _UINT64_BIT: |
| 524 return wireType == WireFormat.WIRETYPE_VARINT || |
| 525 wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED; |
| 526 case _FLOAT_BIT: |
| 527 case _FIXED32_BIT: |
| 528 case _SFIXED32_BIT: |
| 529 return wireType == WireFormat.WIRETYPE_FIXED32 || |
| 530 wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED; |
| 531 case _DOUBLE_BIT: |
| 532 case _FIXED64_BIT: |
| 533 case _SFIXED64_BIT: |
| 534 return wireType == WireFormat.WIRETYPE_FIXED64 || |
| 535 wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED; |
| 536 case _BYTES_BIT: |
| 537 case _STRING_BIT: |
| 538 case _MESSAGE_BIT: |
| 539 return wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED; |
| 540 case _GROUP_BIT: |
| 541 return wireType == WireFormat.WIRETYPE_START_GROUP; |
| 542 default: |
| 543 return false; |
| 544 } |
| 545 } |
| 546 |
| 547 while (true) { |
| 548 int tag = input.readTag(); |
| 549 if (tag == 0) { |
| 550 unknownFields = unknownFieldSetBuilder.build(); |
| 551 onChanged(); |
| 552 return this; |
| 553 } |
| 554 int wireType = tag & 0x7; |
| 555 int tagNumber = tag >> 3; |
| 556 int fieldType = -1; |
| 557 |
| 558 if (info_ != null) { |
| 559 if (info_.containsTagNumber(tagNumber)) { |
| 560 fieldType = info_.fieldType(tagNumber); |
| 561 } else { |
| 562 Extension extension = extensionRegistry |
| 563 .getExtension(info_.messageName, tagNumber); |
| 564 if (extension != null) { |
| 565 _addExtensionToMap(extension); |
| 566 fieldType = extension.type; |
| 567 } |
| 568 } |
| 569 } |
| 570 if (fieldType == -1 || !wireTypeMatch(tagNumber, fieldType, wireType)) { |
| 571 if (!parseUnknownFieldFromBuffer(input, unknownFieldSetBuilder, tag)) { |
| 572 unknownFields = unknownFieldSetBuilder.build(); |
| 573 onChanged(); |
| 574 return this; |
| 575 } else { |
| 576 continue; |
| 577 } |
| 578 } |
| 579 |
| 580 // ignore required/optional packed/unpacked |
| 581 fieldType &= ~(_PACKED_BIT | _REQUIRED_BIT); |
| 582 switch (fieldType) { |
| 583 case _OPTIONAL_BOOL: |
| 584 _fieldValues[tagNumber] = input.readBool(); |
| 585 break; |
| 586 case _OPTIONAL_BYTES: |
| 587 _fieldValues[tagNumber] = input.readBytes(); |
| 588 break; |
| 589 case _OPTIONAL_STRING: |
| 590 _fieldValues[tagNumber] = input.readString(); |
| 591 break; |
| 592 case _OPTIONAL_FLOAT: |
| 593 _fieldValues[tagNumber] = input.readFloat(); |
| 594 break; |
| 595 case _OPTIONAL_DOUBLE: |
| 596 _fieldValues[tagNumber] = input.readDouble(); |
| 597 break; |
| 598 case _OPTIONAL_ENUM: |
| 599 int rawValue = input.readEnum(); |
| 600 var value = _getValueOfFunc(tagNumber, extensionRegistry)(rawValue); |
| 601 if (value == null) { |
| 602 unknownFieldSetBuilder.mergeVarintField(tagNumber, rawValue); |
| 603 } else { |
| 604 _fieldValues[tagNumber] = value; |
| 605 } |
| 606 break; |
| 607 case _OPTIONAL_GROUP: |
| 608 Builder subBuilder = _getSubBuilder(tagNumber, extensionRegistry); |
| 609 if (_fieldValues.containsKey(tagNumber)) { |
| 610 subBuilder.mergeFromMessage(getField(tagNumber)); |
| 611 } |
| 612 input.readGroup(tagNumber, subBuilder, extensionRegistry); |
| 613 _fieldValues[tagNumber] = subBuilder.buildPartial(); |
| 614 break; |
| 615 case _OPTIONAL_INT32: |
| 616 _fieldValues[tagNumber] = input.readInt32(); |
| 617 break; |
| 618 case _OPTIONAL_INT64: |
| 619 _fieldValues[tagNumber] = input.readInt64(); |
| 620 break; |
| 621 case _OPTIONAL_SINT32: |
| 622 _fieldValues[tagNumber] = input.readSint32(); |
| 623 break; |
| 624 case _OPTIONAL_SINT64: |
| 625 _fieldValues[tagNumber] = input.readSint64(); |
| 626 break; |
| 627 case _OPTIONAL_UINT32: |
| 628 _fieldValues[tagNumber] = input.readUint32(); |
| 629 break; |
| 630 case _OPTIONAL_UINT64: |
| 631 _fieldValues[tagNumber] = input.readUint64(); |
| 632 break; |
| 633 case _OPTIONAL_FIXED32: |
| 634 _fieldValues[tagNumber] = input.readFixed32(); |
| 635 break; |
| 636 case _OPTIONAL_FIXED64: |
| 637 _fieldValues[tagNumber] = input.readFixed64(); |
| 638 break; |
| 639 case _OPTIONAL_SFIXED32: |
| 640 _fieldValues[tagNumber] = input.readSfixed32(); |
| 641 break; |
| 642 case _OPTIONAL_SFIXED64: |
| 643 _fieldValues[tagNumber] = input.readSfixed64(); |
| 644 break; |
| 645 case _OPTIONAL_MESSAGE: |
| 646 Builder subBuilder = _getSubBuilder(tagNumber, extensionRegistry); |
| 647 if (_fieldValues.containsKey(tagNumber)) { |
| 648 subBuilder.mergeFromMessage(getField(tagNumber)); |
| 649 } |
| 650 input.readMessage(subBuilder, extensionRegistry); |
| 651 _fieldValues[tagNumber] = subBuilder.buildPartial(); |
| 652 break; |
| 653 case _REPEATED_BOOL: |
| 654 readPackable(wireType, tagNumber, input.readBool); |
| 655 break; |
| 656 case _REPEATED_BYTES: |
| 657 List list = getField(tagNumber); |
| 658 list.add(input.readBytes()); |
| 659 break; |
| 660 case _REPEATED_STRING: |
| 661 List list = getField(tagNumber); |
| 662 list.add(input.readString()); |
| 663 break; |
| 664 case _REPEATED_FLOAT: |
| 665 readPackable(wireType, tagNumber, input.readFloat); |
| 666 break; |
| 667 case _REPEATED_DOUBLE: |
| 668 readPackable(wireType, tagNumber, input.readDouble); |
| 669 break; |
| 670 case _REPEATED_ENUM: |
| 671 readPackableIoc(wireType, tagNumber, (var assigner){ |
| 672 int rawValue = input.readEnum(); |
| 673 var value = _getValueOfFunc(tagNumber, extensionRegistry)(rawValue); |
| 674 if (value == null) { |
| 675 unknownFieldSetBuilder.mergeVarintField(tagNumber, rawValue); |
| 676 } else { |
| 677 assigner(value); |
| 678 } |
| 679 }); |
| 680 break; |
| 681 case _REPEATED_GROUP: |
| 682 Builder subBuilder = _getSubBuilder(tagNumber, extensionRegistry); |
| 683 input.readGroup(tagNumber, subBuilder, extensionRegistry); |
| 684 List list = getField(tagNumber); |
| 685 list.add(subBuilder.buildPartial()); |
| 686 break; |
| 687 case _REPEATED_INT32: |
| 688 readPackable(wireType, tagNumber, input.readInt32); |
| 689 break; |
| 690 case _REPEATED_INT64: |
| 691 readPackable(wireType, tagNumber, input.readInt64); |
| 692 break; |
| 693 case _REPEATED_SINT32: |
| 694 readPackable(wireType, tagNumber, input.readSint32); |
| 695 break; |
| 696 case _REPEATED_SINT64: |
| 697 readPackable(wireType, tagNumber, input.readSint64); |
| 698 break; |
| 699 case _REPEATED_UINT32: |
| 700 readPackable(wireType, tagNumber, input.readUint32); |
| 701 break; |
| 702 case _REPEATED_UINT64: |
| 703 readPackable(wireType, tagNumber, input.readUint64); |
| 704 break; |
| 705 case _REPEATED_FIXED32: |
| 706 readPackable(wireType, tagNumber, input.readFixed32); |
| 707 break; |
| 708 case _REPEATED_FIXED64: |
| 709 readPackable(wireType, tagNumber, input.readFixed64); |
| 710 break; |
| 711 case _REPEATED_SFIXED32: |
| 712 readPackable(wireType, tagNumber, input.readSfixed32); |
| 713 break; |
| 714 case _REPEATED_SFIXED64: |
| 715 readPackable(wireType, tagNumber, input.readSfixed64); |
| 716 break; |
| 717 case _REPEATED_MESSAGE: |
| 718 Builder subBuilder = _getSubBuilder(tagNumber, extensionRegistry); |
| 719 input.readMessage(subBuilder, extensionRegistry); |
| 720 List list = getField(tagNumber); |
| 721 list.add(subBuilder.buildPartial()); |
| 722 break; |
| 723 default: |
| 724 throw "Unknown field type $fieldType"; |
| 725 } |
| 726 } |
| 727 } |
| 728 |
| 729 /** |
| 730 * Merge field values from a JSON object, encoded as described by |
| 731 * [GeneratedMessage.writeToJson]. |
| 732 */ |
| 733 Builder mergeFromJson(String json, [ExtensionRegistry extensionRegistry]) { |
| 734 extensionRegistry = extensionRegistry == null ? |
| 735 ExtensionRegistry.EMPTY_REGISTRY : extensionRegistry; |
| 736 Map<String, Object> parsed = JSON.parse(json); |
| 737 _mergeFromJson(parsed, extensionRegistry); |
| 738 return this; |
| 739 } |
| 740 |
| 741 Builder mergeFromMessage(GeneratedMessage other) { |
| 742 for (int tagNumber in other._fieldValues.getKeys()) { |
| 743 var fieldValue = other._fieldValues[tagNumber]; |
| 744 |
| 745 int fieldType = other._builderInfo.fieldType(tagNumber); |
| 746 if (fieldType != null) { |
| 747 if ((fieldType & _REPEATED_BIT) != 0) { |
| 748 List otherList = fieldValue; |
| 749 if (!otherList.isEmpty()) { |
| 750 List thisList = getField(tagNumber); |
| 751 thisList.addAll(otherList); |
| 752 onChanged(); |
| 753 } |
| 754 } else { |
| 755 setField(tagNumber, fieldValue); |
| 756 } |
| 757 } else { |
| 758 Extension extension = other._extensions[tagNumber]; |
| 759 _addExtensionToMap(extension); |
| 760 fieldType = extension.type; |
| 761 if ((fieldType & _REPEATED_BIT) != 0) { |
| 762 List otherList = fieldValue; |
| 763 if (!otherList.isEmpty()) { |
| 764 List thisList = extension.makeDefault(); |
| 765 thisList.addAll(otherList); |
| 766 _fieldValues[tagNumber] = thisList; |
| 767 onChanged(); |
| 768 } |
| 769 } else { |
| 770 setField(tagNumber, fieldValue, fieldType); |
| 771 } |
| 772 } |
| 773 } |
| 774 |
| 775 mergeUnknownFields(other.unknownFields); |
| 776 return this; |
| 777 } |
| 778 |
| 779 Future<Builder> mergeFromCodedStreamReader(CodedStreamReader input, |
| 780 [ExtensionRegistry extensionRegistry]) { |
| 781 UnknownFieldSet_Builder unknownFieldSetBuilder = |
| 782 new UnknownFieldSet_Builder(unknownFields); |
| 783 extensionRegistry = extensionRegistry == null ? |
| 784 ExtensionRegistry.EMPTY_REGISTRY : extensionRegistry; |
| 785 Completer<Builder> c = new Completer<Builder>(); |
| 786 |
| 787 Function merge; |
| 788 |
| 789 Function appendAndMerge(int tagNumber) { |
| 790 return Future _(Dynamic value) { |
| 791 List list = getField(tagNumber); |
| 792 list.add(value); |
| 793 return merge(); |
| 794 }; |
| 795 } |
| 796 |
| 797 Function assignAndMerge(int tagNumber) { |
| 798 return Future _(Dynamic value) { |
| 799 _fieldValues[tagNumber] = value; |
| 800 return merge(); |
| 801 }; |
| 802 } |
| 803 |
| 804 // readPackableIoc inverts control in that it takes in a read function |
| 805 // that itself takes a function parameter. This function actually sets the |
| 806 // value in the current message. This is important because the setter method |
| 807 // may need to be substituted in the case that an enum is unresolved. |
| 808 Future readPackableIoc(int wireType, int tagNumber, var iocReadFunc) { |
| 809 List list = getField(tagNumber); |
| 810 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { |
| 811 // Packed |
| 812 return input.readInt32().chain((int length) { |
| 813 int limit = input._pushLimit(length); |
| 814 Future readUntilLimit() { |
| 815 if (input.getBytesUntilLimit() > 0) { |
| 816 return iocReadFunc((var v) => list.add(v)) |
| 817 .chain(() => readUntilLimit()); |
| 818 } else { |
| 819 input._popLimit(limit); |
| 820 return merge(); |
| 821 } |
| 822 } |
| 823 }); |
| 824 } else { |
| 825 // Not-packed |
| 826 return iocReadFunc((var v) => list.add(v)).chain((_) => merge()); |
| 827 } |
| 828 } |
| 829 |
| 830 Future readPackable(int wireType, int tagNumber, var readFunc) => |
| 831 readPackableIoc(wireType, tagNumber, _(var assigner) => |
| 832 readFunc().transform((v) => assigner(v)) |
| 833 ); |
| 834 |
| 835 bool wireTypeMatch(int tagNumber, int fieldType, int wireType) { |
| 836 int fieldDataType = fieldType & |
| 837 ~(Builder._REQUIRED_BIT | Builder._REPEATED_BIT | |
| 838 Builder._PACKED_BIT); |
| 839 switch (fieldDataType) { |
| 840 case Builder._BOOL_BIT: |
| 841 case Builder._ENUM_BIT: |
| 842 case Builder._INT32_BIT: |
| 843 case Builder._INT64_BIT: |
| 844 case Builder._SINT32_BIT: |
| 845 case Builder._SINT64_BIT: |
| 846 case Builder._UINT32_BIT: |
| 847 case Builder._UINT64_BIT: |
| 848 return wireType == WireFormat.WIRETYPE_VARINT || |
| 849 wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED; |
| 850 case Builder._FLOAT_BIT: |
| 851 case Builder._FIXED32_BIT: |
| 852 case Builder._SFIXED32_BIT: |
| 853 return wireType == WireFormat.WIRETYPE_FIXED32 || |
| 854 wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED; |
| 855 case Builder._DOUBLE_BIT: |
| 856 case Builder._FIXED64_BIT: |
| 857 case Builder._SFIXED64_BIT: |
| 858 return wireType == WireFormat.WIRETYPE_FIXED64 || |
| 859 wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED; |
| 860 case Builder._BYTES_BIT: |
| 861 case Builder._STRING_BIT: |
| 862 case Builder._MESSAGE_BIT: |
| 863 return wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED; |
| 864 case Builder._GROUP_BIT: |
| 865 return wireType == WireFormat.WIRETYPE_START_GROUP; |
| 866 default: |
| 867 return false; |
| 868 } |
| 869 } |
| 870 |
| 871 Future readField(int tagNumber, int wireType, int fieldType) { |
| 872 // ignore required/optional packed/unpacked |
| 873 fieldType &= ~(Builder._PACKED_BIT | Builder._REQUIRED_BIT); |
| 874 switch (fieldType) { |
| 875 case Builder._OPTIONAL_BOOL: |
| 876 return input.readBool().chain(assignAndMerge(tagNumber)); |
| 877 case Builder._OPTIONAL_BYTES: |
| 878 return input.readBytes().chain(assignAndMerge(tagNumber)); |
| 879 case Builder._OPTIONAL_STRING: |
| 880 return input.readString().chain(assignAndMerge(tagNumber)); |
| 881 case Builder._OPTIONAL_FLOAT: |
| 882 return input.readFloat().chain(assignAndMerge(tagNumber)); |
| 883 case Builder._OPTIONAL_DOUBLE: |
| 884 return input.readDouble().chain(assignAndMerge(tagNumber)); |
| 885 case Builder._OPTIONAL_ENUM: |
| 886 return input.readEnum().chain((int rawValue) { |
| 887 var value = _getValueOfFunc(tagNumber, extensionRegistry)(rawValue); |
| 888 if (value == null) { |
| 889 unknownFieldSetBuilder.mergeVarintField(tagNumber, rawValue); |
| 890 } else { |
| 891 _fieldValues[tagNumber] = value; |
| 892 } |
| 893 return merge(); |
| 894 }); |
| 895 case Builder._OPTIONAL_GROUP: |
| 896 Builder subBuilder = info_.subBuilder(tagNumber)(); |
| 897 if (_fieldValues.containsKey(tagNumber)) { |
| 898 subBuilder.mergeFromMessage(getField(tagNumber)); |
| 899 } |
| 900 return input.readGroup(tagNumber, subBuilder, extensionRegistry) |
| 901 .chain((_) { |
| 902 _fieldValues[tagNumber] = subBuilder.buildPartial(); |
| 903 return merge(); |
| 904 }); |
| 905 case Builder._OPTIONAL_INT32: |
| 906 return input.readInt32().chain(assignAndMerge(tagNumber)); |
| 907 case Builder._OPTIONAL_INT64: |
| 908 return input.readInt64().chain(assignAndMerge(tagNumber)); |
| 909 case Builder._OPTIONAL_SINT32: |
| 910 return input.readSint32().chain(assignAndMerge(tagNumber)); |
| 911 case Builder._OPTIONAL_SINT64: |
| 912 return input.readSint64().chain(assignAndMerge(tagNumber)); |
| 913 case Builder._OPTIONAL_UINT32: |
| 914 return input.readUint32().chain(assignAndMerge(tagNumber)); |
| 915 case Builder._OPTIONAL_UINT64: |
| 916 return input.readUint64().chain(assignAndMerge(tagNumber)); |
| 917 case Builder._OPTIONAL_FIXED32: |
| 918 return input.readFixed32().chain(assignAndMerge(tagNumber)); |
| 919 case Builder._OPTIONAL_FIXED64: |
| 920 return input.readFixed64().chain(assignAndMerge(tagNumber)); |
| 921 case Builder._OPTIONAL_SFIXED32: |
| 922 return input.readSfixed32().chain(assignAndMerge(tagNumber)); |
| 923 case Builder._OPTIONAL_SFIXED64: |
| 924 return input.readSfixed64().chain(assignAndMerge(tagNumber)); |
| 925 case Builder._OPTIONAL_MESSAGE: |
| 926 Builder subBuilder = info_.subBuilder(tagNumber)(); |
| 927 if (_fieldValues.containsKey(tagNumber)) { |
| 928 subBuilder.mergeFromMessage(getField(tagNumber)); |
| 929 } |
| 930 return input.readMessage(subBuilder, extensionRegistry).chain((_) { |
| 931 _fieldValues[tagNumber] = subBuilder.buildPartial(); |
| 932 return merge(); |
| 933 }); |
| 934 case Builder._REPEATED_BOOL: |
| 935 return readPackable(wireType, tagNumber, input.readBool); |
| 936 case Builder._REPEATED_BYTES: |
| 937 return input.readBytes().chain(appendAndMerge(tagNumber)); |
| 938 case Builder._REPEATED_STRING: |
| 939 return input.readString().chain(appendAndMerge(tagNumber)); |
| 940 case Builder._REPEATED_FLOAT: |
| 941 return readPackable(wireType, tagNumber, input.readFloat); |
| 942 case Builder._REPEATED_DOUBLE: |
| 943 return readPackable(wireType, tagNumber, input.readDouble); |
| 944 case Builder._REPEATED_ENUM: |
| 945 return readPackableIoc(wireType, tagNumber, (var assigner) => |
| 946 input.readEnum().transform((int rawValue) { |
| 947 var value = |
| 948 _getValueOfFunc(tagNumber, extensionRegistry)(rawValue); |
| 949 if (value == null) { |
| 950 unknownFieldSetBuilder.mergeVarintField(tagNumber, rawValue); |
| 951 } else { |
| 952 assigner(value); |
| 953 } |
| 954 return null; |
| 955 }) |
| 956 ); |
| 957 case Builder._REPEATED_GROUP: |
| 958 Builder subBuilder = info_.subBuilder(tagNumber)(); |
| 959 return input.readGroup(tagNumber, subBuilder, extensionRegistry) |
| 960 .chain((_) { |
| 961 List list = getField(tagNumber); |
| 962 list.add(subBuilder.buildPartial()); |
| 963 return merge(); |
| 964 }); |
| 965 case Builder._REPEATED_INT32: |
| 966 return readPackable(wireType, tagNumber, input.readInt32); |
| 967 case Builder._REPEATED_INT64: |
| 968 return readPackable(wireType, tagNumber, input.readInt64); |
| 969 case Builder._REPEATED_SINT32: |
| 970 return readPackable(wireType, tagNumber, input.readSint32); |
| 971 case Builder._REPEATED_SINT64: |
| 972 return readPackable(wireType, tagNumber, input.readSint64); |
| 973 case Builder._REPEATED_UINT32: |
| 974 return readPackable(wireType, tagNumber, input.readUint32); |
| 975 case Builder._REPEATED_UINT64: |
| 976 return readPackable(wireType, tagNumber, input.readUint64); |
| 977 case Builder._REPEATED_FIXED32: |
| 978 return readPackable(wireType, tagNumber, input.readFixed32); |
| 979 case Builder._REPEATED_FIXED64: |
| 980 return readPackable(wireType, tagNumber, input.readFixed64); |
| 981 case Builder._REPEATED_SFIXED32: |
| 982 return readPackable(wireType, tagNumber, input.readSfixed32); |
| 983 case Builder._REPEATED_SFIXED64: |
| 984 return readPackable(wireType, tagNumber, input.readSfixed64); |
| 985 case Builder._REPEATED_MESSAGE: |
| 986 Builder subBuilder = info_.subBuilder(tagNumber)(); |
| 987 return input.readMessage(subBuilder, extensionRegistry).chain((_) { |
| 988 List list = getField(tagNumber); |
| 989 list.add(subBuilder.buildPartial()); |
| 990 return merge(); |
| 991 }); |
| 992 default: |
| 993 throw "Unknown field type $fieldType"; |
| 994 } |
| 995 }; |
| 996 |
| 997 Future mergeImpl() { |
| 998 return input.readTag().chain((int tag) { |
| 999 if (tag == 0) { |
| 1000 unknownFields = unknownFieldSetBuilder.build(); |
| 1001 onChanged(); |
| 1002 return new Future.immediate(null); |
| 1003 } |
| 1004 int wireType = tag & 0x7; |
| 1005 int tagNumber = tag >> 3; |
| 1006 int fieldType = -1; |
| 1007 |
| 1008 if (info_.containsTagNumber(tagNumber)) { |
| 1009 fieldType = info_.fieldType(tagNumber); |
| 1010 } else { |
| 1011 Extension extension = |
| 1012 extensionRegistry.getExtension(info_.messageName, tagNumber); |
| 1013 if (extension != null) { |
| 1014 _addExtensionToMap(extension); |
| 1015 fieldType = extension.type; |
| 1016 } |
| 1017 } |
| 1018 if (fieldType == -1 || !wireTypeMatch(tagNumber, fieldType, wireType)) { |
| 1019 return parseUnknownFieldFromStream(input, unknownFieldSetBuilder, |
| 1020 extensionRegistry, tag).chain(_(bool unknownTag) { |
| 1021 if (!unknownTag) { |
| 1022 unknownFields = unknownFieldSetBuilder.build(); |
| 1023 onChanged(); |
| 1024 return new Future.immediate(null); |
| 1025 } else { |
| 1026 return merge(); |
| 1027 } |
| 1028 }); |
| 1029 } |
| 1030 return readField(tagNumber, wireType, fieldType); |
| 1031 }); |
| 1032 }; |
| 1033 merge = mergeImpl; |
| 1034 return merge().transform((_) => this); |
| 1035 } |
| 1036 |
| 1037 Future<Builder> mergeFromStream(InputStream input, |
| 1038 [ExtensionRegistry extensionRegistry]) { |
| 1039 extensionRegistry = extensionRegistry == null ? |
| 1040 ExtensionRegistry.EMPTY_REGISTRY : extensionRegistry; |
| 1041 CodedStreamReader codedInput = new CodedStreamReader(input); |
| 1042 return mergeFromCodedStreamReader(codedInput, extensionRegistry) |
| 1043 .transform((_) { |
| 1044 codedInput.checkLastTagWas(0); |
| 1045 return this; |
| 1046 }); |
| 1047 } |
| 1048 |
| 1049 Builder mergeUnknownFields(UnknownFieldSet unknownFields) { |
| 1050 _unknownFields = |
| 1051 (new UnknownFieldSet_Builder(_unknownFields)) |
| 1052 .mergeFromUnknownFieldSet(unknownFields).build(); |
| 1053 onChanged(); |
| 1054 return this; |
| 1055 } |
| 1056 |
| 1057 void onBuilt() { |
| 1058 // if (builderParent !== null) { |
| 1059 // markClean(); |
| 1060 // } |
| 1061 } |
| 1062 |
| 1063 void onChanged() { |
| 1064 // if (_isClean && builderParent !== null) { |
| 1065 // builderParent.markDirty(); |
| 1066 // |
| 1067 // // Don't keep dispatching invalidations until build is called again. |
| 1068 // _isClean = false; |
| 1069 // } |
| 1070 } |
| 1071 |
| 1072 bool parseUnknownFieldFromBuffer(CodedBufferReader input, |
| 1073 UnknownFieldSet_Builder unknownFieldSetBuilder, int tag) { |
| 1074 // If returns false, the tag is an "end group" which is expected |
| 1075 // If returns true, the field is considered unknown. |
| 1076 bool val = unknownFieldSetBuilder.mergeFieldFromBuffer(tag, input); |
| 1077 return val; |
| 1078 } |
| 1079 |
| 1080 Future<bool> parseUnknownFieldFromStream(CodedStreamReader input, |
| 1081 UnknownFieldSet_Builder unknownFieldSetBuilder, |
| 1082 ExtensionRegistry extensionRegistry, int tag) { |
| 1083 // If returns false, the tag is an "end group" which is expected |
| 1084 // If returns true, the field is considered unknown. |
| 1085 return unknownFieldSetBuilder.mergeFieldFromStream(tag, input); |
| 1086 } |
| 1087 |
| 1088 Message partial(GeneratedMessage result) { |
| 1089 // Set empty repeating fields |
| 1090 info_.fieldInfo.forEach( |
| 1091 void _(int tagNumber, FieldInfo fieldInfo){ |
| 1092 int type = fieldInfo.type; |
| 1093 if ((type & _REPEATED_BIT) != 0 && !hasField(tagNumber)) { |
| 1094 result._fieldValues[tagNumber] = PbImmutableList.EMPTY; |
| 1095 } |
| 1096 } |
| 1097 ); |
| 1098 |
| 1099 // Copy extensions |
| 1100 if (_extensions != null) { |
| 1101 for (int tagNumber in _extensions.getKeys()) { |
| 1102 if (result._extensions == null) { |
| 1103 result._extensions = new Map<int, Extension>(); |
| 1104 } |
| 1105 result._extensions[tagNumber] = _extensions[tagNumber]; |
| 1106 } |
| 1107 } |
| 1108 |
| 1109 // Then copy fields that have been set |
| 1110 for (int tagNumber in _fieldValues.getKeys()) { |
| 1111 if (hasField(tagNumber)) { |
| 1112 int type = _getFieldType(tagNumber); |
| 1113 result._fieldValues[tagNumber] = |
| 1114 _converterForType(type)(_fieldValues[tagNumber]); |
| 1115 } |
| 1116 } |
| 1117 |
| 1118 onBuilt(); |
| 1119 return result; |
| 1120 } |
| 1121 |
| 1122 // Shorthand for setField |
| 1123 void s_(int tagNumber, Object value) { |
| 1124 setField(tagNumber, value); |
| 1125 } |
| 1126 |
| 1127 /** |
| 1128 * Set the value of a non-repeated extension field. |
| 1129 */ |
| 1130 void setExtension(Extension extension, var value) { |
| 1131 _checkExtension(extension); |
| 1132 _addExtensionToMap(extension); |
| 1133 setField(extension.tagNumber, value, extension.type); |
| 1134 } |
| 1135 |
| 1136 /** |
| 1137 * Sets the value of a given field by its [tagNumber]. Can throw an |
| 1138 * [:IllegalArgumentException:] if the value does not match the type |
| 1139 * associated with [tagNumber]. |
| 1140 */ |
| 1141 void setField(int tagNumber, var value, [int fieldType = null]) { |
| 1142 if (value == null) { |
| 1143 throw new NullPointerException(); |
| 1144 } |
| 1145 if (fieldType == null) { |
| 1146 if (!info_.containsTagNumber(tagNumber)) { |
| 1147 throw new IllegalArgumentException("Unknown tag: $tagNumber"); |
| 1148 } |
| 1149 fieldType = info_.fieldType(tagNumber); |
| 1150 } |
| 1151 if ((fieldType & _REPEATED_BIT) != 0) { |
| 1152 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1153 "repeating field (use get + .add())")); |
| 1154 } |
| 1155 |
| 1156 // Validate type and range |
| 1157 value = _validate(tagNumber, fieldType & ~0x7, value); |
| 1158 _fieldValues[tagNumber] = value; |
| 1159 onChanged(); |
| 1160 } |
| 1161 |
| 1162 UnknownFieldSet get unknownFields() => _unknownFields; |
| 1163 |
| 1164 void set unknownFields(UnknownFieldSet unknownFields) { |
| 1165 _unknownFields = unknownFields; |
| 1166 onChanged(); |
| 1167 } |
| 1168 |
| 1169 void _addExtensionToMap(Extension extension) { |
| 1170 if (_extensions == null) { |
| 1171 _extensions = new Map<int, Extension>(); |
| 1172 } |
| 1173 _extensions[extension.tagNumber] = extension; |
| 1174 } |
| 1175 |
| 1176 void _checkExtension(Extension extension) { |
| 1177 if (extension.extendee != info_.messageName) { |
| 1178 throw new IllegalArgumentException( |
| 1179 "Extension $extension not legal for message ${info_.messageName}"); |
| 1180 } |
| 1181 } |
| 1182 |
| 1183 // dart2js's implementation of 'x is int' is not reliable |
| 1184 bool _isInt(var value) { |
| 1185 return (value is num) && (value == value.floor()); |
| 1186 } |
| 1187 |
| 1188 // Extract a value from its JSON representation |
| 1189 Dynamic _convertJsonValue(var value, int tagNumber, int fieldType, |
| 1190 ExtensionRegistry extensionRegistry) { |
| 1191 // Mask off 'required', 'repeated' and 'packed' bits to obtain base type |
| 1192 fieldType &= ~(_REQUIRED_BIT | _REPEATED_BIT | _PACKED_BIT); |
| 1193 |
| 1194 String expectedType; // for exception message |
| 1195 switch (fieldType) { |
| 1196 case _BOOL_BIT: |
| 1197 if (value is bool) { |
| 1198 return value; |
| 1199 } else if (value is String) { |
| 1200 if (value == "true") { |
| 1201 return true; |
| 1202 } else if (value == "false") { |
| 1203 return false; |
| 1204 } |
| 1205 } |
| 1206 expectedType = 'bool, "true", or "false"'; |
| 1207 break; |
| 1208 case _BYTES_BIT: |
| 1209 if (value is String) { |
| 1210 return Base64Codec.defaultInstance.decodeAsList(value); |
| 1211 } |
| 1212 expectedType = 'Base64 String'; |
| 1213 break; |
| 1214 case _STRING_BIT: |
| 1215 if (value is String) { |
| 1216 return value; |
| 1217 } |
| 1218 expectedType = "String"; |
| 1219 break; |
| 1220 case _FLOAT_BIT: |
| 1221 case _DOUBLE_BIT: |
| 1222 // Allow quoted values, although we don't emit them |
| 1223 if (value is double) { |
| 1224 return value; |
| 1225 } else if (value is num) { |
| 1226 return value.toDouble(); |
| 1227 } else if (value is String) { |
| 1228 return Math.parseDouble(value); |
| 1229 } |
| 1230 expectedType = "num or stringified num"; |
| 1231 break; |
| 1232 case _ENUM_BIT: |
| 1233 // Allow quoted values, although we don't emit them |
| 1234 if (value is String) { |
| 1235 value = Math.parseInt(value); |
| 1236 } |
| 1237 if (_isInt(value)) { |
| 1238 return _getValueOfFunc(tagNumber, extensionRegistry)(value.toInt()); |
| 1239 } |
| 1240 expectedType = "int or stringified int"; |
| 1241 break; |
| 1242 case _INT32_BIT: |
| 1243 case _SINT32_BIT: |
| 1244 case _UINT32_BIT: |
| 1245 case _FIXED32_BIT: |
| 1246 case _SFIXED32_BIT: |
| 1247 // Allow quoted values, although we don't emit them |
| 1248 if (_isInt(value)) { |
| 1249 return value.toInt(); |
| 1250 } else if (value is String) { |
| 1251 return Math.parseInt(value); |
| 1252 } |
| 1253 expectedType = "int or stringified int"; |
| 1254 break; |
| 1255 case _INT64_BIT: |
| 1256 case _SINT64_BIT: |
| 1257 case _UINT64_BIT: |
| 1258 case _FIXED64_BIT: |
| 1259 case _SFIXED64_BIT: |
| 1260 // Allow unquoted values, although we don't emit them |
| 1261 // TODO - decode large numbers as Packed64 on JavaScript platforms |
| 1262 if (value is String) { |
| 1263 return Math.parseInt(value); |
| 1264 } else if (_isInt(value)) { |
| 1265 return value.toInt(); |
| 1266 } |
| 1267 expectedType = "int or stringified int"; |
| 1268 break; |
| 1269 case _GROUP_BIT: |
| 1270 case _MESSAGE_BIT: |
| 1271 if (value is Map<String, Object>) { |
| 1272 Builder subBuilder = _getSubBuilder(tagNumber, extensionRegistry); |
| 1273 subBuilder._mergeFromJson(value, extensionRegistry); |
| 1274 return subBuilder.build(); |
| 1275 } |
| 1276 expectedType = "nested message or group"; |
| 1277 break; |
| 1278 default: |
| 1279 throw new PbException("Unknown type $fieldType"); |
| 1280 } |
| 1281 throw new PbException("Expected type $expectedType, got $value"); |
| 1282 } |
| 1283 |
| 1284 void _findInvalidFields(List<String> invalidFields) { |
| 1285 info_._findInvalidFields(_fieldValues, invalidFields); |
| 1286 invalidFields.sort((a, b) => a.compareTo(b)); |
| 1287 } |
| 1288 |
| 1289 /** |
| 1290 * Returns the type associated with a given tag number, either from the |
| 1291 * [BuilderInfo] associated with this [Builder], or from a known extension. |
| 1292 * If the type is unknown, [null] is returned. |
| 1293 */ |
| 1294 int _getFieldType(int tagNumber) { |
| 1295 int type = info_.fieldType(tagNumber); |
| 1296 if (type == null && _extensions != null && |
| 1297 _extensions.containsKey(tagNumber)) { |
| 1298 type = _extensions[tagNumber].type; |
| 1299 } |
| 1300 return type; |
| 1301 } |
| 1302 |
| 1303 Builder _getSubBuilder(int tagNumber, ExtensionRegistry extensionRegistry) { |
| 1304 CreateBuilderFunc subBuilderFunc = info_.subBuilder(tagNumber); |
| 1305 if (subBuilderFunc == null && extensionRegistry != null) { |
| 1306 subBuilderFunc = extensionRegistry.getExtension(info_.messageName, |
| 1307 tagNumber).subBuilder; |
| 1308 } |
| 1309 if (subBuilderFunc == null) { |
| 1310 throw new PbException("No subbuilder for tag $tagNumber"); |
| 1311 } |
| 1312 return subBuilderFunc(); |
| 1313 } |
| 1314 |
| 1315 ValueOfFunc _getValueOfFunc(int tagNumber, |
| 1316 ExtensionRegistry extensionRegistry) { |
| 1317 ValueOfFunc valueOfFunc = info_.valueOfFunc(tagNumber); |
| 1318 if (valueOfFunc == null && extensionRegistry != null) { |
| 1319 valueOfFunc = extensionRegistry.getExtension(info_.messageName, |
| 1320 tagNumber).valueOf; |
| 1321 } |
| 1322 if (valueOfFunc == null) { |
| 1323 throw new PbException("No valueOf for tag $tagNumber"); |
| 1324 } |
| 1325 return valueOfFunc; |
| 1326 } |
| 1327 |
| 1328 // Merge fields from a previously decoded JSON object |
| 1329 Builder _mergeFromJson(Map<String, Object> json, |
| 1330 ExtensionRegistry extensionRegistry) { |
| 1331 List<int> tags = new List<int>.from( |
| 1332 json.getKeys().map((x) => Math.parseInt(x))); |
| 1333 tags.sort((a, b) => a.compareTo(b)); |
| 1334 |
| 1335 for (int tagNumber in tags) { |
| 1336 var fieldValue = json[tagNumber.toString()]; |
| 1337 int fieldType = -1; |
| 1338 |
| 1339 Extension extension = null; |
| 1340 if (info_.containsTagNumber(tagNumber)) { |
| 1341 fieldType = info_.fieldType(tagNumber); |
| 1342 } else if (extensionRegistry != null) { |
| 1343 extension = extensionRegistry.getExtension(info_.messageName, |
| 1344 tagNumber); |
| 1345 if (extension == null) { |
| 1346 // Unknown extensions can be skipped. |
| 1347 continue; |
| 1348 } |
| 1349 _addExtensionToMap(extension); |
| 1350 fieldType = extension.type; |
| 1351 } |
| 1352 if (fieldType == -1) { |
| 1353 throw new PbException("Unknown field type for tag number $tagNumber"); |
| 1354 } |
| 1355 if ((fieldType & _REPEATED_BIT) != 0) { |
| 1356 List thisList = getField(tagNumber); |
| 1357 if (thisList == null) { |
| 1358 thisList = extension.makeDefault(); |
| 1359 } |
| 1360 for (var value in fieldValue) { |
| 1361 value = _convertJsonValue(value, tagNumber, fieldType, |
| 1362 extensionRegistry); |
| 1363 thisList.add(value); |
| 1364 } |
| 1365 _fieldValues[tagNumber] = thisList; |
| 1366 onChanged(); |
| 1367 } else { |
| 1368 var value = _convertJsonValue(fieldValue, tagNumber, fieldType, |
| 1369 extensionRegistry); |
| 1370 setField(tagNumber, value, fieldType); |
| 1371 } |
| 1372 } |
| 1373 } |
| 1374 |
| 1375 // does not perform validation |
| 1376 void _setExtension(Extension extension, var value) { |
| 1377 _addExtensionToMap(extension); |
| 1378 _fieldValues[extension.tagNumber] = value; |
| 1379 } |
| 1380 |
| 1381 String _generateMessage(int tagNumber, var value, String detail) { |
| 1382 String fieldName; |
| 1383 if (_extensions != null && _extensions[tagNumber] != null) { |
| 1384 fieldName = _extensions[tagNumber].name; |
| 1385 } else { |
| 1386 fieldName = info_.fieldName(tagNumber); |
| 1387 } |
| 1388 String messageType = info_.messageName; |
| 1389 return "Illegal to set field $fieldName ($tagNumber) of $messageType" |
| 1390 " to value ($value): $detail"; |
| 1391 } |
| 1392 |
| 1393 // For int values, force coercion to int since there isn't a reliable |
| 1394 // check for int-ness that works in both the VM and dart2js |
| 1395 Dynamic _validate(int tagNumber, int fieldType, var value) { |
| 1396 switch (fieldType) { |
| 1397 case _BOOL_BIT: |
| 1398 if (value is !bool) { |
| 1399 throw new IllegalArgumentException( |
| 1400 _generateMessage(tagNumber, value, "not type bool")); |
| 1401 } |
| 1402 break; |
| 1403 case _BYTES_BIT: |
| 1404 if (value is !List<int>) { |
| 1405 throw new IllegalArgumentException( |
| 1406 _generateMessage(tagNumber, value, "not List<int>")); |
| 1407 } |
| 1408 break; |
| 1409 case _STRING_BIT: |
| 1410 if (value is !String) { |
| 1411 throw new IllegalArgumentException( |
| 1412 _generateMessage(tagNumber, value, "not type String")); |
| 1413 } |
| 1414 break; |
| 1415 case _FLOAT_BIT: |
| 1416 if (value is !double) { |
| 1417 throw new IllegalArgumentException( |
| 1418 _generateMessage(tagNumber, value, "not type double")); |
| 1419 } |
| 1420 if (value < -_Constants.MAX_FLOAT || value > _Constants.MAX_FLOAT) { |
| 1421 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1422 "out of range for float")); |
| 1423 } |
| 1424 break; |
| 1425 case _DOUBLE_BIT: |
| 1426 if (value is !double) { |
| 1427 throw new IllegalArgumentException( |
| 1428 _generateMessage(tagNumber, value, "not type double")); |
| 1429 } |
| 1430 break; |
| 1431 case _ENUM_BIT: |
| 1432 if (value is !ProtobufEnum) { |
| 1433 throw new IllegalArgumentException( |
| 1434 _generateMessage(tagNumber, value, "not type ProtobufEnum")); |
| 1435 } |
| 1436 break; |
| 1437 case _INT32_BIT: |
| 1438 if (!_isInt(value)) { |
| 1439 throw new IllegalArgumentException( |
| 1440 _generateMessage(tagNumber, value, "not type int")); |
| 1441 } |
| 1442 if (value < _Constants.MIN_SINT32 || value > _Constants.MAX_SINT32) { |
| 1443 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1444 "out of range for int32")); |
| 1445 } |
| 1446 value = value.toInt(); |
| 1447 break; |
| 1448 case _INT64_BIT: |
| 1449 if (!_isInt(value) && value is !Packed64) { |
| 1450 throw new IllegalArgumentException( |
| 1451 _generateMessage(tagNumber, value, "not int or Packed64")); |
| 1452 } |
| 1453 if (_isInt(value) && |
| 1454 (value < _Constants.MIN_SINT64 || value > _Constants.MAX_SINT64)) { |
| 1455 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1456 "out of range for int64")); |
| 1457 } |
| 1458 if (value is !Packed64) { |
| 1459 value = value.toInt(); |
| 1460 } |
| 1461 break; |
| 1462 case _SINT32_BIT: |
| 1463 if (!_isInt(value)) { |
| 1464 throw new IllegalArgumentException( |
| 1465 _generateMessage(tagNumber, value, "not type int")); |
| 1466 } |
| 1467 if (value < _Constants.MIN_SINT32 || value > _Constants.MAX_SINT32) { |
| 1468 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1469 "out of range for sint32")); |
| 1470 } |
| 1471 value = value.toInt(); |
| 1472 break; |
| 1473 case _SINT64_BIT: |
| 1474 if (!_isInt(value) && value is !Packed64) { |
| 1475 throw new IllegalArgumentException( |
| 1476 _generateMessage(tagNumber, value, "not int or Packed64")); |
| 1477 } |
| 1478 if (_isInt(value) && |
| 1479 (value < _Constants.MIN_SINT64 || value > _Constants.MAX_SINT64)) { |
| 1480 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1481 "out of range for sint64")); |
| 1482 } |
| 1483 if (value is !Packed64) { |
| 1484 value = value.toInt(); |
| 1485 } |
| 1486 break; |
| 1487 case _UINT32_BIT: |
| 1488 if (!_isInt(value)) { |
| 1489 throw new IllegalArgumentException( |
| 1490 _generateMessage(tagNumber, value, "not type int")); |
| 1491 } |
| 1492 if (value < 0 || value > _Constants.MAX_UINT32) { |
| 1493 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1494 "out of range for uint32")); |
| 1495 } |
| 1496 value = value.toInt(); |
| 1497 break; |
| 1498 case _UINT64_BIT: |
| 1499 if (!_isInt(value) && value is !Packed64) { |
| 1500 throw new IllegalArgumentException( |
| 1501 _generateMessage(tagNumber, value, "not int or Packed64")); |
| 1502 } |
| 1503 if ((_isInt(value)) && (value < 0 || value > _Constants.MAX_UINT64)) { |
| 1504 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1505 "out of range for uint64")); |
| 1506 } |
| 1507 if (value is !Packed64) { |
| 1508 value = value.toInt(); |
| 1509 } |
| 1510 break; |
| 1511 case _FIXED32_BIT: |
| 1512 if (!_isInt(value)) { |
| 1513 throw new IllegalArgumentException( |
| 1514 _generateMessage(tagNumber, value, "not type int")); |
| 1515 } |
| 1516 if (value < 0 || value > _Constants.MAX_UINT32) { |
| 1517 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1518 "out of range for fixed32")); |
| 1519 } |
| 1520 break; |
| 1521 case _FIXED64_BIT: |
| 1522 if (!_isInt(value) && value is !Packed64) { |
| 1523 throw new IllegalArgumentException( |
| 1524 _generateMessage(tagNumber, value, "not int or Packed64")); |
| 1525 } |
| 1526 if ((_isInt(value)) && (value < 0 || value > _Constants.MAX_UINT64)) { |
| 1527 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1528 "out of range for fixed64")); |
| 1529 } |
| 1530 if (value is !Packed64) { |
| 1531 value = value.toInt(); |
| 1532 } |
| 1533 break; |
| 1534 case _SFIXED32_BIT: |
| 1535 if (!_isInt(value)) { |
| 1536 throw new IllegalArgumentException( |
| 1537 _generateMessage(tagNumber, value, "not type int")); |
| 1538 } |
| 1539 if (value < _Constants.MIN_SINT32 || value > _Constants.MAX_SINT32) { |
| 1540 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1541 "out of range for sfixed32")); |
| 1542 } |
| 1543 break; |
| 1544 case _SFIXED64_BIT: |
| 1545 if (!_isInt(value) && value is !Packed64) { |
| 1546 throw new IllegalArgumentException( |
| 1547 _generateMessage(tagNumber, value, "not int or Packed64")); |
| 1548 } |
| 1549 if ((_isInt(value)) && (value < _Constants.MIN_SINT64 || |
| 1550 value > _Constants.MAX_SINT64)) { |
| 1551 throw new IllegalArgumentException(_generateMessage(tagNumber, value, |
| 1552 "out of range for sfixed64")); |
| 1553 } |
| 1554 if (value is !Packed64) { |
| 1555 value = value.toInt(); |
| 1556 } |
| 1557 break; |
| 1558 case _GROUP_BIT: |
| 1559 case _MESSAGE_BIT: |
| 1560 if (value is !GeneratedMessage) { |
| 1561 throw new IllegalArgumentException( |
| 1562 _generateMessage(tagNumber, value, "not a GeneratedMessage")); |
| 1563 } |
| 1564 break; |
| 1565 default: |
| 1566 throw new IllegalArgumentException( |
| 1567 _generateMessage(tagNumber, value, "field has unknown type " |
| 1568 "$fieldType")); |
| 1569 } |
| 1570 return value; |
| 1571 } |
| 1572 } |
OLD | NEW |