anchor.diff:      }
     }
   
  +  /// 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('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 enum_ in _idl.enums.values) {
  +      _EnumReaderGenerator(_idl, _outBuffer, enum_).generate();
  +      out();
  +    }
  +    for (idlModel.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(
  +    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,
  +      ),
  +    );
  +  }
  +
  +  /// 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 idlModel.EnumDeclaration enum_;
  +
  +  _EnumReaderGenerator(idlModel.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(idlModel.Idl idl, StringBuffer outBuffer)
  +      : super(idl, outBuffer);
  +
  +  void generate() {
  +    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)};');
  +    }
  +  }
  +
     /// Generate a string representing the FlatBuffer schema type which should be
     /// used to represent [type].
  -  String fbsType(idlModel.FieldType type) {
  +  String _fbsType(idlModel.FieldType type) {
       String typeStr;
       switch (type.typeName) {
         case 'bool':
  
positive.code:       out();
        // Write cache fields.
        for (idlModel.FieldDeclaration field in cls.fields) {
          String returnType = dartType(field.type);
          String fieldName = field.name;
          out('$returnType _$fieldName;');
        }
  
negative.code:     out('}');
    }
  
    /// 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;
      }
    }
  }
  
  class _MixinGenerator extends _BaseGenerator {
    final idlModel.ClassDeclaration cls;
  
    _MixinGenerator(idlModel.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)} {');
  