// Copyright (c) 2015, 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.

/// This file contains code to generate serialization/deserialization logic for
/// summaries based on an "IDL" description of the summary format (written in
/// stylized Dart).
///
/// For each class in the "IDL" input, two corresponding classes are generated:
/// - A class with the same name which represents deserialized summary data in
///   memory.  This class has read-only semantics.
/// - A "builder" class which can be used to generate serialized summary data.
///   This class has write-only semantics.
///
/// Each of the "builder" classes has a single `finish` method which writes
/// the entity being built into the given FlatBuffer and returns the `Offset`
/// reference to it.
import 'dart:convert';
import 'dart:io';

import 'package:analysis_tool/tools.dart';
import 'package:front_end/src/fasta/scanner/string_scanner.dart';
import 'package:front_end/src/scanner/token.dart' show Token;

import 'idl_model.dart' as idlModel;
import 'mini_ast.dart';

main(List<String> args) async {
  if (args.length != 1) {
    print('Error: IDL path is required');
    print('usage: dart generate.dart path/to/idl.dart');
  }
  String idlPath = args[0];
  await GeneratedContent.generateAll(
      File(idlPath).parent.path, getAllTargets(idlPath));
}

List<GeneratedContent> getAllTargets(String idlPath) {
  final GeneratedFile formatTarget =
      new GeneratedFile('format.dart', (_) async {
    _CodeGenerator codeGenerator = new _CodeGenerator(idlPath);
    codeGenerator.generateFormatCode();
    return codeGenerator._outBuffer.toString();
  });

  final GeneratedFile schemaTarget = new GeneratedFile('format.fbs', (_) async {
    _CodeGenerator codeGenerator = new _CodeGenerator(idlPath);
    codeGenerator.generateFlatBufferSchema();
    return codeGenerator._outBuffer.toString();
  });

  return <GeneratedContent>[formatTarget, schemaTarget];
}

typedef String _StringToString(String s);

class _CodeGenerator {
  static const String _throwDeprecated =
      "throw new UnimplementedError('attempt to access deprecated field')";

  /// Buffer in which generated code is accumulated.
  final StringBuffer _outBuffer = new StringBuffer();

  /// Current indentation level.
  String _indentation = '';

  /// Semantic model of the "IDL" input file.
  idlModel.Idl _idl;

  _CodeGenerator(String idlPath) {
    // Parse the input "IDL" file.
    File idlFile = new File(idlPath);
    String idlText =
        idlFile.readAsStringSync().replaceAll(new RegExp('\r\n?'), '\n');
    // Extract a description of the IDL and make sure it is valid.
    var scanner = new StringScanner(idlText, includeComments: true);
    var startingToken = scanner.tokenize();
    var listener = new MiniAstBuilder();
    var parser = new MiniAstParser(listener);
    parser.parseUnit(startingToken);
    extractIdl(listener.compilationUnit);
    checkIdl();
  }

