// @dart = 2.9
// 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:_fe_analyzer_shared/src/scanner/scanner.dart';
import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
import 'package:analyzer_utilities/tools.dart';

import 'idl_model.dart' as idl_model;
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 = GeneratedFile('format.dart', (_) async {
    _CodeGenerator codeGenerator = _CodeGenerator(idlPath);
    codeGenerator.generateFormatCode();
    return codeGenerator._outBuffer.toString();
  });

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

  return <GeneratedContent>[formatTarget, schemaTarget];
}

typedef _StringToString = String Function(String s);

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

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

  /// Buffer in which generated code is accumulated.
  final StringBuffer _outBuffer;

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

  _BaseGenerator(this._idl, this._outBuffer);

  /// 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(idl_model.FieldType type, bool builder) {
    if (type.isList) {
      if (builder) {
        idl_model.FieldType elementType =
            idl_model.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(idl_model.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;
    }
  }

  /// Return the nullable [encodedType] of the [type].
  String encodedType2(idl_model.FieldType type) {
    return encodedType(type) + '?';
  }

  /// 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 Function() 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);
    }
  }

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

  List<String> _computeVariants(idl_model.ClassDeclaration cls) {
    var allVariants = <String>{};
    for (var field in cls.fields) {
      var logicalFields = field.logicalProperties?.values;
      if (logicalFields != null) {
        for (var logicalField in logicalFields) {
          allVariants.addAll(logicalField.variants);
        }
      }
    }
    return allVariants.toList()..sort();
  }

  bool _isNullable(idl_model.FieldType type) {
    return !type.isList && _idl.classes.containsKey(type.typeName);
  }

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

class _BuilderGenerator extends _BaseGenerator {
  final idl_model.ClassDeclaration cls;
  List<String> constructorParams = <String>[];

  _BuilderGenerator(idl_model.Idl idl, StringBuffer outBuffer, this.cls)
      : super(idl, outBuffer);

  String get builderName => name + 'Builder';

  String get name => cls.name;

  void generate() {
    String mixinName = '_${name}Mixin';
    var implementsClause =
        cls.isDeprecated ? '' : ' implements ${idlPrefix(name)}';
    out('class $builderName extends Object with $mixinName$implementsClause {');
    indent(() {
      _generateFields();
      _generateGettersSetters();
      _generateConstructors();
      _generateFlushInformative();
      _generateCollectApiSignature();
      _generateToBuffer();
      _generateFinish();
    });
    out('}');
  }

