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

library dart2js.serialization.util;

import '../common.dart';
import '../constants/expressions.dart';
import '../elements/resolution_types.dart';
import '../diagnostics/messages.dart';
import '../elements/elements.dart';
import '../elements/modelx.dart' show WrappedMessage;
import '../elements/names.dart';
import '../elements/operators.dart';
import '../resolution/access_semantics.dart';
import '../resolution/send_structure.dart';
import '../universe/call_structure.dart';
import '../universe/selector.dart';
import 'keys.dart';
import 'serialization.dart';

/// Serialize [name] into [encoder].
void serializeName(Name name, ObjectEncoder encoder) {
  encoder.setString(Key.NAME, name.text);
  encoder.setBool(Key.IS_SETTER, name.isSetter);
  if (name.library != null) {
    LibraryElement library = name.library;
    encoder.setElement(Key.LIBRARY, library);
  }
}

/// Deserialize a [Name] from [decoder].
Name deserializeName(ObjectDecoder decoder) {
  String name = decoder.getString(Key.NAME);
  bool isSetter = decoder.getBool(Key.IS_SETTER);
  LibraryElement library = decoder.getElement(Key.LIBRARY, isOptional: true);
  return new Name(name, library, isSetter: isSetter);
}

/// Serialize [callStructure] into [encoder].
void serializeCallStructure(
    CallStructure callStructure, ObjectEncoder encoder) {
  encoder.setInt(Key.ARGUMENTS, callStructure.argumentCount);
  encoder.setStrings(Key.NAMED_ARGUMENTS, callStructure.namedArguments);
}

/// Serialize [selector] into [encoder].
void serializeSelector(Selector selector, ObjectEncoder encoder) {
  encoder.setEnum(Key.KIND, selector.kind);
  serializeCallStructure(selector.callStructure, encoder);
  serializeName(selector.memberName, encoder);
}

/// Deserialize a [CallStructure] from [decoder].
CallStructure deserializeCallStructure(ObjectDecoder decoder) {
  int argumentCount = decoder.getInt(Key.ARGUMENTS);
  List<String> namedArguments =
      decoder.getStrings(Key.NAMED_ARGUMENTS, isOptional: true);
  return new CallStructure(argumentCount, namedArguments);
}

/// Deserialize a [Selector] from [decoder].
Selector deserializeSelector(ObjectDecoder decoder) {
  SelectorKind kind = decoder.getEnum(Key.KIND, SelectorKind.values);
  CallStructure callStructure = deserializeCallStructure(decoder);
  return new Selector(kind, deserializeName(decoder), callStructure);
}

/// Serialize [sendStructure] into [encoder].
void serializeSendStructure(
    SendStructure sendStructure, ObjectEncoder encoder) {
  encoder.setEnum(Key.KIND, sendStructure.kind);
  switch (sendStructure.kind) {
    case SendStructureKind.IF_NULL:
    case SendStructureKind.LOGICAL_AND:
    case SendStructureKind.LOGICAL_OR:
    case SendStructureKind.NOT:
    case SendStructureKind.INVALID_UNARY:
    case SendStructureKind.INVALID_BINARY:
      // No additional properties.
      break;
    case SendStructureKind.IS:
      IsStructure structure = sendStructure;
      encoder.setType(Key.TYPE, structure.type);
      break;
    case SendStructureKind.IS_NOT:
      IsNotStructure structure = sendStructure;
      encoder.setType(Key.TYPE, structure.type);
      break;
    case SendStructureKind.AS:
      AsStructure structure = sendStructure;
      encoder.setType(Key.TYPE, structure.type);
      break;
    case SendStructureKind.INVOKE:
      InvokeStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      serializeSelector(structure.selector, encoder.createObject(Key.SELECTOR));
      break;
    case SendStructureKind.INCOMPATIBLE_INVOKE:
      IncompatibleInvokeStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      serializeSelector(structure.selector, encoder.createObject(Key.SELECTOR));
      break;
    case SendStructureKind.GET:
      GetStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      break;
    case SendStructureKind.SET:
      SetStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      break;
    case SendStructureKind.UNARY:
      UnaryStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
      break;
    case SendStructureKind.INDEX:
      IndexStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      break;
    case SendStructureKind.EQUALS:
      EqualsStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      break;
    case SendStructureKind.NOT_EQUALS:
      NotEqualsStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      break;
    case SendStructureKind.BINARY:
      BinaryStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
      break;
    case SendStructureKind.INDEX_SET:
      IndexSetStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      break;
    case SendStructureKind.INDEX_PREFIX:
      IndexPrefixStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
      break;
    case SendStructureKind.INDEX_POSTFIX:
      IndexPostfixStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
      break;
    case SendStructureKind.COMPOUND:
      CompoundStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
      break;
    case SendStructureKind.SET_IF_NULL:
      SetIfNullStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      break;
    case SendStructureKind.COMPOUND_INDEX_SET:
      CompoundIndexSetStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
      break;
    case SendStructureKind.INDEX_SET_IF_NULL:
      IndexSetIfNullStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      break;
    case SendStructureKind.PREFIX:
      PrefixStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
      break;
    case SendStructureKind.POSTFIX:
      PostfixStructure structure = sendStructure;
      serializeAccessSemantics(
          structure.semantics, encoder.createObject(Key.SEMANTICS));
      encoder.setEnum(Key.OPERATOR, structure.operator.kind);
      break;
    case SendStructureKind.DEFERRED_PREFIX:
      DeferredPrefixStructure structure = sendStructure;
      encoder.setElement(Key.PREFIX, structure.prefix);
      serializeSendStructure(
          structure.sendStructure, encoder.createObject(Key.SEND_STRUCTURE));
      break;
  }
}

