generateForAnnotatedElement method
String
generateForAnnotatedElement(
- Element element,
- ConstantReader annotation,
- BuildStep buildStep
Implement to return source code to generate for element.
This method is invoked based on finding elements annotated with an
instance of T. The annotation is provided as a ConstantReader.
Supported return values include a single String or multiple String instances within an Iterable or Stream. It is also valid to return a Future of String, Iterable, or Stream.
Implementations should return null when no content is generated. Empty
or whitespace-only String instances are also ignored.
Implementation
@override
String generateForAnnotatedElement(
Element element,
ConstantReader annotation,
BuildStep buildStep,
) {
if (element is! ClassElement) {
throw '@BleObject can only be used on classes';
}
final className = element.name;
print('Generating parser for class: $className');
// Read default values from @BleObject annotation
final defaultEndian = _readDefaultEndian(annotation);
final defaultSigned = _readDefaultSigned(annotation);
// Collect field information first
int autoOffset = 0;
List<String> constructorArgsUint8 = [];
List<String> constructorArgsList = [];
// Iterate through all fields
for (var field in element.fields) {
if (field.isStatic) continue;
// Get @BleField annotation with defaults applied
final fieldAnn = _getAnnotation(field, defaultEndian, defaultSigned);
if (fieldAnn == null) continue;
// 1. Determine offset
int currentOffset = fieldAnn.offset ?? autoOffset;
// 2. Generate read expressions for both Uint8List and List<int> versions
String readExprUint8 = _genReadExpr(fieldAnn, currentOffset, true);
String readExprList = _genReadExpr(fieldAnn, currentOffset, false);
// 3. Store constructor arguments separately for each version
constructorArgsUint8.add('${field.name}: $readExprUint8');
constructorArgsList.add('${field.name}: $readExprList');
// 4. Update auto offset
autoOffset = currentOffset + fieldAnn.length;
}
final constructorBody = ' return $className(\n${constructorArgsUint8.join(',\n')}\n );';
final constructorBodyList = ' return $className(\n${constructorArgsList.join(',\n')}\n );';
final buffer = StringBuffer();
// Generate Uint8List version (primary method, keeps original name)
buffer.writeln('$className _\$${className}FromBytes(Uint8List rawData) {');
buffer.writeln(' final view = ByteData.sublistView(rawData);');
buffer.write(constructorBody);
buffer.writeln('}');
buffer.writeln('');
// Generate List<int> version (additional method for compatibility)
buffer.writeln('$className _\$${className}FromBytesList(List<int> rawData) {');
buffer.writeln(' final view = ByteData.sublistView(Uint8List.fromList(rawData));');
buffer.write(constructorBodyList);
buffer.writeln('}');
return buffer.toString();
}