  void _generateCollectApiSignature() {
    out();
    out('/// Accumulate non-[informative] data into [signature].');
    out('void collectApiSignature(api_sig.ApiSignature signature) {');

    void writeField(String name, idl_model.FieldType type, bool isInformative) {
      if (isInformative) {
        return;
      }
      String ref = 'this.$name';
      if (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(type.typeName, 'x', false);
          });
          out('}');
        });
        out('}');
      } else {
        _generateSignatureCall(type.typeName, ref, true);
      }
    }

    indent(() {
      List<idl_model.FieldDeclaration> sortedFields = cls.fields.toList()
        ..sort((idl_model.FieldDeclaration a, idl_model.FieldDeclaration b) =>
            a.id.compareTo(b.id));
      if (cls.variantField != null) {
        var firstVariant = true;
        for (var variant in _computeVariants(cls)) {
          if (firstVariant) {
            firstVariant = false;
          } else {
            out('else');
          }
          out('if (${cls.variantField} == idl.$variant) {');
          indent(() {
            for (var field in sortedFields) {
              var logicalProperties = field.logicalProperties;
              if (logicalProperties != null) {
                for (var logicalName in logicalProperties.keys) {
                  var logicalProperty = logicalProperties[logicalName];
                  if (logicalProperty.variants.contains(variant)) {
                    writeField(
                      logicalName,
                      field.type,
                      logicalProperty.isInformative,
                    );
                  }
                }
              } else {
                writeField(field.name, field.type, field.isInformative);
              }
            }
          });
          out('}');
        }
      } else {
        for (idl_model.FieldDeclaration field in sortedFields) {
          writeField('_${field.name}', field.type, field.isInformative);
        }
      }
    });
    out('}');
  }

  void _generateConstructors() {
    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.logicalProperties != null) {
            for (var logicalName in field.logicalProperties.keys) {
              var logicalProperty = field.logicalProperties[logicalName];
              if (logicalProperty.variants.contains(variant)) {
                out('${encodedType2(field.type)} $logicalName,');
              }
            }
          }
        }

        out('}) : ');

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

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

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

  void _generateFields() {
    for (idl_model.FieldDeclaration field in cls.fields) {
      String fieldName = field.name;
      idl_model.FieldType type = field.type;
      String typeStr = encodedType2(type);
      out('$typeStr _$fieldName;');
    }
  }

  void _generateFinish() {
    out();
    out('fb.Offset finish(fb.Builder fbBuilder) {');
    indent(() {
      // Write objects and remember Offset(s).
      for (idl_model.FieldDeclaration field in cls.fields) {
        idl_model.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 (idl_model.FieldDeclaration field in cls.fields) {
        idl_model.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 (idl_model.FieldDeclaration field in cls.fields) {
        int index = field.id;
        idl_model.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 UnimplementedError('Writing type ${fieldType.typeName}');
        }
        out('if ($condition) {');
        indent(() {
          out(writeCode);
        });
        out('}');
      }
      out('return fbBuilder.endTable();');
    });
    out('}');
  }

  void _generateFlushInformative() {
    out();
    out('/// Flush [informative] data recursively.');
    out('void flushInformative() {');

    void writeField(String name, idl_model.FieldType type, bool isInformative) {
      if (isInformative) {
        out('$name = null;');
      } else if (_idl.classes.containsKey(type.typeName)) {
        if (type.isList) {
          out('$name?.forEach((b) => b.flushInformative());');
        } else {
          out('$name?.flushInformative();');
        }
      }
    }

    indent(() {
      if (cls.variantField != null) {
        var firstVariant = true;
        for (var variant in _computeVariants(cls)) {
          if (firstVariant) {
            firstVariant = false;
          } else {
            out('else');
          }
          out('if (${cls.variantField} == idl.$variant) {');
          indent(() {
            for (var field in cls.fields) {
              var logicalProperties = field.logicalProperties;
              if (logicalProperties != null) {
                for (var logicalName in logicalProperties.keys) {
                  var logicalProperty = logicalProperties[logicalName];
                  if (logicalProperty.variants.contains(variant)) {
                    writeField(
                      logicalName,
                      field.type,
                      logicalProperty.isInformative,
                    );
                  }
                }
              } else {
                writeField(field.name, field.type, field.isInformative);
              }
            }
          });
          out('}');
        }
      } else {
        for (idl_model.FieldDeclaration field in cls.fields) {
          writeField('_${field.name}', field.type, field.isInformative);
        }
      }
    });
    out('}');
  }

  void _generateGettersSetters() {
    for (idl_model.FieldDeclaration field in cls.allFields) {
      String fieldName = field.name;
      idl_model.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 => ${_BaseGenerator._throwDeprecated};');
      } else {
        if (field.logicalProperties != null) {
          for (var logicalName in field.logicalProperties.keys) {
            var logicalProperty = field.logicalProperties[logicalName];
            out('@override');
            out('$typeStr get $logicalName {');
            indent(() {
              out(_variantAssertStatement(cls, logicalProperty));
              out('return _${field.name}$defSuffix;');
            });
            out('}');
            out();
          }
        } else {
          out('@override');
          var nn = _isNullable(field.type) ? '?' : '';
          out('$typeStr$nn get $fieldName => _$fieldName$defSuffix;');
        }
        out();

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

        outDoc(field.documentation);

        if (field.logicalProperties != null) {
          for (var logicalName in field.logicalProperties.keys) {
            var logicalProperty = field.logicalProperties[logicalName];
            out('set $logicalName($typeStr value) {');
            indent(() {
              out(_variantAssertStatement(cls, logicalProperty));
              _generateNonNegativeInt(fieldType);
              out('_variantField_${field.id} = value;');
            });
            out('}');
            out();
          }
        } else {
          var nn = _isNullable(field.type) ? '?' : '';
          out('set $fieldName($typeStr$nn value) {');
          indent(() {
            _generateNonNegativeInt(fieldType);
            out('this._$fieldName = value;');
          });
          out('}');
        }
      }
    }
  }

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

  /// 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 {
        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";
      }
    }
  }

  void _generateToBuffer() {
    if (cls.isTopLevel) {
      out();
      out('List<int> toBuffer() {');
      indent(() {
        out('fb.Builder fbBuilder = fb.Builder();');
        String fileId =
            cls.fileIdentifier == null ? '' : ', ${quoted(cls.fileIdentifier)}';
        out('return fbBuilder.finish(finish(fbBuilder)$fileId);');
      });
      out('}');
    }
  }
}

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

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

  _CodeGenerator(String idlPath) {
    // Parse the input "IDL" file.
    File idlFile = File(idlPath);
    String idlText =
        idlFile.readAsStringSync().replaceAll(RegExp('\r\n?'), '\n');
    // Extract a description of the IDL and make sure it is valid.
    var startingToken = scanString(idlText, includeComments: true).tokens;
    var listener = MiniAstBuilder();
    var parser = 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, idl_model.ClassDeclaration cls) {
      if (cls.fileIdentifier != null) {
        if (cls.fileIdentifier.length != 4) {
          throw Exception('$name: file identifier must be 4 characters');
        }
        for (int i = 0; i < cls.fileIdentifier.length; i++) {
          if (cls.fileIdentifier.codeUnitAt(i) >= 256) {
            throw Exception(
                '$name: file identifier must be encodable as Latin-1');
          }
        }
      }
      Map<int, String> idsUsed = <int, String>{};
      for (idl_model.FieldDeclaration field in cls.allFields) {
        String fieldName = field.name;
        idl_model.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 Exception(
                '$name.$fieldName: illegal type (list of ${type.typeName})');
          }
        }
        if (idsUsed.containsKey(field.id)) {
          throw 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 Exception('$name: no field uses id $i');
        }
      }
    });
  }

  /// Process the AST in [idlParsed] and store the resulting semantic model in
  /// [_idl].  Also perform some error checking.
  void extractIdl(CompilationUnit idlParsed) {
    _idl = idl_model.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 Exception(
                    'Class `$clsName`: TopLevel argument must be a string'
                    ' literal');
              }
            } else if (annotation.arguments.isNotEmpty) {
              throw 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 Exception(
                  'Class `$clsName`: @Variant argument must be a string literal',
                );
              }
            } else if (annotation.arguments.isNotEmpty) {
              throw Exception(
                'Class `$clsName`: @Variant requires 1 argument',
              );
            }
          }
        }
        idl_model.ClassDeclaration cls = idl_model.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 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 Exception('Unexpected class member `$classMember`');
          }
        }
      } else if (decl is EnumDeclaration) {
        String doc = _getNodeDoc(decl);
        idl_model.EnumDeclaration enm =
            idl_model.EnumDeclaration(doc, decl.name);
        _idl.enums[enm.name] = enm;
        for (EnumConstantDeclaration constDecl in decl.constants) {
          String doc = _getNodeDoc(constDecl);
          enm.values.add(idl_model.EnumValueDeclaration(doc, constDecl.name));
        }
      } else {
        throw Exception('Unexpected declaration `$decl`');
      }
    }
  }

  /// Entry point to the code generator when generating the "format.fbs" file.
  void generateFlatBufferSchema() {
    outputHeader();
    _FlatBufferSchemaGenerator(_idl, _outBuffer).generate();
  }

  /// Entry point to the code generator when generating the "format.dart" file.
  void generateFormatCode() {
    outputHeader();
    out("// The generator sometimes generates unnecessary 'this' references.");
    out('// ignore_for_file: unnecessary_this');
    out();
    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 (idl_model.EnumDeclaration enum_ in _idl.enums.values) {
      _EnumReaderGenerator(_idl, _outBuffer, enum_).generate();
      out();
    }
    for (idl_model.ClassDeclaration cls in _idl.classes.values) {
      if (!cls.isDeprecated) {
        _BuilderGenerator(_idl, _outBuffer, cls).generate();
        out();
      }
      if (cls.isTopLevel) {
        _ReaderGenerator(_idl, _outBuffer, cls).generateReaderFunction();
        out();
      }
      if (!cls.isDeprecated) {
        _ReaderGenerator(_idl, _outBuffer, cls).generateReader();
        out();
        _ImplGenerator(_idl, _outBuffer, cls).generate();
        out();
        _MixinGenerator(_idl, _outBuffer, cls).generate();
        out();
      }
    }
  }

  /// Add the string [s] to the output as a single line.
  void out([String s = '']) {
    _outBuffer.writeln(s);
  }

  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();
  }

  void _addFieldForGetter(
    idl_model.ClassDeclaration cls,
    MethodDeclaration getter,
  ) {
    var desc = '${cls.name}.${getter.name}';
    if (getter.returnType == null) {
      throw 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 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 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 Exception(
            '@Id argument must be an integer literal ($desc)',
          );
        }
      } else if (annotation.name == 'deprecated') {
        if (annotation.arguments != null) {
          throw 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 Exception('Missing @id annotation ($desc)');
    }

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

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

        var map = existingField.logicalProperties;
        for (var variant in variants) {
          for (var logicalName in map.keys) {
            if (map[logicalName].variants.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}',
          );
        }

        if (map[getter.name] != null) {
          throw Exception(
            '$desc: logical property ${getter.name} is already used',
          );
        }

        map[getter.name] = idl_model.LogicalProperty(
          isDeprecated: isDeprecated,
          isInformative: isInformative,
          variants: variants,
        );
        return;
      } else {
        name = 'variantField_$id';
        logicalProperties = <String, idl_model.LogicalProperty>{
          getter.name: idl_model.LogicalProperty(
            isDeprecated: isDeprecated,
            isInformative: isInformative,
            variants: variants,
          ),
        };
      }
    }

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

  /// 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;
  }
}

