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

Side by Side Diff: lib/protobuf_field.dart

Issue 2043913005: Change how to set the Dart name of a field (Closed) Base URL: git@github.com:dart-lang/dart-protoc-plugin.git@master
Patch Set: better error checking, clean up pubspec Created 4 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of protoc; 5 part of protoc;
6 6
7 class ProtobufField { 7 class ProtobufField {
8 static final RegExp HEX_LITERAL_REGEX = 8 static final RegExp HEX_LITERAL_REGEX =
9 new RegExp(r'^0x[0-9a-f]+$', multiLine: false, caseSensitive: false); 9 new RegExp(r'^0x[0-9a-f]+$', multiLine: false, caseSensitive: false);
10 static final RegExp INTEGER_LITERAL_REGEX = new RegExp(r'^[+-]?[0-9]+$'); 10 static final RegExp INTEGER_LITERAL_REGEX = new RegExp(r'^[+-]?[0-9]+$');
11 static final RegExp DECIMAL_LITERAL_REGEX_A = new RegExp( 11 static final RegExp DECIMAL_LITERAL_REGEX_A = new RegExp(
12 r'^[+-]?([0-9]*)\.[0-9]+(e[+-]?[0-9]+)?$', 12 r'^[+-]?([0-9]*)\.[0-9]+(e[+-]?[0-9]+)?$',
13 multiLine: false, 13 multiLine: false,
14 caseSensitive: false); 14 caseSensitive: false);
15 static final RegExp DECIMAL_LITERAL_REGEX_B = new RegExp( 15 static final RegExp DECIMAL_LITERAL_REGEX_B = new RegExp(
16 r'^[+-]?[0-9]+e[+-]?[0-9]+$', 16 r'^[+-]?[0-9]+e[+-]?[0-9]+$',
17 multiLine: false, 17 multiLine: false,
18 caseSensitive: false); 18 caseSensitive: false);
19 19
20 final FieldDescriptorProto _field; 20 final FieldDescriptorProto descriptor;
21 21
22 /// The index of this field in MessageGenerator._fieldList. 22 /// Dart names within a GeneratedMessage or `null` for an extension.
23 /// The same index will be stored in FieldInfo.index. 23 final MemberNames memberNames;
24 /// For extension fields, this will be null.
25 final int index;
26 24
27 final String fqname; 25 final String fqname;
28 final BaseType baseType; 26 final BaseType baseType;
29 final GenerationOptions _genOptions;
30 27
31 ProtobufField(FieldDescriptorProto field, this.index, 28 ProtobufField.message(
29 MemberNames names, ProtobufContainer parent, GenerationContext ctx)
30 : this._(names.descriptor, names, parent, ctx);
31
32 ProtobufField.extension(FieldDescriptorProto descriptor,
32 ProtobufContainer parent, GenerationContext ctx) 33 ProtobufContainer parent, GenerationContext ctx)
33 : _field = field, 34 : this._(descriptor, null, parent, ctx);
34 fqname = '${parent.fqname}.${field.name}',
35 baseType = new BaseType(field, ctx),
36 _genOptions = ctx.options;
37 35
38 int get number => _field.number; 36 ProtobufField._(FieldDescriptorProto descriptor, MemberNames dartNames,
37 ProtobufContainer parent, GenerationContext ctx)
38 : this.descriptor = descriptor,
39 this.memberNames = dartNames,
40 fqname = '${parent.fqname}.${descriptor.name}',
41 baseType = new BaseType(descriptor, ctx);
42
43 /// The index of this field in MessageGenerator.fieldList.
44 ///
45 /// `null` for an extension.
46 int get index => memberNames?.index;
39 47
40 bool get isRequired => 48 bool get isRequired =>
41 _field.label == FieldDescriptorProto_Label.LABEL_REQUIRED; 49 descriptor.label == FieldDescriptorProto_Label.LABEL_REQUIRED;
42 50
43 bool get isRepeated => 51 bool get isRepeated =>
44 _field.label == FieldDescriptorProto_Label.LABEL_REPEATED; 52 descriptor.label == FieldDescriptorProto_Label.LABEL_REPEATED;
45 53
46 /// True if the field is to be encoded with [packed=true] encoding. 54 /// True if the field is to be encoded with [packed=true] encoding.
47 bool get isPacked => 55 bool get isPacked =>
48 isRepeated && _field.options != null && _field.options.packed; 56 isRepeated && descriptor.options != null && descriptor.options.packed;
49 57
50 /// True if this field uses the Int64 from the fixnum package. 58 /// True if this field uses the Int64 from the fixnum package.
51 bool get needsFixnumImport => baseType.unprefixed == "Int64"; 59 bool get needsFixnumImport => baseType.unprefixed == "Int64";
52 60
53 /// Returns the expression to use for the Dart type. 61 /// Returns the expression to use for the Dart type.
54 /// 62 ///
55 /// This will be a List for repeated types. 63 /// This will be a List for repeated types.
56 /// [package] is the package where we are generating code. 64 /// [package] is the package where we are generating code.
57 String getDartType(String package) { 65 String getDartType(String package) {
58 if (isRepeated) return baseType.getRepeatedDartType(package); 66 if (isRepeated) return baseType.getRepeatedDartType(package);
59 return baseType.getDartType(package); 67 return baseType.getDartType(package);
60 } 68 }
61 69
70 /// Returns the tag number of the underlying proto field.
71 int get number => descriptor.number;
72
62 /// Returns the constant in PbFieldType corresponding to this type. 73 /// Returns the constant in PbFieldType corresponding to this type.
63 String get typeConstant { 74 String get typeConstant {
64 String prefix = 'O'; 75 String prefix = 'O';
65 if (isRequired) { 76 if (isRequired) {
66 prefix = 'Q'; 77 prefix = 'Q';
67 } else if (isPacked) { 78 } else if (isPacked) {
68 prefix = 'K'; 79 prefix = 'K';
69 } else if (isRepeated) { 80 } else if (isRepeated) {
70 prefix = 'P'; 81 prefix = 'P';
71 } 82 }
72 return "PbFieldType." + prefix + baseType.typeConstantSuffix; 83 return "PbFieldType." + prefix + baseType.typeConstantSuffix;
73 } 84 }
74 85
75 /// The name to use by default for the Dart getter and setter.
76 /// (A suffix will be added if there is a conflict.)
77 String get dartFieldName {
78 String name = _fieldMethodSuffix;
79 return '${name[0].toLowerCase()}${name.substring(1)}';
80 }
81
82 String get hasMethodName => 'has$_fieldMethodSuffix';
83 String get clearMethodName => 'clear$_fieldMethodSuffix';
84
85 /// The suffix to use for this field in Dart method names.
86 /// (It should be camelcase and begin with an uppercase letter.)
87 String get _fieldMethodSuffix {
88 String underscoresToCamelCase(String s) {
89 cap(s) => s.isEmpty ? s : '${s[0].toUpperCase()}${s.substring(1)}';
90 return s.split('_').map(cap).join('');
91 }
92
93 // For groups, use capitalization of 'typeName' rather than 'name'.
94 if (baseType.isGroup) {
95 String name = _field.typeName;
96 int index = name.lastIndexOf('.');
97 if (index != -1) {
98 name = name.substring(index + 1);
99 }
100 return underscoresToCamelCase(name);
101 }
102 var name = _genOptions.fieldNameOverrides[fqname];
103 return name != null ? name : underscoresToCamelCase(_field.name);
104 }
105
106 /// Returns Dart code adding this field to a BuilderInfo object. 86 /// Returns Dart code adding this field to a BuilderInfo object.
107 /// The call will start with ".." and a method name. 87 /// The call will start with ".." and a method name.
108 /// [package] is the package where the code will be evaluated. 88 /// [package] is the package where the code will be evaluated.
109 String generateBuilderInfoCall(String package) { 89 String generateBuilderInfoCall(String package, String dartFieldName) {
110 String quotedName = "'$dartFieldName'"; 90 String quotedName = "'$dartFieldName'";
111 String type = baseType.getDartType(package); 91 String type = baseType.getDartType(package);
112 92
113 if (isRepeated) { 93 if (isRepeated) {
114 if (baseType.isMessage || baseType.isGroup) { 94 if (baseType.isMessage || baseType.isGroup) {
115 return '..pp/*<$type>*/($number, $quotedName, $typeConstant,' 95 return '..pp/*<$type>*/($number, $quotedName, $typeConstant,'
116 ' $type.$checkItem, $type.create)'; 96 ' $type.$checkItem, $type.create)';
117 } else if (baseType.isEnum) { 97 } else if (baseType.isEnum) {
118 return '..pp/*<$type>*/($number, $quotedName, $typeConstant,' 98 return '..pp/*<$type>*/($number, $quotedName, $typeConstant,'
119 ' $type.$checkItem, null, $type.valueOf)'; 99 ' $type.$checkItem, null, $type.valueOf)';
(...skipping 18 matching lines...) Expand all
138 118
139 return prefix + ', $makeDefault)'; 119 return prefix + ', $makeDefault)';
140 } 120 }
141 121
142 /// Returns a Dart expression that evaluates to this field's default value. 122 /// Returns a Dart expression that evaluates to this field's default value.
143 /// 123 ///
144 /// Returns "null" if unavailable, in which case FieldSet._getDefault() 124 /// Returns "null" if unavailable, in which case FieldSet._getDefault()
145 /// should be called instead. 125 /// should be called instead.
146 String getDefaultExpr() { 126 String getDefaultExpr() {
147 if (isRepeated) return "null"; 127 if (isRepeated) return "null";
148 switch (_field.type) { 128 switch (descriptor.type) {
149 case FieldDescriptorProto_Type.TYPE_BOOL: 129 case FieldDescriptorProto_Type.TYPE_BOOL:
150 return _getDefaultAsBoolExpr("false"); 130 return _getDefaultAsBoolExpr("false");
151 case FieldDescriptorProto_Type.TYPE_INT32: 131 case FieldDescriptorProto_Type.TYPE_INT32:
152 case FieldDescriptorProto_Type.TYPE_UINT32: 132 case FieldDescriptorProto_Type.TYPE_UINT32:
153 case FieldDescriptorProto_Type.TYPE_SINT32: 133 case FieldDescriptorProto_Type.TYPE_SINT32:
154 case FieldDescriptorProto_Type.TYPE_FIXED32: 134 case FieldDescriptorProto_Type.TYPE_FIXED32:
155 case FieldDescriptorProto_Type.TYPE_SFIXED32: 135 case FieldDescriptorProto_Type.TYPE_SFIXED32:
156 return _getDefaultAsInt32Expr("0"); 136 return _getDefaultAsInt32Expr("0");
157 case FieldDescriptorProto_Type.TYPE_STRING: 137 case FieldDescriptorProto_Type.TYPE_STRING:
158 return _getDefaultAsStringExpr("''"); 138 return _getDefaultAsStringExpr("''");
159 default: 139 default:
160 return "null"; 140 return "null";
161 } 141 }
162 } 142 }
163 143
164 /// Returns a function expression that returns the field's default value. 144 /// Returns a function expression that returns the field's default value.
165 /// 145 ///
166 /// [package] is the package where the expression will be evaluated. 146 /// [package] is the package where the expression will be evaluated.
167 /// Returns null if this field doesn't have an initializer. 147 /// Returns null if this field doesn't have an initializer.
168 String generateDefaultFunction(String package) { 148 String generateDefaultFunction(String package) {
169 if (isRepeated) { 149 if (isRepeated) {
170 return '() => new PbList()'; 150 return '() => new PbList()';
171 } 151 }
172 152
173 bool samePackage = package == baseType.package; 153 bool samePackage = package == baseType.package;
174 154
175 switch (_field.type) { 155 switch (descriptor.type) {
176 case FieldDescriptorProto_Type.TYPE_BOOL: 156 case FieldDescriptorProto_Type.TYPE_BOOL:
177 return _getDefaultAsBoolExpr(null); 157 return _getDefaultAsBoolExpr(null);
178 case FieldDescriptorProto_Type.TYPE_FLOAT: 158 case FieldDescriptorProto_Type.TYPE_FLOAT:
179 case FieldDescriptorProto_Type.TYPE_DOUBLE: 159 case FieldDescriptorProto_Type.TYPE_DOUBLE:
180 if (!_field.hasDefaultValue()) { 160 if (!descriptor.hasDefaultValue()) {
181 return null; 161 return null;
182 } else if ('0.0' == _field.defaultValue || '0' == _field.defaultValue) { 162 } else if ('0.0' == descriptor.defaultValue ||
163 '0' == descriptor.defaultValue) {
183 return null; 164 return null;
184 } else if (_field.defaultValue == 'inf') { 165 } else if (descriptor.defaultValue == 'inf') {
185 return 'double.INFINITY'; 166 return 'double.INFINITY';
186 } else if (_field.defaultValue == '-inf') { 167 } else if (descriptor.defaultValue == '-inf') {
187 return 'double.NEGATIVE_INFINITY'; 168 return 'double.NEGATIVE_INFINITY';
188 } else if (_field.defaultValue == 'nan') { 169 } else if (descriptor.defaultValue == 'nan') {
189 return 'double.NAN'; 170 return 'double.NAN';
190 } else if (HEX_LITERAL_REGEX.hasMatch(_field.defaultValue)) { 171 } else if (HEX_LITERAL_REGEX.hasMatch(descriptor.defaultValue)) {
191 return '(${_field.defaultValue}).toDouble()'; 172 return '(${descriptor.defaultValue}).toDouble()';
192 } else if (INTEGER_LITERAL_REGEX.hasMatch(_field.defaultValue)) { 173 } else if (INTEGER_LITERAL_REGEX.hasMatch(descriptor.defaultValue)) {
193 return '${_field.defaultValue}.0'; 174 return '${descriptor.defaultValue}.0';
194 } else if (DECIMAL_LITERAL_REGEX_A.hasMatch(_field.defaultValue) || 175 } else if (DECIMAL_LITERAL_REGEX_A.hasMatch(descriptor.defaultValue) ||
195 DECIMAL_LITERAL_REGEX_B.hasMatch(_field.defaultValue)) { 176 DECIMAL_LITERAL_REGEX_B.hasMatch(descriptor.defaultValue)) {
196 return '${_field.defaultValue}'; 177 return '${descriptor.defaultValue}';
197 } 178 }
198 throw _invalidDefaultValue; 179 throw _invalidDefaultValue;
199 case FieldDescriptorProto_Type.TYPE_INT32: 180 case FieldDescriptorProto_Type.TYPE_INT32:
200 case FieldDescriptorProto_Type.TYPE_UINT32: 181 case FieldDescriptorProto_Type.TYPE_UINT32:
201 case FieldDescriptorProto_Type.TYPE_SINT32: 182 case FieldDescriptorProto_Type.TYPE_SINT32:
202 case FieldDescriptorProto_Type.TYPE_FIXED32: 183 case FieldDescriptorProto_Type.TYPE_FIXED32:
203 case FieldDescriptorProto_Type.TYPE_SFIXED32: 184 case FieldDescriptorProto_Type.TYPE_SFIXED32:
204 return _getDefaultAsInt32Expr(null); 185 return _getDefaultAsInt32Expr(null);
205 case FieldDescriptorProto_Type.TYPE_INT64: 186 case FieldDescriptorProto_Type.TYPE_INT64:
206 case FieldDescriptorProto_Type.TYPE_UINT64: 187 case FieldDescriptorProto_Type.TYPE_UINT64:
207 case FieldDescriptorProto_Type.TYPE_SINT64: 188 case FieldDescriptorProto_Type.TYPE_SINT64:
208 case FieldDescriptorProto_Type.TYPE_FIXED64: 189 case FieldDescriptorProto_Type.TYPE_FIXED64:
209 case FieldDescriptorProto_Type.TYPE_SFIXED64: 190 case FieldDescriptorProto_Type.TYPE_SFIXED64:
210 var value = '0'; 191 var value = '0';
211 if (_field.hasDefaultValue()) value = _field.defaultValue; 192 if (descriptor.hasDefaultValue()) value = descriptor.defaultValue;
212 if (value == '0') return 'Int64.ZERO'; 193 if (value == '0') return 'Int64.ZERO';
213 return "parseLongInt('$value')"; 194 return "parseLongInt('$value')";
214 case FieldDescriptorProto_Type.TYPE_STRING: 195 case FieldDescriptorProto_Type.TYPE_STRING:
215 return _getDefaultAsStringExpr(null); 196 return _getDefaultAsStringExpr(null);
216 case FieldDescriptorProto_Type.TYPE_BYTES: 197 case FieldDescriptorProto_Type.TYPE_BYTES:
217 if (!_field.hasDefaultValue() || _field.defaultValue.isEmpty) { 198 if (!descriptor.hasDefaultValue() || descriptor.defaultValue.isEmpty) {
218 return null; 199 return null;
219 } 200 }
220 String byteList = _field.defaultValue.codeUnits 201 String byteList = descriptor.defaultValue.codeUnits
221 .map((b) => '0x${b.toRadixString(16)}') 202 .map((b) => '0x${b.toRadixString(16)}')
222 .join(','); 203 .join(',');
223 return '() => <int>[$byteList]'; 204 return '() => <int>[$byteList]';
224 case FieldDescriptorProto_Type.TYPE_GROUP: 205 case FieldDescriptorProto_Type.TYPE_GROUP:
225 case FieldDescriptorProto_Type.TYPE_MESSAGE: 206 case FieldDescriptorProto_Type.TYPE_MESSAGE:
226 if (samePackage) return '${baseType.unprefixed}.getDefault'; 207 if (samePackage) return '${baseType.unprefixed}.getDefault';
227 return "${baseType.prefixed}.getDefault"; 208 return "${baseType.prefixed}.getDefault";
228 case FieldDescriptorProto_Type.TYPE_ENUM: 209 case FieldDescriptorProto_Type.TYPE_ENUM:
229 var className = samePackage ? baseType.unprefixed : baseType.prefixed; 210 var className = samePackage ? baseType.unprefixed : baseType.prefixed;
230 EnumGenerator gen = baseType.generator; 211 EnumGenerator gen = baseType.generator;
231 if (_field.hasDefaultValue() && !_field.defaultValue.isEmpty) { 212 if (descriptor.hasDefaultValue() && !descriptor.defaultValue.isEmpty) {
232 return '$className.${_field.defaultValue}'; 213 return '$className.${descriptor.defaultValue}';
233 } else if (!gen._canonicalValues.isEmpty) { 214 } else if (!gen._canonicalValues.isEmpty) {
234 return '$className.${gen._canonicalValues[0].name}'; 215 return '$className.${gen._canonicalValues[0].name}';
235 } 216 }
236 return null; 217 return null;
237 default: 218 default:
238 throw _typeNotImplemented("generatedDefaultFunction"); 219 throw _typeNotImplemented("generatedDefaultFunction");
239 } 220 }
240 } 221 }
241 222
242 String _getDefaultAsBoolExpr(String noDefault) { 223 String _getDefaultAsBoolExpr(String noDefault) {
243 if (_field.hasDefaultValue() && 'false' != _field.defaultValue) { 224 if (descriptor.hasDefaultValue() && 'false' != descriptor.defaultValue) {
244 return '${_field.defaultValue}'; 225 return '${descriptor.defaultValue}';
245 } 226 }
246 return noDefault; 227 return noDefault;
247 } 228 }
248 229
249 String _getDefaultAsStringExpr(String noDefault) { 230 String _getDefaultAsStringExpr(String noDefault) {
250 if (!_field.hasDefaultValue() || _field.defaultValue.isEmpty) { 231 if (!descriptor.hasDefaultValue() || descriptor.defaultValue.isEmpty) {
251 return noDefault; 232 return noDefault;
252 } 233 }
253 // TODO(skybrian): fix dubious escaping. 234 // TODO(skybrian): fix dubious escaping.
254 String value = _field.defaultValue.replaceAll(r'$', r'\$'); 235 String value = descriptor.defaultValue.replaceAll(r'$', r'\$');
255 return '\'$value\''; 236 return '\'$value\'';
256 } 237 }
257 238
258 String _getDefaultAsInt32Expr(String noDefault) { 239 String _getDefaultAsInt32Expr(String noDefault) {
259 if (_field.hasDefaultValue() && '0' != _field.defaultValue) { 240 if (descriptor.hasDefaultValue() && '0' != descriptor.defaultValue) {
260 return '${_field.defaultValue}'; 241 return '${descriptor.defaultValue}';
261 } 242 }
262 return noDefault; 243 return noDefault;
263 } 244 }
264 245
265 get _invalidDefaultValue => "dart-protoc-plugin:" 246 get _invalidDefaultValue => "dart-protoc-plugin:"
266 " invalid default value (${_field.defaultValue})" 247 " invalid default value (${descriptor.defaultValue})"
267 " found in field $fqname"; 248 " found in field $fqname";
268 249
269 _typeNotImplemented(String methodName) => "dart-protoc-plugin:" 250 _typeNotImplemented(String methodName) => "dart-protoc-plugin:"
270 " $methodName not implemented for type (${_field.type})" 251 " $methodName not implemented for type (${descriptor.type})"
271 " found in field $fqname"; 252 " found in field $fqname";
272 } 253 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698