generateForAnnotatedElement method

  1. @override
String generateForAnnotatedElement(
  1. Element element,
  2. ConstantReader annotation,
  3. 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();
}