class _EnumReaderGenerator extends _BaseGenerator {
  final idl_model.EnumDeclaration enum_;

  _EnumReaderGenerator(idl_model.Idl idl, StringBuffer outBuffer, this.enum_)
      : super(idl, outBuffer);

  void generate() {
    String name = enum_.name;
    String readerName = '_${name}Reader';
    String count = '${idlPrefix(name)}.values.length';
    String def = '${idlPrefix(name)}.${enum_.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('}');
  }
}

class _FlatBufferSchemaGenerator extends _BaseGenerator {
  _FlatBufferSchemaGenerator(idl_model.Idl idl, StringBuffer outBuffer)
      : super(idl, outBuffer);

  void generate() {
    for (idl_model.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++) {
          idl_model.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 (idl_model.ClassDeclaration cls in _idl.classes.values) {
      out();
      outDoc(cls.documentation);
      out('table ${cls.name} {');
      indent(() {
        for (int i = 0; i < cls.allFields.length; i++) {
          idl_model.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.
    idl_model.ClassDeclaration rootType = _idl.classes['PackageBundle'];
    out('root_type ${rootType.name};');
    if (rootType.fileIdentifier != null) {
      out();
      out('file_identifier ${quoted(rootType.fileIdentifier)};');
    }
  }

  /// Generate a string representing the FlatBuffer schema type which should be
  /// used to represent [type].
  String _fbsType(idl_model.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;
    }
  }
}

class _ImplGenerator extends _BaseGenerator {
  final idl_model.ClassDeclaration cls;

  _ImplGenerator(idl_model.Idl idl, StringBuffer outBuffer, this.cls)
      : super(idl, outBuffer);

  void generate() {
    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 (idl_model.FieldDeclaration field in cls.fields) {
        String returnType = _dartType(field.type);
        String fieldName = field.name;
        out('$returnType? _$fieldName;');
      }
      // Write getters.
      for (idl_model.FieldDeclaration field in cls.allFields) {
        int index = field.id;
        String fieldName = field.name;
        idl_model.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 = 'fb.StringReader()';
            readCode = 'const fb.ListReader<String>($itemCode)';
          } else if (_idl.classes.containsKey(typeName)) {
            String itemCode = '_${typeName}Reader()';
            readCode = 'const fb.ListReader<${idlPrefix(typeName)}>($itemCode)';
          } else {
            assert(_idl.enums.containsKey(typeName));
            String itemCode = '_${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 => ${_BaseGenerator._throwDeprecated};');
        } else {
          if (field.logicalProperties != null) {
            for (var logicalName in field.logicalProperties.keys) {
              var logicalProperty = field.logicalProperties[logicalName];
              out('@override');
              out('$returnType get $logicalName {');
              indent(() {
                out(_variantAssertStatement(cls, logicalProperty));
                String readExpr =
                    '$readCode.vTableGet(_bc, _bcOffset, $index, $def)';
                out('return _$fieldName ??= $readExpr;');
              });
              out('}');
              out();
            }
          } else {
            out('@override');
            if (_isNullable(type)) {
              out('$returnType? get $fieldName {');
            } else {
              out('$returnType get $fieldName {');
            }
            indent(() {
              String readExpr;
              if (_isNullable(type)) {
                readExpr = '$readCode.vTableGetOrNull(_bc, _bcOffset, $index)';
              } else {
                readExpr = '$readCode.vTableGet(_bc, _bcOffset, $index, $def)';
              }
              out('return _$fieldName ??= $readExpr;');
            });
            out('}');
          }
        }
      }
    });
    out('}');
  }

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

class _MixinGenerator extends _BaseGenerator {
  final idl_model.ClassDeclaration cls;

