| Index: lib/protobuf/runtime/BuilderInfo.dart
|
| diff --git a/lib/protobuf/runtime/BuilderInfo.dart b/lib/protobuf/runtime/BuilderInfo.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..434c52df4396ec3c6ffd40cb65cc2008e72a85aa
|
| --- /dev/null
|
| +++ b/lib/protobuf/runtime/BuilderInfo.dart
|
| @@ -0,0 +1,239 @@
|
| +// 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.
|
| +
|
| +/**
|
| + * Per-message type setup.
|
| + */
|
| +class BuilderInfo {
|
| + Builder _builder;
|
| + final String messageName;
|
| + final Map<int, FieldInfo> fieldInfo;
|
| + final Map<String, FieldInfo> byName;
|
| + bool hasExtensions = false;
|
| + bool hasRequiredFields = true;
|
| +
|
| + BuilderInfo(Builder this._builder, String this.messageName)
|
| + : fieldInfo = new Map<int, FieldInfo>(),
|
| + byName = new Map<String, FieldInfo>();
|
| +
|
| + void add(int tagNumber_, String name, int fieldType_,
|
| + [MakeDefaultFunc makeDefault_ = null,
|
| + CreateBuilderFunc subBuilder_ = null, ValueOfFunc valueOf = null]) {
|
| + FieldInfo i = new FieldInfo(name, tagNumber_, fieldType_, makeDefault_,
|
| + subBuilder_, valueOf);
|
| + fieldInfo[tagNumber_] = i;
|
| + byName[name] = i;
|
| + }
|
| +
|
| + void a(int tagNumber_, String name, int fieldType_,
|
| + [MakeDefaultFunc makeDefault_ = null,
|
| + CreateBuilderFunc subBuilder_ = null,
|
| + ValueOfFunc valueOf = null]) {
|
| + add(tagNumber_, name, fieldType_, makeDefault_, subBuilder_, valueOf);
|
| + }
|
| +
|
| + // Enum
|
| + void e(int tagNumber_, String name, int fieldType_,
|
| + MakeDefaultFunc makeDefault_, ValueOfFunc valueOf) {
|
| + add(tagNumber_, name, fieldType_, makeDefault_, null, valueOf);
|
| + }
|
| +
|
| + // Repeated message
|
| + void m(int tagNumber_, String name, CreateBuilderFunc subBuilder_,
|
| + [var newListFunc = null]) {
|
| + add(tagNumber_, name, Builder._REPEATED_MESSAGE,
|
| + newListFunc != null ? newListFunc : () =>
|
| + new PbList<GeneratedMessage>(_builder), subBuilder_, null);
|
| + }
|
| +
|
| + // Repeated non-message
|
| + void p(int tagNumber_, String name, int fieldType_) {
|
| + Function createFunc;
|
| + switch (fieldType_ & ~0x7) {
|
| + case Builder._BOOL_BIT:
|
| + createFunc = () => new PbList<bool>(_builder);
|
| + break;
|
| + case Builder._BYTES_BIT:
|
| + createFunc = () => new PbList<List<int>>(_builder);
|
| + break;
|
| + case Builder._STRING_BIT:
|
| + createFunc = () => new PbList<String>(_builder);
|
| + break;
|
| + case Builder._FLOAT_BIT:
|
| + createFunc = () => new PbFloatList(_builder);
|
| + break;
|
| + case Builder._DOUBLE_BIT:
|
| + createFunc = () => new PbList<double>(_builder);
|
| + break;
|
| + case Builder._ENUM_BIT:
|
| + createFunc = () => new PbList<ProtobufEnum>(_builder);
|
| + break;
|
| + case Builder._INT32_BIT:
|
| + case Builder._SINT32_BIT:
|
| + case Builder._SFIXED32_BIT:
|
| + createFunc = () => new PbSint32List(_builder);
|
| + break;
|
| + case Builder._UINT32_BIT:
|
| + case Builder._FIXED32_BIT:
|
| + createFunc = () => new PbUint32List(_builder);
|
| + break;
|
| + case Builder._INT64_BIT:
|
| + case Builder._SINT64_BIT:
|
| + case Builder._SFIXED64_BIT:
|
| + // Allow either int or Packed64 entries
|
| + createFunc = () => new PbSint64List(_builder);
|
| + break;
|
| + case Builder._UINT64_BIT:
|
| + case Builder._FIXED64_BIT:
|
| + // Allow either int or Packed64 entries
|
| + createFunc = () => new PbUint64List(_builder);
|
| + break;
|
| + case Builder._MESSAGE_BIT:
|
| + throw new IllegalArgumentException(
|
| + "use BuilderInfo.m() for repeated messages");
|
| + default:
|
| + throw new IllegalArgumentException("unknown type ${fieldType_}");
|
| + }
|
| +
|
| + add(tagNumber_, name, fieldType_, createFunc, null, null);
|
| + }
|
| +
|
| + bool containsTagNumber(int tagNumber_) => fieldInfo.containsKey(tagNumber_);
|
| +
|
| + Object defaultValue(int tagNumber_) {
|
| + MakeDefaultFunc func = makeDefault(tagNumber_);
|
| + return func === null ? null : func();
|
| + }
|
| +
|
| + // Returns the field name for a given tag number, for debugging purposes.
|
| + String fieldName(int tagNumber_) {
|
| + FieldInfo i = fieldInfo[tagNumber_];
|
| + return i != null ? i.name : null;
|
| + }
|
| +
|
| + int fieldType(int tagNumber_) {
|
| + FieldInfo i = fieldInfo[tagNumber_];
|
| + return i != null ? i.type : null;
|
| + }
|
| +
|
| + MakeDefaultFunc makeDefault(int tagNumber_) {
|
| + FieldInfo i = fieldInfo[tagNumber_];
|
| + return i != null ? i.makeDefault : null;
|
| + }
|
| +
|
| + bool isInitialized(Map<int, Object> fieldValues) {
|
| + return fieldInfo.getKeys().every(bool _(int tagNumber_) {
|
| + return _isFieldInitialized(fieldValues, tagNumber_);
|
| + });
|
| + }
|
| +
|
| + CreateBuilderFunc subBuilder(int tagNumber_) {
|
| + FieldInfo i = fieldInfo[tagNumber_];
|
| + return i != null ? i.subBuilder : null;
|
| + }
|
| +
|
| + int tagNumber(String fieldName_) {
|
| + FieldInfo i = byName[fieldName_];
|
| + return i != null ? i.tagNumber : null;
|
| + }
|
| +
|
| + ValueOfFunc valueOfFunc(int tagNumber_) {
|
| + FieldInfo i = fieldInfo[tagNumber_];
|
| + return i != null ? i.valueOf : null;
|
| + }
|
| +
|
| + bool _isFieldInitialized(Map<int, Object> fieldValues, int tagNumber_,
|
| + [int fieldType_ = null]) {
|
| + if (fieldType_ == null) {
|
| + fieldType_ = fieldInfo[tagNumber_].type;
|
| + }
|
| + if ((fieldType_ &
|
| + (Builder._MESSAGE_BIT | Builder._GROUP_BIT)) != 0) {
|
| + if ((fieldType_ & Builder._REQUIRED_BIT) != 0) {
|
| + Message message = fieldValues[tagNumber_];
|
| + // required message/group must be present and initialized
|
| + if (message === null || !message.isInitialized()) {
|
| + return false;
|
| + }
|
| + } else if ((fieldType_ & Builder._REPEATED_BIT) != 0) {
|
| + if (fieldValues.containsKey(tagNumber_)) {
|
| + // repeated message/group must have all its members initialized
|
| + List list = fieldValues[tagNumber_];
|
| + // For message types that (recursively) contain no required fields,
|
| + // short-circuit the loop
|
| + if (!list.isEmpty() && list[0].hasRequiredFields()) {
|
| + for (Message message in list) {
|
| + if (!message.isInitialized()) {
|
| + return false;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + } else {
|
| + Message message = fieldValues[tagNumber_];
|
| + // optional message/group must be initialized if it is present
|
| + if (message !== null && !message.isInitialized()) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + } else if ((fieldType_ & Builder._REQUIRED_BIT) != 0) {
|
| + // required 'primitive' must be present
|
| + if (fieldValues[tagNumber_] === null) {
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + List<String> _findInvalidFields(Map<int, Object> fieldValues,
|
| + List<String> invalidFields, [String prefix = ""]) {
|
| + fieldInfo.forEach(_(int tagNumber_, FieldInfo field) {
|
| + int fieldType_ = field.type;
|
| + if ((fieldType_ &
|
| + (Builder._MESSAGE_BIT | Builder._GROUP_BIT)) != 0) {
|
| + if ((fieldType_ & Builder._REQUIRED_BIT) != 0) {
|
| + Message message = fieldValues[tagNumber_];
|
| + // required message/group must be present
|
| + if (message === null) {
|
| + invalidFields.add("${prefix}${field.name}");
|
| + } else {
|
| + message._findInvalidFields(invalidFields,
|
| + "${prefix}${field.name}.");
|
| + }
|
| + } else if ((fieldType_ & Builder._REPEATED_BIT) != 0) {
|
| + if (fieldValues.containsKey(tagNumber_)) {
|
| + // repeated message/group must have all its members initialized
|
| + List list = fieldValues[tagNumber_];
|
| + // For messages that (recursively) contain no required fields,
|
| + // short-circuit the loop
|
| + if (!list.isEmpty() && list[0].hasRequiredFields()) {
|
| + int position = 0;
|
| + for (Message message in list) {
|
| + if (message.hasRequiredFields()) {
|
| + message._findInvalidFields(invalidFields,
|
| + "${prefix}${field.name}[${position}].");
|
| + }
|
| + position++;
|
| + }
|
| + }
|
| + }
|
| + } else {
|
| + Message message = fieldValues[tagNumber_];
|
| + // required message/group must be present
|
| + if (message !== null) {
|
| + message._findInvalidFields(invalidFields, "${prefix}${field.name}.");
|
| + }
|
| + }
|
| +
|
| + } else if((fieldType_ & Builder._REQUIRED_BIT) != 0) {
|
| + // required 'primitive' must be present
|
| + if (fieldValues[tagNumber_] === null) {
|
| + invalidFields.add("${prefix}${field.name}");
|
| + }
|
| + }
|
| + });
|
| + return invalidFields;
|
| + }
|
| +}
|
|
|