/// Deserialize a [SendStructure] from [decoder].
// ignore: MISSING_RETURN
SendStructure deserializeSendStructure(ObjectDecoder decoder) {
  SendStructureKind kind = decoder.getEnum(Key.KIND, SendStructureKind.values);
  switch (kind) {
    case SendStructureKind.IF_NULL:
      return const IfNullStructure();
    case SendStructureKind.LOGICAL_AND:
      return const LogicalAndStructure();
    case SendStructureKind.LOGICAL_OR:
      return const LogicalOrStructure();
    case SendStructureKind.IS:
      return new IsStructure(decoder.getType(Key.TYPE));
    case SendStructureKind.IS_NOT:
      return new IsNotStructure(decoder.getType(Key.TYPE));
    case SendStructureKind.AS:
      return new AsStructure(decoder.getType(Key.TYPE));
    case SendStructureKind.INVOKE:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      Selector selector = deserializeSelector(decoder.getObject(Key.SELECTOR));
      return new InvokeStructure(semantics, selector);
    case SendStructureKind.INCOMPATIBLE_INVOKE:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      Selector selector = deserializeSelector(decoder.getObject(Key.SELECTOR));
      return new IncompatibleInvokeStructure(semantics, selector);
    case SendStructureKind.GET:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new GetStructure(semantics);
    case SendStructureKind.SET:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new SetStructure(semantics);
    case SendStructureKind.NOT:
      return const NotStructure();
    case SendStructureKind.UNARY:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new UnaryStructure(
          semantics,
          UnaryOperator.fromKind(
              decoder.getEnum(Key.OPERATOR, UnaryOperatorKind.values)));
    case SendStructureKind.INVALID_UNARY:
      return new InvalidUnaryStructure();
    case SendStructureKind.INDEX:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new IndexStructure(semantics);
    case SendStructureKind.EQUALS:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new EqualsStructure(semantics);
    case SendStructureKind.NOT_EQUALS:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new NotEqualsStructure(semantics);
    case SendStructureKind.BINARY:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new BinaryStructure(
          semantics,
          BinaryOperator.fromKind(
              decoder.getEnum(Key.OPERATOR, BinaryOperatorKind.values)));
    case SendStructureKind.INVALID_BINARY:
      return const InvalidBinaryStructure();
    case SendStructureKind.INDEX_SET:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new IndexSetStructure(semantics);
    case SendStructureKind.INDEX_PREFIX:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new IndexPrefixStructure(
          semantics,
          IncDecOperator.fromKind(
              decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
    case SendStructureKind.INDEX_POSTFIX:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new IndexPostfixStructure(
          semantics,
          IncDecOperator.fromKind(
              decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
    case SendStructureKind.COMPOUND:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new CompoundStructure(
          semantics,
          AssignmentOperator.fromKind(
              decoder.getEnum(Key.OPERATOR, AssignmentOperatorKind.values)));
    case SendStructureKind.SET_IF_NULL:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new SetIfNullStructure(semantics);
    case SendStructureKind.COMPOUND_INDEX_SET:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new CompoundIndexSetStructure(
          semantics,
          AssignmentOperator.fromKind(
              decoder.getEnum(Key.OPERATOR, AssignmentOperatorKind.values)));
    case SendStructureKind.INDEX_SET_IF_NULL:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new IndexSetIfNullStructure(semantics);
    case SendStructureKind.PREFIX:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new PrefixStructure(
          semantics,
          IncDecOperator.fromKind(
              decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
    case SendStructureKind.POSTFIX:
      AccessSemantics semantics =
          deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
      return new PostfixStructure(
          semantics,
          IncDecOperator.fromKind(
              decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
    case SendStructureKind.DEFERRED_PREFIX:
      PrefixElement prefix = decoder.getElement(Key.PREFIX);
      SendStructure sendStructure =
          deserializeSendStructure(decoder.getObject(Key.SEND_STRUCTURE));
      return new DeferredPrefixStructure(prefix, sendStructure);
  }
}

/// Serialize [newStructure] into [encoder].
void serializeNewStructure(NewStructure newStructure, ObjectEncoder encoder) {
  encoder.setEnum(Key.KIND, newStructure.kind);
  switch (newStructure.kind) {
    case NewStructureKind.NEW_INVOKE:
      NewInvokeStructure structure = newStructure;
      encoder.setEnum(Key.SUB_KIND, structure.semantics.kind);
      encoder.setElement(Key.ELEMENT, structure.semantics.element);
      encoder.setType(Key.TYPE, structure.semantics.type);
      serializeSelector(structure.selector, encoder.createObject(Key.SELECTOR));
      break;
    case NewStructureKind.CONST_INVOKE:
      ConstInvokeStructure structure = newStructure;
      encoder.setEnum(Key.SUB_KIND, structure.constantInvokeKind);
      encoder.setConstant(Key.CONSTANT, structure.constant);
      break;
    case NewStructureKind.LATE_CONST:
      throw new UnsupportedError(
          'Unsupported NewStructure kind ${newStructure.kind}.');
  }
}

/// Deserialize a [NewStructure] from [decoder].
// ignore: MISSING_RETURN
NewStructure deserializeNewStructure(ObjectDecoder decoder) {
  NewStructureKind kind = decoder.getEnum(Key.KIND, NewStructureKind.values);
  switch (kind) {
    case NewStructureKind.NEW_INVOKE:
      ConstructorAccessKind constructorAccessKind =
          decoder.getEnum(Key.SUB_KIND, ConstructorAccessKind.values);
      Element element = decoder.getElement(Key.ELEMENT);
      ResolutionDartType type = decoder.getType(Key.TYPE);
      ConstructorAccessSemantics semantics =
          new ConstructorAccessSemantics(constructorAccessKind, element, type);
      Selector selector = deserializeSelector(decoder.getObject(Key.SELECTOR));
      return new NewInvokeStructure(semantics, selector);

    case NewStructureKind.CONST_INVOKE:
      ConstantInvokeKind constantInvokeKind =
          decoder.getEnum(Key.SUB_KIND, ConstantInvokeKind.values);
      ConstantExpression constant = decoder.getConstant(Key.CONSTANT);
      return new ConstInvokeStructure(constantInvokeKind, constant);
    case NewStructureKind.LATE_CONST:
      throw new UnsupportedError('Unsupported NewStructure kind $kind.');
  }
}

/// Serialize [semantics] into [encoder].
void serializeAccessSemantics(
    AccessSemantics semantics, ObjectEncoder encoder) {
  encoder.setEnum(Key.KIND, semantics.kind);
  switch (semantics.kind) {
    case AccessKind.EXPRESSION:
    case AccessKind.THIS:
      // No additional properties.
      break;
    case AccessKind.THIS_PROPERTY:
    case AccessKind.DYNAMIC_PROPERTY:
    case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
      serializeName(semantics.name, encoder);
      break;
    case AccessKind.CLASS_TYPE_LITERAL:
    case AccessKind.TYPEDEF_TYPE_LITERAL:
    case AccessKind.DYNAMIC_TYPE_LITERAL:
      encoder.setConstant(Key.CONSTANT, semantics.constant);
      break;
    case AccessKind.LOCAL_FUNCTION:
    case AccessKind.LOCAL_VARIABLE:
    case AccessKind.FINAL_LOCAL_VARIABLE:
    case AccessKind.PARAMETER:
    case AccessKind.FINAL_PARAMETER:
    case AccessKind.STATIC_FIELD:
    case AccessKind.FINAL_STATIC_FIELD:
    case AccessKind.STATIC_METHOD:
    case AccessKind.STATIC_GETTER:
    case AccessKind.STATIC_SETTER:
    case AccessKind.TOPLEVEL_FIELD:
    case AccessKind.FINAL_TOPLEVEL_FIELD:
    case AccessKind.TOPLEVEL_METHOD:
    case AccessKind.TOPLEVEL_GETTER:
    case AccessKind.TOPLEVEL_SETTER:
    case AccessKind.SUPER_FIELD:
    case AccessKind.SUPER_FINAL_FIELD:
    case AccessKind.SUPER_METHOD:
    case AccessKind.SUPER_GETTER:
    case AccessKind.SUPER_SETTER:
    case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
    case AccessKind.UNRESOLVED:
    case AccessKind.UNRESOLVED_SUPER:
    case AccessKind.INVALID:
      encoder.setElement(Key.ELEMENT, semantics.element);
      break;
    case AccessKind.COMPOUND:
      CompoundAccessSemantics compoundAccess = semantics;
      encoder.setEnum(Key.SUB_KIND, compoundAccess.compoundAccessKind);
      encoder.setElement(Key.GETTER, semantics.getter);
      encoder.setElement(Key.SETTER, semantics.setter);
      break;
    case AccessKind.CONSTANT:
      throw new UnsupportedError('Unsupported access kind: ${semantics.kind}');
  }
}

/// Deserialize a [AccessSemantics] from [decoder].
// ignore: MISSING_RETURN
AccessSemantics deserializeAccessSemantics(ObjectDecoder decoder) {
  AccessKind kind = decoder.getEnum(Key.KIND, AccessKind.values);
  switch (kind) {
    case AccessKind.EXPRESSION:
      return const DynamicAccess.expression();
    case AccessKind.THIS:
      return const DynamicAccess.thisAccess();
    case AccessKind.THIS_PROPERTY:
      return new DynamicAccess.thisProperty(deserializeName(decoder));
    case AccessKind.DYNAMIC_PROPERTY:
      return new DynamicAccess.dynamicProperty(deserializeName(decoder));
    case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
      return new DynamicAccess.ifNotNullProperty(deserializeName(decoder));
    case AccessKind.CLASS_TYPE_LITERAL:
    case AccessKind.TYPEDEF_TYPE_LITERAL:
    case AccessKind.DYNAMIC_TYPE_LITERAL:
      return new ConstantAccess(kind, decoder.getConstant(Key.CONSTANT));

    case AccessKind.LOCAL_FUNCTION:
    case AccessKind.LOCAL_VARIABLE:
    case AccessKind.FINAL_LOCAL_VARIABLE:
    case AccessKind.PARAMETER:
    case AccessKind.FINAL_PARAMETER:
    case AccessKind.STATIC_FIELD:
    case AccessKind.FINAL_STATIC_FIELD:
    case AccessKind.STATIC_METHOD:
    case AccessKind.STATIC_GETTER:
    case AccessKind.STATIC_SETTER:
    case AccessKind.TOPLEVEL_FIELD:
    case AccessKind.FINAL_TOPLEVEL_FIELD:
    case AccessKind.TOPLEVEL_METHOD:
    case AccessKind.TOPLEVEL_GETTER:
    case AccessKind.TOPLEVEL_SETTER:
    case AccessKind.SUPER_FIELD:
    case AccessKind.SUPER_FINAL_FIELD:
    case AccessKind.SUPER_METHOD:
    case AccessKind.SUPER_GETTER:
    case AccessKind.SUPER_SETTER:
    case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
    case AccessKind.UNRESOLVED:
    case AccessKind.UNRESOLVED_SUPER:
    case AccessKind.INVALID:
      return new StaticAccess.internal(kind, decoder.getElement(Key.ELEMENT));

    case AccessKind.COMPOUND:
      CompoundAccessKind compoundAccessKind =
          decoder.getEnum(Key.SUB_KIND, CompoundAccessKind.values);
      Element getter = decoder.getElement(Key.GETTER);
      Element setter = decoder.getElement(Key.SETTER);
      return new CompoundAccessSemantics(compoundAccessKind, getter, setter);
    case AccessKind.CONSTANT:
      throw new UnsupportedError('Unsupported access kind: $kind');
  }
}

/// Serialize a reference from [context] to an [element] which might be a member
/// of an unnamed mixin application. If it is, [element] is by serialized
/// indirectly by name in the [nameKey] of [encoder], otherwise [element] is
/// serialized directly in [elementKey] in [encoder].
void serializeElementReference(Element context, Key elementKey, Key nameKey,
    ObjectEncoder encoder, Element element) {
  if (element.isGenerativeConstructor &&
      element.enclosingClass.isUnnamedMixinApplication) {
    assert(
        element.isConstructor,
        failedAt(
            element,
            "Unexpected reference of forwarding constructor "
            "${element} from $context."));
    encoder.setString(nameKey, element.name);
  } else {
    encoder.setElement(elementKey, element);
  }
}

/// Deserialize a reference from [context] to an [Element] which might be a
/// member of an unnamed mixin application. If it is, the [Element] is by
/// deserialized indirectly by name from [nameKey] in [decoder], otherwise
/// the [Element] is deserialized directly from [elementKey] in [encoder].
Element deserializeElementReference(
    Element context, Key elementKey, Key nameKey, ObjectDecoder decoder,
    {bool isOptional: false}) {
  Element element = decoder.getElement(elementKey, isOptional: true);
  if (element == null) {
    String elementName = decoder.getString(nameKey, isOptional: isOptional);
    if (elementName == null) {
      return null;
    }
    ClassElement cls;
    if (context is ClassElement) {
      assert(
          context.isNamedMixinApplication,
          failedAt(
              NO_LOCATION_SPANNABLE,
              "Unexpected reference of forwarding constructor "
              "'${elementName}' from $context."));
      cls = context;
    } else {
      assert(
          context.isConstructor,
          failedAt(
              NO_LOCATION_SPANNABLE,
              "Unexpected reference of forwarding constructor "
              "'${elementName}' from $context."));
      cls = context.enclosingClass;
    }
    ClassElement superclass = cls.superclass;
    element = superclass.lookupConstructor(elementName);
    assert(
        element != null,
        failedAt(
            NO_LOCATION_SPANNABLE,
            "Unresolved reference of forwarding constructor "
            "'${elementName}' from $context."));
  }
  return element;
}

void serializeMessageArguments(
    ObjectEncoder encoder, Key key, Map<String, dynamic> messageArguments) {
  if (messageArguments.isNotEmpty) {
    MapEncoder mapEncoder = encoder.createMap(Key.ARGUMENTS);
    messageArguments.forEach((String key, var value) {
      mapEncoder.setString(key, Message.convertToString(value));
    });
  }
}

Map<String, String> deserializeMessageArguments(
    ObjectDecoder decoder, Key key) {
  Map<String, String> arguments = <String, String>{};
  MapDecoder mapDecoder = decoder.getMap(key, isOptional: true);
  if (mapDecoder != null) {
    mapDecoder.forEachKey((String key) {
      arguments[key] = mapDecoder.getString(key);
    });
  }
  return arguments;
}

void serializeSourceSpan(ObjectEncoder encoder, SourceSpan sourceSpan) {
  encoder.setUri(Key.URI, sourceSpan.uri, sourceSpan.uri);
  encoder.setInt(Key.OFFSET, sourceSpan.begin);
  encoder.setInt(Key.LENGTH, sourceSpan.end - sourceSpan.begin);
}

SourceSpan deserializeSourceSpan(ObjectDecoder decoder) {
  Uri uri = decoder.getUri(Key.URI);
  int offset = decoder.getInt(Key.OFFSET);
  int length = decoder.getInt(Key.LENGTH);
  return new SourceSpan(uri, offset, offset + length);
}

void serializeWrappedMessage(
    ObjectEncoder encoder, Key key, WrappedMessage message) {
  ObjectEncoder object = encoder.createObject(key);
  if (message.sourceSpan != null) {
    serializeSourceSpan(
        object.createObject(Key.SOURCE_SPAN), message.sourceSpan);
  }
  object.setEnum(Key.KIND, message.messageKind);
  serializeMessageArguments(object, Key.ARGUMENTS, message.messageArguments);
}

WrappedMessage deserializeWrappedMessage(ObjectDecoder decoder, Key key) {
  ObjectDecoder object = decoder.getObject(key);
  SourceSpan sourceSpan;
  ObjectDecoder sourceSpanDecoder =
      object.getObject(Key.SOURCE_SPAN, isOptional: true);
  if (sourceSpanDecoder != null) {
    sourceSpan = deserializeSourceSpan(sourceSpanDecoder);
  }
  MessageKind messageKind = object.getEnum(Key.KIND, MessageKind.values);
  Map<String, dynamic> messageArguments =
      deserializeMessageArguments(object, Key.ARGUMENTS);
  return new WrappedMessage(sourceSpan, messageKind, messageArguments);
}