  _MixinGenerator(idl_model.Idl idl, StringBuffer outBuffer, this.cls)
      : super(idl, outBuffer);

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

      String jsonStore(
          idl_model.FieldType type, String name, String localName) {
        _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 = localName;
        } else if (type.isList) {
          convertField = '$localName.map((_value) =>'
              ' ${convertItem('_value')}).toList()';
        } else {
          convertField = convertItem(localName);
        }
        return '_result[${quoted(name)}] = $convertField';
      }

      void writeConditionalStatement(String condition, String statement) {
        out('if ($condition) {');
        out('  $statement;');
        out('}');
      }

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

        if (cls.variantField != null) {
          indent(() {
            for (idl_model.FieldDeclaration field in cls.fields) {
              if (field.logicalProperties == null) {
                var localName = 'local_${field.name}';
                out('var $localName = ${field.name};');
                var condition = jsonCondition(field.type, localName);
                var storeField = jsonStore(field.type, field.name, localName);
                writeConditionalStatement(condition, storeField);
              }
            }
            for (var variant in _computeVariants(cls)) {
              out('if (${cls.variantField} == idl.$variant) {');
              indent(() {
                for (idl_model.FieldDeclaration field in cls.fields) {
                  var logicalProperties = field.logicalProperties;
                  if (logicalProperties != null) {
                    for (var logicalName in logicalProperties.keys) {
                      var logicalProperty = logicalProperties[logicalName];
                      if (logicalProperty.variants.contains(variant)) {
                        var localName = 'local_${field.name}';
                        out('var $localName = ${field.name};');
                        var condition = jsonCondition(field.type, localName);
                        var storeField =
                            jsonStore(field.type, logicalName, localName);
                        writeConditionalStatement(condition, storeField);
                      }
                    }
                  }
                }
              });
              out('}');
            }
          });
        } else {
          indent(() {
            for (idl_model.FieldDeclaration field in cls.fields) {
              var localName = 'local_${field.name}';
              out('var $localName = ${field.name};');
              String condition = jsonCondition(field.type, localName);
              String storeField = jsonStore(field.type, field.name, localName);
              writeConditionalStatement(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 (idl_model.FieldDeclaration field in cls.fields) {
              if (field.logicalProperties != null) {
                for (var logicalName in field.logicalProperties.keys) {
                  var logicalProperty = field.logicalProperties[logicalName];
                  if (logicalProperty.variants.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 (idl_model.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('}');
  }
}

class _ReaderGenerator extends _BaseGenerator {
  final idl_model.ClassDeclaration cls;

  _ReaderGenerator(idl_model.Idl idl, StringBuffer outBuffer, this.cls)
      : super(idl, outBuffer);

  void generateReader() {
    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) => $implName(bc, offset);');
    });
    out('}');
  }

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