Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(594)

Unified Diff: lib/protobuf/runtime/BuilderInfo.dart

Issue 10595002: Protocol Buffer runtime library and 'protoc' plugin (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Work around http://code.google.com/p/dart/issues/detail?id=3806 Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/protobuf/runtime/Builder.dart ('k') | lib/protobuf/runtime/ByteArrayProvider.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
+ }
+}
« no previous file with comments | « lib/protobuf/runtime/Builder.dart ('k') | lib/protobuf/runtime/ByteArrayProvider.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698