| Index: lib/protobuf/plugin/ProtobufField.dart
|
| diff --git a/lib/protobuf/plugin/ProtobufField.dart b/lib/protobuf/plugin/ProtobufField.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..73cec3958b402b7a763953c541565dd406d1c026
|
| --- /dev/null
|
| +++ b/lib/protobuf/plugin/ProtobufField.dart
|
| @@ -0,0 +1,446 @@
|
| +// 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.
|
| +
|
| +class ProtobufField {
|
| +
|
| + // Whitespace
|
| + static final String sp = MessageGenerator.sp;
|
| +
|
| + static final RegExp HEX_LITERAL_REGEX =
|
| + const RegExp(@"^0x[0-9a-f]+$", false, true);
|
| + static final RegExp INTEGER_LITERAL_REGEX = const RegExp(@"^[+-]?[0-9]+$");
|
| + static final RegExp DECIMAL_LITERAL_REGEX_A =
|
| + const RegExp(@"^[+-]?([0-9]*)\.[0-9]+(e[+-]?[0-9]+)?$", false, true);
|
| + static final RegExp DECIMAL_LITERAL_REGEX_B =
|
| + const RegExp(@"^[+-]?[0-9]+e[+-]?[0-9]+$", false, true);
|
| +
|
| + static int _maxIndex = 0;
|
| +
|
| + static void _resetIndices() {
|
| + _maxIndex = 0;
|
| + }
|
| +
|
| + static int _getIndex() {
|
| + _maxIndex++;
|
| + return _maxIndex;
|
| + }
|
| +
|
| + GoogleProtobuf_FieldDescriptorProto _field;
|
| + GenerationContext _context;
|
| +
|
| + int _index;
|
| + int get index() => _index;
|
| +
|
| + String _baseType;
|
| + String get baseType() => _baseType;
|
| +
|
| + String _typeString;
|
| + String get typeString() => _typeString;
|
| +
|
| + String _codedStreamType;
|
| + String get codedStreamType() => _codedStreamType;
|
| +
|
| + bool _repeats = false;
|
| + bool get repeats() => _repeats;
|
| + bool get single() => !repeats;
|
| +
|
| + bool get group() => type === GoogleProtobuf_FieldDescriptorProto_Type.TYPE_GROUP;
|
| + bool get message() => type === GoogleProtobuf_FieldDescriptorProto_Type.TYPE_MESSAGE;
|
| + bool get enum() => type === GoogleProtobuf_FieldDescriptorProto_Type.TYPE_ENUM;
|
| + bool get primitive() => !group && !message;
|
| +
|
| + // Initializer to be applied in the initialize() function
|
| + String _initialization = null;
|
| + String get initialization() => _initialization;
|
| + bool get hasInitialization() => _initialization !== null;
|
| +
|
| + bool _required = false;
|
| + bool get required() => _required;
|
| + bool get optional() => !required; // includes repeated
|
| +
|
| + // True if the field is to be encoded with [packed=true] encoding
|
| + bool _packed = false;
|
| + bool get packed() => _packed;
|
| +
|
| + // True if the fields's type can handle [packed=true] encoding
|
| + bool _packable = false;
|
| + bool get packable() => _packable;
|
| +
|
| + // delegate methods
|
| + String get name() => _field.name;
|
| + int get number() => _field.number;
|
| + GoogleProtobuf_FieldDescriptorProto_Label get label() => _field.label;
|
| + GoogleProtobuf_FieldDescriptorProto_Type get type() => _field.type;
|
| + GoogleProtobuf_FieldOptions get options() => _field.options;
|
| + String get typeName() => _field.typeName;
|
| +
|
| + String _shortName(String name) {
|
| + switch (name) {
|
| + case "OPTIONAL_BOOL": return "OB";
|
| + case "OPTIONAL_BYTES": return "OY";
|
| + case "OPTIONAL_STRING": return "OS";
|
| + case "OPTIONAL_FLOAT": return "OF";
|
| + case "OPTIONAL_DOUBLE": return "OD";
|
| + case "OPTIONAL_ENUM": return "OE";
|
| + case "OPTIONAL_GROUP": return "OG";
|
| + case "OPTIONAL_INT32": return "O3";
|
| + case "OPTIONAL_INT64": return "O6";
|
| + case "OPTIONAL_UINT32": return "OU3";
|
| + case "OPTIONAL_UINT64": return "OU6";
|
| + case "OPTIONAL_SINT32": return "OS3";
|
| + case "OPTIONAL_SINT64": return "OS6";
|
| + case "OPTIONAL_FIXED32": return "OF3";
|
| + case "OPTIONAL_FIXED64": return "OF6";
|
| + case "OPTIONAL_SFIXED32": return "OSF3";
|
| + case "OPTIONAL_SFIXED64": return "OSF6";
|
| + case "OPTIONAL_MESSAGE": return "OM";
|
| +
|
| + case "REQUIRED_BOOL": return "QB";
|
| + case "REQUIRED_BYTES": return "QY";
|
| + case "REQUIRED_STRING": return "QS";
|
| + case "REQUIRED_FLOAT": return "QF";
|
| + case "REQUIRED_DOUBLE": return "QD";
|
| + case "REQUIRED_ENUM": return "QE";
|
| + case "REQUIRED_GROUP": return "QG";
|
| + case "REQUIRED_INT32": return "Q3";
|
| + case "REQUIRED_INT64": return "Q6";
|
| + case "REQUIRED_UINT32": return "QU3";
|
| + case "REQUIRED_UINT64": return "QU6";
|
| + case "REQUIRED_SINT32": return "QS3";
|
| + case "REQUIRED_SINT64": return "QS6";
|
| + case "REQUIRED_FIXED32": return "QF3";
|
| + case "REQUIRED_FIXED64": return "QF6";
|
| + case "REQUIRED_SFIXED32": return "QSF3";
|
| + case "REQUIRED_SFIXED64": return "QSF6";
|
| + case "REQUIRED_MESSAGE": return "QM";
|
| +
|
| + case "REPEATED_BOOL": return "PB";
|
| + case "REPEATED_BYTES": return "PY";
|
| + case "REPEATED_STRING": return "PS";
|
| + case "REPEATED_FLOAT": return "PF";
|
| + case "REPEATED_DOUBLE": return "PD";
|
| + case "REPEATED_ENUM": return "PE";
|
| + case "REPEATED_GROUP": return "PG";
|
| + case "REPEATED_INT32": return "P3";
|
| + case "REPEATED_INT64": return "P6";
|
| + case "REPEATED_UINT32": return "PU3";
|
| + case "REPEATED_UINT64": return "PU6";
|
| + case "REPEATED_SINT32": return "PS3";
|
| + case "REPEATED_SINT64": return "PS6";
|
| + case "REPEATED_FIXED32": return "PF3";
|
| + case "REPEATED_FIXED64": return "PF6";
|
| + case "REPEATED_SFIXED32": return "PSF3";
|
| + case "REPEATED_SFIXED64": return "PSF6";
|
| + case "REPEATED_MESSAGE": return "PM";
|
| +
|
| + case "PACKED_INT32": return "K3";
|
| + case "PACKED_INT64": return "K6";
|
| +
|
| + case "PACKED_BOOL": return "KB";
|
| + case "PACKED_ENUM": return "KE";
|
| + case "PACKED_FLOAT": return "KF";
|
| + case "PACKED_DOUBLE": return "KD";
|
| + case "PACKED_INT32": return "K3";
|
| + case "PACKED_INT64": return "K6";
|
| + case "PACKED_SINT32": return "KS3";
|
| + case "PACKED_SINT64": return "KS6";
|
| + case "PACKED_UINT32": return "KU3";
|
| + case "PACKED_UINT64": return "KU6";
|
| + case "PACKED_FIXED32": return "KF3";
|
| + case "PACKED_FIXED64": return "KF6";
|
| + case "PACKED_SFIXED32": return "KSF3";
|
| + case "PACKED_SFIXED64": return "KSF6";
|
| + }
|
| + return name;
|
| + }
|
| +
|
| + String get shortTypeName() {
|
| + String type;
|
| + if (required) {
|
| + type = "REQUIRED_";
|
| + } else if (packed) {
|
| + type = "PACKED_";
|
| + } else if (repeats) {
|
| + type = "REPEATED_";
|
| + } else if (optional) {
|
| + type = "OPTIONAL_";
|
| + } else {
|
| + throw "$this";
|
| + }
|
| + type = "${type}${codedStreamType.toUpperCase()}";
|
| + return _shortName(type);
|
| + }
|
| +
|
| + ProtobufField(GoogleProtobuf_FieldDescriptorProto this._field, this._context) {
|
| + String _singleFieldType(String typeString) => typeString;
|
| + String _repeatingFieldType(String typeString) => "List<$typeString>";
|
| +
|
| + _required =
|
| + _field.label === GoogleProtobuf_FieldDescriptorProto_Label.LABEL_REQUIRED;
|
| + _repeats =
|
| + _field.label === GoogleProtobuf_FieldDescriptorProto_Label.LABEL_REPEATED;
|
| +
|
| + var write;
|
| + if (repeats) {
|
| + _packed = _field.options == null ? false : _field.options.packed;
|
| + _index = -1;
|
| + write = _repeatingFieldType;
|
| + } else {
|
| + _index = _getIndex();
|
| + write = _singleFieldType;
|
| + }
|
| +
|
| + switch (_field.type) {
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_BOOL:
|
| + _baseType = "bool";
|
| + _typeString = write("bool");
|
| + _packable = true;
|
| + _codedStreamType = "Bool";
|
| + if (!repeats) {
|
| + if (_field.hasDefaultValue() && "false" != _field.defaultValue) {
|
| + _initialization = "()${sp}=>${sp}${_field.defaultValue}";
|
| + }
|
| + }
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_FLOAT:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_DOUBLE:
|
| + _baseType = "double";
|
| + _typeString = write("double");
|
| + _packable = true;
|
| + _codedStreamType =
|
| + (_field.type == GoogleProtobuf_FieldDescriptorProto_Type.TYPE_FLOAT) ?
|
| + "Float" : "Double";
|
| + if (!repeats) {
|
| + if (_field.hasDefaultValue() &&
|
| + ("0.0" != _field.defaultValue || "0" != _field.defaultValue)) {
|
| + switch(true) {
|
| + case _field.defaultValue == "inf":
|
| + _initialization = "()${sp}=>${sp}double.INFINITY";
|
| + break;
|
| + case _field.defaultValue == "-inf":
|
| + _initialization = "()${sp}=>${sp}double.NEGATIVE_INFINITY";
|
| + break;
|
| + case _field.defaultValue == "nan":
|
| + _initialization = "()${sp}=>${sp}double.NAN";
|
| + break;
|
| + case HEX_LITERAL_REGEX.hasMatch(_field.defaultValue):
|
| + _initialization = "()${sp}=>${sp}(${_field.defaultValue})"
|
| + ".toDouble()";
|
| + break;
|
| + case INTEGER_LITERAL_REGEX.hasMatch(_field.defaultValue):
|
| + _initialization = "()${sp}=>${sp}${_field.defaultValue}.0";
|
| + break;
|
| + case DECIMAL_LITERAL_REGEX_A.hasMatch(_field.defaultValue):
|
| + case DECIMAL_LITERAL_REGEX_B.hasMatch(_field.defaultValue):
|
| + _initialization = "()${sp}=>${sp}${_field.defaultValue}";
|
| + break;
|
| + default:
|
| + throw InvalidDefaultValue.invalidDoubleValue(_field.name,
|
| + _field.defaultValue);
|
| + }
|
| + }
|
| + }
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_INT32:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_INT64:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_UINT32:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_UINT64:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SINT32:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SINT64:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_FIXED32:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_FIXED64:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SFIXED32:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SFIXED64:
|
| + _baseType = "int";
|
| + _typeString = write("int");
|
| + _packable = true;
|
| + switch (_field.type) {
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_INT32:
|
| + _codedStreamType = "Int32";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_INT64:
|
| + _codedStreamType = "Int64";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_UINT32:
|
| + _codedStreamType = "Uint32";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_UINT64:
|
| + _codedStreamType = "Uint64";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SINT32:
|
| + _codedStreamType = "Sint32";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SINT64:
|
| + _codedStreamType = "Sint64";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_FIXED32:
|
| + _codedStreamType = "Fixed32";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_FIXED64:
|
| + _codedStreamType = "Fixed64";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SFIXED32:
|
| + _codedStreamType = "Sfixed32";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SFIXED64:
|
| + _codedStreamType = "Sfixed64";
|
| + break;
|
| + }
|
| + if (!repeats) {
|
| + if (_field.hasDefaultValue() && "0" != _field.defaultValue) {
|
| + _initialization = "()${sp}=>${sp}${_field.defaultValue}";
|
| + }
|
| + }
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_STRING:
|
| + _baseType = "String";
|
| + _typeString = write("String");
|
| + _codedStreamType = "String";
|
| + if (!repeats) {
|
| + if (_field.hasDefaultValue() && !_field.defaultValue.isEmpty()) {
|
| + _initialization = "()${sp}=>${sp}'${_field.defaultValue}'";
|
| + }
|
| + }
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_BYTES:
|
| + _baseType = "List<int>";
|
| + _typeString = write("List<int>");
|
| + _codedStreamType = "Bytes";
|
| + if (!repeats) {
|
| + if (_field.hasDefaultValue() && !_field.defaultValue.isEmpty()) {
|
| + List<int> bytes = _field.defaultValue.charCodes();
|
| + bool firstTime = true;
|
| +
|
| + StringBuffer sb = new StringBuffer();
|
| + sb.add("<int>[");
|
| + for (int b in bytes) {
|
| + if (!firstTime) {
|
| + sb.add(",");
|
| + }
|
| + firstTime = false;
|
| + sb.add("0x${b.toRadixString(16)}");
|
| + }
|
| + sb.add("]");
|
| + _initialization = "()${sp}=>${sp}$sb";
|
| + }
|
| + }
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_GROUP:
|
| + ProtobufContainer groupType = _context[typeName];
|
| + if (groupType !== null) {
|
| + _baseType = groupType.classname;
|
| + _typeString = write(groupType.classname);
|
| + _codedStreamType = "Group";
|
| + } else {
|
| + throw "FAILURE: Unknown group type reference ${_field.typeName}";
|
| + }
|
| + _initialization = "()${sp}=>${sp}${baseType}.defaultInstance";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_MESSAGE:
|
| + ProtobufContainer messageType = _context[typeName];
|
| + if (messageType !== null) {
|
| + _baseType = messageType.classname;
|
| + _typeString = write(messageType.classname);
|
| + _codedStreamType = "Message";
|
| + } else {
|
| + throw "FAILURE: Unknown message type reference ${_field.typeName}";
|
| + }
|
| + _initialization = "()${sp}=>${sp}${baseType}.defaultInstance";
|
| + break;
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_ENUM:
|
| + EnumGenerator enumType = _context[typeName];
|
| + if (enumType !== null) {
|
| + _baseType = enumType.classname;
|
| + _typeString = write(enumType.classname);
|
| + _codedStreamType = "Enum";
|
| + _packable = true;
|
| + if (!repeats) {
|
| + if (_field.hasDefaultValue() && !_field.defaultValue.isEmpty()) {
|
| + _initialization =
|
| + "()${sp}=>${sp}${enumType.classname}.${_field.defaultValue}";
|
| + } else if (enumType._canonicalValues.length > 0) {
|
| + _initialization =
|
| + "()${sp}=>${sp}${enumType.classname}."
|
| + "${enumType._canonicalValues[0].name}";
|
| + }
|
| + }
|
| + } else {
|
| + throw "FAILURE: Unknown enum type reference ${_field.typeName}";
|
| + }
|
| + break;
|
| + default:
|
| + throw "Unknown type ${_field.type.name}";
|
| + // no default -- should be an error
|
| + }
|
| +
|
| + if (repeats) {
|
| + _initialization = "()${sp}=>${sp}new PbList(this)";
|
| + }
|
| + }
|
| +
|
| + // camelCase field name
|
| + String get externalFieldName() {
|
| + // For groups, use capitalization of 'typeName' rather than 'name'
|
| + if (codedStreamType == "Group") {
|
| + String name = _field.typeName;
|
| + int index = name.lastIndexOf(".");
|
| + if (index != -1) {
|
| + name = name.substring(index + 1);
|
| + }
|
| +
|
| + List<String> parts = name.split("_");
|
| + parts = parts.map((String x) => "${x[0].toUpperCase()}${x.substring(1)}");
|
| + name = Strings.join(parts, '');
|
| + if (name.length > 0) {
|
| + name = "${name[0].toLowerCase()}${name.substring(1)}";
|
| + }
|
| + return name;
|
| + }
|
| + return underscoresToCamelCase(_field.name);
|
| + }
|
| +
|
| + // underscore-prefixed camelCase field name
|
| + String get internalFieldName() => "_${externalFieldName}";
|
| +
|
| + // TitleCase field name
|
| + String get titlecaseFieldName() {
|
| + // For groups, use capitalization of 'typeName' rather than 'name'
|
| + if (codedStreamType == "Group") {
|
| + String name = externalFieldName;
|
| + if (name.length > 0) {
|
| + name = "${name[0].toUpperCase()}${name.substring(1)}";
|
| + }
|
| + return name;
|
| + }
|
| + return underscoresToCamelCase(_field.name, true);
|
| + }
|
| +
|
| + int get wireType() {
|
| + switch (_field.type) {
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_INT32:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_INT64:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_UINT32:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_UINT64:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SINT32:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SINT64:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_BOOL:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_ENUM:
|
| + return 0; // Varint
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_DOUBLE:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_FIXED64:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SFIXED64:
|
| + return 1; // 64-bit
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_STRING:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_BYTES:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_MESSAGE:
|
| + return 2; // Length-delimited
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_GROUP:
|
| + return 3; // Start group
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_FLOAT:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_FIXED32:
|
| + case GoogleProtobuf_FieldDescriptorProto_Type.TYPE_SFIXED32:
|
| + return 5; // 32-bit
|
| + }
|
| + }
|
| +}
|
|
|