  /// Perform basic sanity checking of the IDL (over and above that done by
  /// [extractIdl]).
  void checkIdl() {
    _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) {
      if (cls.fileIdentifier != null) {
        if (cls.fileIdentifier.length != 4) {
          throw new Exception('$name: file identifier must be 4 characters');
        }
        for (int i = 0; i < cls.fileIdentifier.length; i++) {
          if (cls.fileIdentifier.codeUnitAt(i) >= 256) {
            throw new Exception(
                '$name: file identifier must be encodable as Latin-1');
          }
        }
      }
      Map<int, String> idsUsed = <int, String>{};
      for (idlModel.FieldDeclaration field in cls.allFields) {
        String fieldName = field.name;
        idlModel.FieldType type = field.type;
        if (type.isList) {
          if (_idl.classes.containsKey(type.typeName)) {
            // List of classes is ok
          } else if (_idl.enums.containsKey(type.typeName)) {
            // List of enums is ok
          } else if (type.typeName == 'bool') {
            // List of booleans is ok
          } else if (type.typeName == 'int') {
            // List of ints is ok
          } else if (type.typeName == 'double') {
            // List of doubles is ok
          } else if (type.typeName == 'String') {
            // List of strings is ok
          } else {
            throw new Exception(
                '$name.$fieldName: illegal type (list of ${type.typeName})');
          }
        }
        if (idsUsed.containsKey(field.id)) {
          throw new Exception('$name.$fieldName: id ${field.id} already used by'
              ' ${idsUsed[field.id]}');
        }
        idsUsed[field.id] = fieldName;
      }
      for (int i = 0; i < idsUsed.length; i++) {
        if (!idsUsed.containsKey(i)) {
          throw new Exception('$name: no field uses id $i');
        }
      }
    });
  }

  /// Generate a string representing the Dart type which should be used to
  /// represent [type] when deserialized.
  String dartType(idlModel.FieldType type) {
    String baseType = idlPrefix(type.typeName);
    if (type.isList) {
      return 'List<$baseType>';
    } else {
      return baseType;
    }
  }

  /// Generate a Dart expression representing the default value for a field
  /// having the given [type], or `null` if there is no default value.
  ///
  /// If [builder] is `true`, the returned type should be appropriate for use in
  /// a builder class.
  String defaultValue(idlModel.FieldType type, bool builder) {
    if (type.isList) {
      if (builder) {
        idlModel.FieldType elementType =
            new idlModel.FieldType(type.typeName, false);
        return '<${encodedType(elementType)}>[]';
      } else {
        return 'const <${idlPrefix(type.typeName)}>[]';
      }
    } else if (_idl.enums.containsKey(type.typeName)) {
      return '${idlPrefix(type.typeName)}.'
          '${_idl.enums[type.typeName].values[0].name}';
    } else if (type.typeName == 'double') {
      return '0.0';
    } else if (type.typeName == 'int') {
      return '0';
    } else if (type.typeName == 'String') {
      return "''";
    } else if (type.typeName == 'bool') {
      return 'false';
    } else {
      return null;
    }
  }

  /// Generate a string representing the Dart type which should be used to
  /// represent [type] while building a serialized data structure.
  String encodedType(idlModel.FieldType type) {
    String typeStr;
    if (_idl.classes.containsKey(type.typeName)) {
      typeStr = '${type.typeName}Builder';
    } else {
      typeStr = idlPrefix(type.typeName);
    }
    if (type.isList) {
      return 'List<$typeStr>';
    } else {
      return typeStr;
    }
  }

  /// Process the AST in [idlParsed] and store the resulting semantic model in
  /// [_idl].  Also perform some error checking.
  void extractIdl(CompilationUnit idlParsed) {
    _idl = new idlModel.Idl();
    for (CompilationUnitMember decl in idlParsed.declarations) {
      if (decl is ClassDeclaration) {
        bool isTopLevel = false;
        bool isDeprecated = false;
        String fileIdentifier;
        String clsName = decl.name;
        String variantField;
        for (Annotation annotation in decl.metadata) {
          if (annotation.arguments != null &&
              annotation.name == 'TopLevel' &&
              annotation.constructorName == null) {
            isTopLevel = true;
            if (annotation.arguments.length == 1) {
              Expression arg = annotation.arguments[0];
              if (arg is StringLiteral) {
                fileIdentifier = arg.stringValue;
              } else {
                throw new Exception(
                    'Class `$clsName`: TopLevel argument must be a string'
                    ' literal');
              }
            } else if (annotation.arguments.length != 0) {
              throw new Exception(
                  'Class `$clsName`: TopLevel requires 0 or 1 arguments');
            }
          } else if (annotation.arguments == null &&
              annotation.name == 'deprecated' &&
              annotation.constructorName == null) {
            isDeprecated = true;
          } else if (annotation.arguments != null &&
              annotation.name == 'Variant' &&
              annotation.constructorName == null) {
            if (annotation.arguments.length == 1) {
              Expression arg = annotation.arguments[0];
              if (arg is StringLiteral) {
                variantField = arg.stringValue;
              } else {
                throw new Exception(
                  'Class `$clsName`: @Variant argument must be a string literal',
                );
              }
            } else if (annotation.arguments.length != 0) {
              throw Exception(
                'Class `$clsName`: @Variant requires 1 argument',
              );
            }
          }
        }
        idlModel.ClassDeclaration cls = new idlModel.ClassDeclaration(
          documentation: _getNodeDoc(decl),
          name: clsName,
          isTopLevel: isTopLevel,
          fileIdentifier: fileIdentifier,
          isDeprecated: isDeprecated,
          variantField: variantField,
        );
        _idl.classes[clsName] = cls;
        String expectedBase = 'base.SummaryClass';
        if (decl.superclass == null || decl.superclass.name != expectedBase) {
          throw new Exception(
              'Class `$clsName` needs to extend `$expectedBase`');
        }
        for (ClassMember classMember in decl.members) {
          if (classMember is MethodDeclaration && classMember.isGetter) {
            _addFieldForGetter(cls, classMember);
          } else if (classMember is ConstructorDeclaration &&
              classMember.name.endsWith('fromBuffer')) {
            // Ignore `fromBuffer` declarations; they simply forward to the
            // read functions generated by [_generateReadFunction].
          } else {
            throw new Exception('Unexpected class member `$classMember`');
          }
        }
      } else if (decl is EnumDeclaration) {
        String doc = _getNodeDoc(decl);
        idlModel.EnumDeclaration enm =
            new idlModel.EnumDeclaration(doc, decl.name);
        _idl.enums[enm.name] = enm;
        for (EnumConstantDeclaration constDecl in decl.constants) {
          String doc = _getNodeDoc(constDecl);
          enm.values
              .add(new idlModel.EnumValueDeclaration(doc, constDecl.name));
        }
      } else {
        throw new Exception('Unexpected declaration `$decl`');
      }
    }
  }

  /// Generate a string representing the FlatBuffer schema type which should be
  /// used to represent [type].
  String fbsType(idlModel.FieldType type) {
    String typeStr;
    switch (type.typeName) {
      case 'bool':
        typeStr = 'bool';
        break;
      case 'double':
        typeStr = 'double';
        break;
      case 'int':
        typeStr = 'uint';
        break;
      case 'String':
        typeStr = 'string';
        break;
      default:
        typeStr = type.typeName;
        break;
    }
    if (type.isList) {
      // FlatBuffers don't natively support a packed list of booleans, so we
      // treat it as a list of unsigned bytes, which is a compatible data
      // structure.
      if (typeStr == 'bool') {
        typeStr = 'ubyte';
      }
      return '[$typeStr]';
    } else {
      return typeStr;
    }
  }

  /// Entry point to the code generator when generating the "format.fbs" file.
  void generateFlatBufferSchema() {
    outputHeader();
    for (idlModel.EnumDeclaration enm in _idl.enums.values) {
      out();
      outDoc(enm.documentation);
      out('enum ${enm.name} : byte {');
      indent(() {
        for (int i = 0; i < enm.values.length; i++) {
          idlModel.EnumValueDeclaration value = enm.values[i];
          if (i != 0) {
            out();
          }
          String suffix = i < enm.values.length - 1 ? ',' : '';
          outDoc(value.documentation);
          out('${value.name}$suffix');
        }
      });
      out('}');
    }
    for (idlModel.ClassDeclaration cls in _idl.classes.values) {
      out();
      outDoc(cls.documentation);
      out('table ${cls.name} {');
      indent(() {
        for (int i = 0; i < cls.allFields.length; i++) {
          idlModel.FieldDeclaration field = cls.allFields[i];
          if (i != 0) {
            out();
          }
          outDoc(field.documentation);
          List<String> attributes = <String>['id: ${field.id}'];
          if (field.isDeprecated) {
            attributes.add('deprecated');
          }
          String attrText = attributes.join(', ');
          out('${field.name}:${fbsType(field.type)} ($attrText);');
        }
      });
      out('}');
    }
    out();
    // Standard flatbuffers only support one root type.  We support multiple
    // root types.  For now work around this by forcing PackageBundle to be the
    // root type.  TODO(paulberry): come up with a better solution.
    idlModel.ClassDeclaration rootType = _idl.classes['PackageBundle'];
    out('root_type ${rootType.name};');
    if (rootType.fileIdentifier != null) {
      out();
      out('file_identifier ${quoted(rootType.fileIdentifier)};');
    }
  }

  /// Entry point to the code generator when generating the "format.dart" file.
  void generateFormatCode() {
    outputHeader();
    out('library analyzer.src.summary.format;');
    out();
    out("import 'dart:convert' as convert;");
    out();
    out("import 'package:analyzer/src/summary/api_signature.dart' as api_sig;");
    out("import 'package:analyzer/src/summary/flat_buffers.dart' as fb;");
    out();
    out("import 'idl.dart' as idl;");
    out();
    for (idlModel.EnumDeclaration enm in _idl.enums.values) {
      _generateEnumReader(enm);
      out();
    }
    for (idlModel.ClassDeclaration cls in _idl.classes.values) {
      if (!cls.isDeprecated) {
        _generateBuilder(cls);
        out();
      }
      if (cls.isTopLevel) {
        _generateReadFunction(cls);
        out();
      }
      if (!cls.isDeprecated) {
        _generateReader(cls);
        out();
        _generateImpl(cls);
        out();
        _generateMixin(cls);
        out();
      }
    }
  }

  /// Add the prefix `idl.` to a type name, unless that type name is the name of
  /// a built-in type.
  String idlPrefix(String s) {
    switch (s) {
      case 'bool':
      case 'double':
      case 'int':
      case 'String':
        return s;
      default:
        return 'idl.$s';
    }
  }

  /// Execute [callback] with two spaces added to [_indentation].
  void indent(void callback()) {
    String oldIndentation = _indentation;
    try {
      _indentation += '  ';
      callback();
    } finally {
      _indentation = oldIndentation;
    }
  }

  /// Add the string [s] to the output as a single line, indenting as
  /// appropriate.
  void out([String s = '']) {
    if (s == '') {
      _outBuffer.writeln('');
    } else {
      _outBuffer.writeln('$_indentation$s');
    }
  }

  void outDoc(String documentation) {
    if (documentation != null) {
      documentation.split('\n').forEach(out);
    }
  }

  void outputHeader() {
    out('// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file');
    out('// for details. All rights reserved. Use of this source code is governed by a');
    out('// BSD-style license that can be found in the LICENSE file.');
    out('//');
    out('// This file has been automatically generated.  Please do not edit it manually.');
    out('// To regenerate the file, use the SDK script');
    out('// "pkg/analyzer/tool/summary/generate.dart \$IDL_FILE_PATH",');
    out('// or "pkg/analyzer/tool/generate_files" for the analyzer package IDL/sources.');
    out();
  }

  /// Enclose [s] in quotes, escaping as necessary.
  String quoted(String s) {
    return json.encode(s);
  }

  void _addFieldForGetter(
    idlModel.ClassDeclaration cls,
    MethodDeclaration getter,
  ) {
    var desc = '${cls.name}.${getter.name}';
    if (getter.returnType == null) {
      throw new Exception('Getter needs a type: $desc');
    }

    var type = getter.returnType;

    var isList = false;
    if (type.name == 'List' &&
        type.typeArguments != null &&
        type.typeArguments.length == 1) {
      isList = true;
      type = type.typeArguments[0];
    }
    if (type.typeArguments != null) {
      throw new Exception('Cannot handle type arguments in `$type`');
    }

    int id;
    List<String> variants;
    bool isDeprecated = false;
    bool isInformative = false;

    for (Annotation annotation in getter.metadata) {
      if (annotation.name == 'Id') {
        if (id != null) {
          throw new Exception('Duplicate @id annotation ($getter)');
        }
        if (annotation.arguments == null) {
          throw Exception('@Id must be passed an argument ($desc)');
        }
        if (annotation.arguments.length != 1) {
          throw Exception('@Id must be passed exactly one argument ($desc)');
        }

        var idExpression = annotation.arguments[0];
        if (idExpression is IntegerLiteral) {
          id = idExpression.value;
        } else {
          throw new Exception(
            '@Id argument must be an integer literal ($desc)',
          );
        }
      } else if (annotation.name == 'deprecated') {
        if (annotation.arguments != null) {
          throw new Exception('@deprecated does not take args ($desc)');
        }
        isDeprecated = true;
      } else if (annotation.name == 'informative') {
        isInformative = true;
      } else if (annotation.name == 'VariantId') {
        if (id != null) {
          throw Exception('Cannot specify both @Id and @VariantId ($getter)');
        }
        if (variants != null) {
          throw Exception('Duplicate @VariantId annotation ($getter)');
        }

        if (annotation.arguments == null) {
          throw Exception('@VariantId must be given arguments ($desc)');
        }
        if (annotation.arguments.length != 2) {
          throw Exception(
            '@VariantId must be given exactly two arguments ($desc)',
          );
        }

        var idExpression = annotation.arguments[0];
        if (idExpression is IntegerLiteral) {
          id = idExpression.value;
        } else {
          throw Exception(
            '@VariantId argument must be an integer literal ($desc)',
          );
        }

        var variantExpression = annotation.arguments[1];
        if (variantExpression is NamedExpression) {
          if (variantExpression.name == 'variant') {
            variants = [variantExpression.expression.toCode()];
          } else if (variantExpression.name == 'variantList') {
            variants = (variantExpression.expression as ListLiteral)
                .elements
                .map((e) => e.toCode())
                .toList();
          } else {
            throw Exception(
              'Only "key" or "keyList" expected in @VariantId ($desc)',
            );
          }
        } else {
          throw Exception(
            'The second argument of @VariantId must be named ($desc)',
          );
        }
      }
    }
    if (id == null) {
      throw new Exception('Missing @id annotation ($desc)');
    }

    var fieldType = new idlModel.FieldType(type.name, isList);

    String name = getter.name;
    Map<String, List<String>> variantMap;
    if (variants != null) {
      var fieldsWithSameId =
          cls.allFields.where((field) => field.id == id).toList();
      if (fieldsWithSameId.isNotEmpty) {
        var existingField = fieldsWithSameId.first;
        if (existingField.variantMap == null) {
          throw Exception('$desc: id $id is already used as a non-variant '
              'field: ${existingField.name}');
        }

        var map = existingField.variantMap;
        for (var variant in variants) {
          for (var logicalName in map.keys) {
            if (map[logicalName].contains(variant)) {
              throw Exception('$desc: id $id is already used for $logicalName');
            }
          }
        }

        if (existingField.type != fieldType) {
          throw Exception(
            '$desc: id $id is already used with type ${existingField.type}',
          );
        }

        map.putIfAbsent(getter.name, () => <String>[]).addAll(variants);
        return;
      } else {
        name = 'variantField_$id';
        variantMap = <String, List<String>>{getter.name: variants};
      }
    }

    cls.allFields.add(
      idlModel.FieldDeclaration(
        documentation: _getNodeDoc(getter),
        name: name,
        type: fieldType,
        id: id,
        isDeprecated: isDeprecated,
        isInformative: isInformative,
        variantMap: variantMap,
      ),
    );
  }

  Iterable<String> _computeVariants(idlModel.ClassDeclaration cls) {
    return cls.fields
        .map((f) => f.variantMap?.values ?? [])
        .expand((v) => v)
        .expand((v) => v)
        .toSet();
  }

  void _generateBuilder(idlModel.ClassDeclaration cls) {
    String name = cls.name;
    String builderName = name + 'Builder';
    String mixinName = '_${name}Mixin';
    List<String> constructorParams = <String>[];
    var implementsClause =
        cls.isDeprecated ? '' : ' implements ${idlPrefix(name)}';
    out('class $builderName extends Object with $mixinName$implementsClause {');
    indent(() {
      // Generate fields.
      for (idlModel.FieldDeclaration field in cls.fields) {
        String fieldName = field.name;
        idlModel.FieldType type = field.type;
        String typeStr = encodedType(type);
        out('$typeStr _$fieldName;');
      }

      // Generate getters and setters.
      for (idlModel.FieldDeclaration field in cls.allFields) {
        String fieldName = field.name;
        idlModel.FieldType fieldType = field.type;
        String typeStr = encodedType(fieldType);
        String def = defaultValue(fieldType, true);
        String defSuffix = def == null ? '' : ' ??= $def';
        out();
        if (field.isDeprecated) {
          out('@override');
          out('Null get $fieldName => $_throwDeprecated;');
        } else {
          if (field.variantMap != null) {
            for (var logicalName in field.variantMap.keys) {
              var variants = field.variantMap[logicalName];
              out('@override');
              out('$typeStr get $logicalName {');
              indent(() {
                out(_variantAssertStatement(cls, variants));
                out('return _${field.name}$defSuffix;');
              });
              out('}');
              out();
            }
          } else {
            out('@override');
            out('$typeStr get $fieldName => _$fieldName$defSuffix;');
          }
          out();

          constructorParams.add('$typeStr $fieldName');

          outDoc(field.documentation);

          if (field.variantMap != null) {
            for (var logicalName in field.variantMap.keys) {
              var variants = field.variantMap[logicalName];
              out('set $logicalName($typeStr value) {');
              indent(() {
                out(_variantAssertStatement(cls, variants));
                _generateNonNegativeInt(fieldType);
                out('_variantField_${field.id} = value;');
              });
              out('}');
              out();
            }
          } else {
            out('set $fieldName($typeStr value) {');
            indent(() {
              _generateNonNegativeInt(fieldType);
              out('this._$fieldName = value;');
            });
            out('}');
          }
        }
      }
      // Generate constructor.
      out();
      if (cls.variantField != null) {
        for (var variant in _computeVariants(cls)) {
          var constructorName = variant.split('.')[1];
          out('$builderName.$constructorName({');

          for (var field in cls.fields) {
            if (field.variantMap != null) {
              for (var property in field.variantMap.keys) {
                if (field.variantMap[property].contains(variant)) {
                  out('${encodedType(field.type)} $property,');
                }
              }
            }
          }

          out('}) : ');

          out('_${cls.variantField} = idl.$variant');

          var separator = ',';
          for (var field in cls.fields) {
            if (field.variantMap != null) {
              for (var property in field.variantMap.keys) {
                if (field.variantMap[property].contains(variant)) {
                  out('$separator _${field.name} = $property');
                  separator = ', ';
                }
              }
            }
          }

          out(';');
          out();
        }
      } else {
        out('$builderName({${constructorParams.join(', ')}})');
        List<idlModel.FieldDeclaration> fields = cls.fields.toList();
        for (int i = 0; i < fields.length; i++) {
          idlModel.FieldDeclaration field = fields[i];
          String prefix = i == 0 ? '  : ' : '    ';
          String suffix = i == fields.length - 1 ? ';' : ',';
          out('${prefix}_${field.name} = ${field.name}$suffix');
        }
      }

      // Generate flushInformative().
      {
        out();
        out('/// Flush [informative] data recursively.');
        out('void flushInformative() {');
        indent(() {
          for (idlModel.FieldDeclaration field in cls.fields) {
            idlModel.FieldType fieldType = field.type;
            String valueName = '_' + field.name;
            if (field.isInformative) {
              out('$valueName = null;');
            } else if (_idl.classes.containsKey(fieldType.typeName)) {
              if (fieldType.isList) {
                out('$valueName?.forEach((b) => b.flushInformative());');
              } else {
                out('$valueName?.flushInformative();');
              }
            }
          }
        });
        out('}');
      }
      // Generate collectApiSignature().
      {
        out();
        out('/// Accumulate non-[informative] data into [signature].');
        out('void collectApiSignature(api_sig.ApiSignature signature) {');
        indent(() {
          List<idlModel.FieldDeclaration> sortedFields = cls.fields.toList()
            ..sort((idlModel.FieldDeclaration a, idlModel.FieldDeclaration b) =>
                a.id.compareTo(b.id));
          for (idlModel.FieldDeclaration field in sortedFields) {
            if (field.isInformative) {
              continue;
            }
            String ref = 'this._${field.name}';
            if (field.type.isList) {
              out('if ($ref == null) {');
              indent(() {
                out('signature.addInt(0);');
              });
              out('} else {');
              indent(() {
                out('signature.addInt($ref.length);');
                out('for (var x in $ref) {');
                indent(() {
                  _generateSignatureCall(field.type.typeName, 'x', false);
                });
                out('}');
              });
              out('}');
            } else {
              _generateSignatureCall(field.type.typeName, ref, true);
            }
          }
        });
        out('}');
      }
      // Generate finish.
      if (cls.isTopLevel) {
        out();
        out('List<int> toBuffer() {');
        indent(() {
          out('fb.Builder fbBuilder = new fb.Builder();');
          String fileId = cls.fileIdentifier == null
              ? ''
              : ', ${quoted(cls.fileIdentifier)}';
          out('return fbBuilder.finish(finish(fbBuilder)$fileId);');
        });
        out('}');
      }
      out();
      out('fb.Offset finish(fb.Builder fbBuilder) {');
      indent(() {
        // Write objects and remember Offset(s).
        for (idlModel.FieldDeclaration field in cls.fields) {
          idlModel.FieldType fieldType = field.type;
          String offsetName = 'offset_' + field.name;
          if (fieldType.isList ||
              fieldType.typeName == 'String' ||
              _idl.classes.containsKey(fieldType.typeName)) {
            out('fb.Offset $offsetName;');
          }
        }
        for (idlModel.FieldDeclaration field in cls.fields) {
          idlModel.FieldType fieldType = field.type;
          String valueName = '_' + field.name;
          String offsetName = 'offset_' + field.name;
          String condition;
          String writeCode;
          if (fieldType.isList) {
            condition = ' || $valueName.isEmpty';
            if (_idl.classes.containsKey(fieldType.typeName)) {
              String itemCode = 'b.finish(fbBuilder)';
              String listCode = '$valueName.map((b) => $itemCode).toList()';
              writeCode = '$offsetName = fbBuilder.writeList($listCode);';
            } else if (_idl.enums.containsKey(fieldType.typeName)) {
              String itemCode = 'b.index';
              String listCode = '$valueName.map((b) => $itemCode).toList()';
              writeCode = '$offsetName = fbBuilder.writeListUint8($listCode);';
            } else if (fieldType.typeName == 'bool') {
              writeCode = '$offsetName = fbBuilder.writeListBool($valueName);';
            } else if (fieldType.typeName == 'int') {
              writeCode =
                  '$offsetName = fbBuilder.writeListUint32($valueName);';
            } else if (fieldType.typeName == 'double') {
              writeCode =
                  '$offsetName = fbBuilder.writeListFloat64($valueName);';
            } else {
              assert(fieldType.typeName == 'String');
              String itemCode = 'fbBuilder.writeString(b)';
              String listCode = '$valueName.map((b) => $itemCode).toList()';
              writeCode = '$offsetName = fbBuilder.writeList($listCode);';
            }
          } else if (fieldType.typeName == 'String') {
            writeCode = '$offsetName = fbBuilder.writeString($valueName);';
          } else if (_idl.classes.containsKey(fieldType.typeName)) {
            writeCode = '$offsetName = $valueName.finish(fbBuilder);';
          }
          if (writeCode != null) {
            if (condition == null) {
              out('if ($valueName != null) {');
            } else {
              out('if (!($valueName == null$condition)) {');
            }
            indent(() {
              out(writeCode);
            });
            out('}');
          }
        }
        // Write the table.
        out('fbBuilder.startTable();');
        for (idlModel.FieldDeclaration field in cls.fields) {
          int index = field.id;
          idlModel.FieldType fieldType = field.type;
          String valueName = '_' + field.name;
          String condition = '$valueName != null';
          String writeCode;
          if (fieldType.isList ||
              fieldType.typeName == 'String' ||
              _idl.classes.containsKey(fieldType.typeName)) {
            String offsetName = 'offset_' + field.name;
            condition = '$offsetName != null';
            writeCode = 'fbBuilder.addOffset($index, $offsetName);';
          } else if (fieldType.typeName == 'bool') {
            condition = '$valueName == true';
            writeCode = 'fbBuilder.addBool($index, true);';
          } else if (fieldType.typeName == 'double') {
            condition += ' && $valueName != ${defaultValue(fieldType, true)}';
            writeCode = 'fbBuilder.addFloat64($index, $valueName);';
          } else if (fieldType.typeName == 'int') {
            condition += ' && $valueName != ${defaultValue(fieldType, true)}';
            writeCode = 'fbBuilder.addUint32($index, $valueName);';
          } else if (_idl.enums.containsKey(fieldType.typeName)) {
            condition += ' && $valueName != ${defaultValue(fieldType, true)}';
            writeCode = 'fbBuilder.addUint8($index, $valueName.index);';
          }
          if (writeCode == null) {
            throw new UnimplementedError('Writing type ${fieldType.typeName}');
          }
          out('if ($condition) {');
          indent(() {
            out(writeCode);
          });
          out('}');
        }
        out('return fbBuilder.endTable();');
      });
      out('}');
    });
    out('}');
  }

  void _generateEnumReader(idlModel.EnumDeclaration enm) {
    String name = enm.name;
    String readerName = '_${name}Reader';
    String count = '${idlPrefix(name)}.values.length';
    String def = '${idlPrefix(name)}.${enm.values[0].name}';
    out('class $readerName extends fb.Reader<${idlPrefix(name)}> {');
    indent(() {
      out('const $readerName() : super();');
      out();
      out('@override');
      out('int get size => 1;');
      out();
      out('@override');
      out('${idlPrefix(name)} read(fb.BufferContext bc, int offset) {');
      indent(() {
        out('int index = const fb.Uint8Reader().read(bc, offset);');
        out('return index < $count ? ${idlPrefix(name)}.values[index] : $def;');
      });
      out('}');
    });
    out('}');
  }

  void _generateImpl(idlModel.ClassDeclaration cls) {
    String name = cls.name;
    String implName = '_${name}Impl';
    String mixinName = '_${name}Mixin';
    out('class $implName extends Object with $mixinName'
        ' implements ${idlPrefix(name)} {');
    indent(() {
      out('final fb.BufferContext _bc;');
      out('final int _bcOffset;');
      out();
      out('$implName(this._bc, this._bcOffset);');
      out();
      // Write cache fields.
      for (idlModel.FieldDeclaration field in cls.fields) {
        String returnType = dartType(field.type);
        String fieldName = field.name;
        out('$returnType _$fieldName;');
      }
      // Write getters.
      for (idlModel.FieldDeclaration field in cls.allFields) {
        int index = field.id;
        String fieldName = field.name;
        idlModel.FieldType type = field.type;
        String typeName = type.typeName;
        // Prepare "readCode" + "def"
        String readCode;
        String def = defaultValue(type, false);
        if (type.isList) {
          if (typeName == 'bool') {
            readCode = 'const fb.BoolListReader()';
          } else if (typeName == 'int') {
            readCode = 'const fb.Uint32ListReader()';
          } else if (typeName == 'double') {
            readCode = 'const fb.Float64ListReader()';
          } else if (typeName == 'String') {
            String itemCode = 'const fb.StringReader()';
            readCode = 'const fb.ListReader<String>($itemCode)';
          } else if (_idl.classes.containsKey(typeName)) {
            String itemCode = 'const _${typeName}Reader()';
            readCode = 'const fb.ListReader<${idlPrefix(typeName)}>($itemCode)';
          } else {
            assert(_idl.enums.containsKey(typeName));
            String itemCode = 'const _${typeName}Reader()';
            readCode = 'const fb.ListReader<${idlPrefix(typeName)}>($itemCode)';
          }
        } else if (typeName == 'bool') {
          readCode = 'const fb.BoolReader()';
        } else if (typeName == 'double') {
          readCode = 'const fb.Float64Reader()';
        } else if (typeName == 'int') {
          readCode = 'const fb.Uint32Reader()';
        } else if (typeName == 'String') {
          readCode = 'const fb.StringReader()';
        } else if (_idl.enums.containsKey(typeName)) {
          readCode = 'const _${typeName}Reader()';
        } else if (_idl.classes.containsKey(typeName)) {
          readCode = 'const _${typeName}Reader()';
        }
        assert(readCode != null);
        // Write the getter implementation.
        out();
        String returnType = dartType(type);
        if (field.isDeprecated) {
          out('@override');
          out('Null get $fieldName => $_throwDeprecated;');
        } else {
          if (field.variantMap != null) {
            for (var logicalName in field.variantMap.keys) {
              var variants = field.variantMap[logicalName];
              out('@override');
              out('$returnType get $logicalName {');
              indent(() {
                out(_variantAssertStatement(cls, variants));
                String readExpr =
                    '$readCode.vTableGet(_bc, _bcOffset, $index, $def)';
                out('_$fieldName ??= $readExpr;');
                out('return _$fieldName;');
              });
              out('}');
              out();
            }
          } else {
            out('@override');
            out('$returnType get $fieldName {');
            indent(() {
              String readExpr =
                  '$readCode.vTableGet(_bc, _bcOffset, $index, $def)';
              out('_$fieldName ??= $readExpr;');
              out('return _$fieldName;');
            });
            out('}');
          }
        }
      }
    });
    out('}');
  }

  void _generateMixin(idlModel.ClassDeclaration cls) {
    String name = cls.name;
    String mixinName = '_${name}Mixin';
    out('abstract class $mixinName implements ${idlPrefix(name)} {');
    indent(() {
      String jsonCondition(idlModel.FieldType type, String name) {
        if (type.isList) {
          return '$name.isNotEmpty';
        } else {
          return '$name != ${defaultValue(type, false)}';
        }
      }

      String jsonStore(idlModel.FieldType type, String name) {
        _StringToString convertItem;
        if (_idl.classes.containsKey(type.typeName)) {
          convertItem = (String name) => '$name.toJson()';
        } else if (_idl.enums.containsKey(type.typeName)) {
          // TODO(paulberry): it would be better to generate a const list of
          // strings so that we don't have to do this kludge.
          convertItem = (String name) => "$name.toString().split('.')[1]";
        } else if (type.typeName == 'double') {
          convertItem =
              (String name) => '$name.isFinite ? $name : $name.toString()';
        }
        String convertField;
        if (convertItem == null) {
          convertField = name;
        } else if (type.isList) {
          convertField = '$name.map((_value) =>'
              ' ${convertItem('_value')}).toList()';
        } else {
          convertField = convertItem(name);
        }
        return '_result[${quoted(name)}] = $convertField';
      }

      // Write toJson().
      out('@override');
      out('Map<String, Object> toJson() {');
      indent(() {
        out('Map<String, Object> _result = <String, Object>{};');

        if (cls.variantField != null) {
          indent(() {
            for (idlModel.FieldDeclaration field in cls.fields) {
              if (field.variantMap == null) {
                var condition = jsonCondition(field.type, field.name);
                var storeField = jsonStore(field.type, field.name);
                out('if ($condition) $storeField;');
              }
            }
            for (var variant in _computeVariants(cls)) {
              out('if (${cls.variantField} == idl.$variant) {');
              indent(() {
                for (idlModel.FieldDeclaration field in cls.fields) {
                  if (field.variantMap != null) {
                    for (var logicalName in field.variantMap.keys) {
                      if (field.variantMap[logicalName].contains(variant)) {
                        var condition = jsonCondition(field.type, logicalName);
                        var storeField = jsonStore(field.type, logicalName);
                        out('if ($condition) $storeField;');
                      }
                    }
                  }
                }
              });
              out('}');
            }
          });
        } else {
          indent(() {
            for (idlModel.FieldDeclaration field in cls.fields) {
              String condition = jsonCondition(field.type, field.name);
              String storeField = jsonStore(field.type, field.name);
              out('if ($condition) $storeField;');
            }
          });
        }

        out('return _result;');
      });
      out('}');
      out();

      // Write toMap().
      out('@override');
      if (cls.variantField != null) {
        out('Map<String, Object> toMap() {');
        for (var variant in _computeVariants(cls)) {
          out('if (${cls.variantField} == idl.$variant) {');
          indent(() {
            out('return {');
            for (idlModel.FieldDeclaration field in cls.fields) {
              if (field.variantMap != null) {
                for (var logicalName in field.variantMap.keys) {
                  if (field.variantMap[logicalName].contains(variant)) {
                    out('${quoted(logicalName)}: $logicalName,');
                  }
                }
              } else {
                String fieldName = field.name;
                out('${quoted(fieldName)}: $fieldName,');
              }
            }
            out('};');
          });
          out('}');
        }
        out('throw StateError("Unexpected \$${cls.variantField}");');
        out('}');
      } else {
        out('Map<String, Object> toMap() => {');
        indent(() {
          for (idlModel.FieldDeclaration field in cls.fields) {
            String fieldName = field.name;
            out('${quoted(fieldName)}: $fieldName,');
          }
        });
        out('};');
      }
      out();
      // Write toString().
      out('@override');
      out('String toString() => convert.json.encode(toJson());');
    });
    out('}');
  }

  void _generateNonNegativeInt(idlModel.FieldType fieldType) {
    if (fieldType.typeName == 'int') {
      if (!fieldType.isList) {
        out('assert(value == null || value >= 0);');
      } else {
        out('assert(value == null || value.every((e) => e >= 0));');
      }
    }
  }

  void _generateReader(idlModel.ClassDeclaration cls) {
    String name = cls.name;
    String readerName = '_${name}Reader';
    String implName = '_${name}Impl';
    out('class $readerName extends fb.TableReader<$implName> {');
    indent(() {
      out('const $readerName();');
      out();
      out('@override');
      out('$implName createObject(fb.BufferContext bc, int offset) => new $implName(bc, offset);');
    });
    out('}');
  }

  void _generateReadFunction(idlModel.ClassDeclaration cls) {
    String name = cls.name;
    out('${idlPrefix(name)} read$name(List<int> buffer) {');
    indent(() {
      out('fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);');
      out('return const _${name}Reader().read(rootRef, 0);');
    });
    out('}');
  }

  /// Generate a call to the appropriate method of [ApiSignature] for the type
  /// [typeName], using the data named by [ref].  If [couldBeNull] is `true`,
  /// generate code to handle the possibility that [ref] is `null` (substituting
  /// in the appropriate default value).
  void _generateSignatureCall(String typeName, String ref, bool couldBeNull) {
    if (_idl.enums.containsKey(typeName)) {
      if (couldBeNull) {
        out('signature.addInt($ref == null ? 0 : $ref.index);');
      } else {
        out('signature.addInt($ref.index);');
      }
    } else if (_idl.classes.containsKey(typeName)) {
      if (couldBeNull) {
        out('signature.addBool($ref != null);');
      }
      out('$ref?.collectApiSignature(signature);');
    } else {
      switch (typeName) {
        case 'String':
          if (couldBeNull) {
            ref += " ?? ''";
          }
          out("signature.addString($ref);");
          break;
        case 'int':
          if (couldBeNull) {
            ref += ' ?? 0';
          }
          out('signature.addInt($ref);');
          break;
        case 'bool':
          if (couldBeNull) {
            ref += ' == true';
          }
          out('signature.addBool($ref);');
          break;
        case 'double':
          if (couldBeNull) {
            ref += ' ?? 0.0';
          }
          out('signature.addDouble($ref);');
          break;
        default:
          throw "Don't know how to generate signature call for $typeName";
      }
    }
  }

  /// Return the documentation text of the given [node], or `null` if the [node]
  /// does not have a comment.  Each line is `\n` separated.
  String _getNodeDoc(AnnotatedNode node) {
    Comment comment = node.documentationComment;
    if (comment != null && comment.isDocumentation) {
      if (comment.tokens.length == 1 &&
          comment.tokens.first.lexeme.startsWith('/*')) {
        Token token = comment.tokens.first;
        return token.lexeme.split('\n').map((String line) {
          line = line.trimLeft();
          if (line.startsWith('*')) line = ' ' + line;
          return line;
        }).join('\n');
      } else if (comment.tokens
          .every((token) => token.lexeme.startsWith('///'))) {
        return comment.tokens
            .map((token) => token.lexeme.trimLeft())
            .join('\n');
      }
    }
    return null;
  }

  String _variantAssertStatement(
    idlModel.ClassDeclaration class_,
    List<String> variants,
  ) {
    var assertCondition = variants
        ?.map((key) => '${class_.variantField} == idl.$key')
        ?.join(' || ');
    return 'assert($assertCondition);';
  }
}
