// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:convert';
import 'dart:io';

import 'package:gen_keycodes/utils.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;

/// The data structure used to manage keyboard key entries.
///
/// The main constructor parses the given input data into the data structure.
///
/// The data structure can be also loaded and saved to JSON, with the
/// [KeyData.fromJson] constructor and [toJson] method, respectively.
class KeyData {
  /// Parses the input data given in from the various data source files,
  /// populating the data structure.
  ///
  /// None of the parameters may be null.
  KeyData(
    String chromiumHidCodes,
    String androidKeyboardLayout,
    String androidKeyCodeHeader,
    String androidNameMap,
    String glfwKeyCodeHeader,
    String glfwNameMap,
    String gtkKeyCodeHeader,
    String gtkNameMap,
    String windowsKeyCodeHeader,
    String windowsNameMap,
  )   : assert(chromiumHidCodes != null),
        assert(androidKeyboardLayout != null),
        assert(androidKeyCodeHeader != null),
        assert(androidNameMap != null),
        assert(glfwKeyCodeHeader != null),
        assert(glfwNameMap != null),
        assert(gtkKeyCodeHeader != null),
        assert(gtkNameMap != null),
        assert(windowsKeyCodeHeader != null),
        assert(windowsNameMap != null) {
    _nameToAndroidScanCodes = _readAndroidScanCodes(androidKeyboardLayout);
    _nameToAndroidKeyCode = _readAndroidKeyCodes(androidKeyCodeHeader);
    _nameToGlfwKeyCode = _readGlfwKeyCodes(glfwKeyCodeHeader);
    _nameToGtkKeyCode = _readGtkKeyCodes(gtkKeyCodeHeader);
    _nameToWindowsKeyCode = _readWindowsKeyCodes(windowsKeyCodeHeader);
    // Cast Android dom map
    final Map<String, List<dynamic>> dynamicAndroidNames = (json.decode(androidNameMap) as Map<String, dynamic>).cast<String, List<dynamic>>();
    _nameToAndroidName = dynamicAndroidNames.map<String, List<String>>((String key, List<dynamic> value) {
      return MapEntry<String, List<String>>(key, value.cast<String>());
    });
    // Cast GLFW dom map
    final Map<String, List<dynamic>> dynamicGlfwNames = (json.decode(glfwNameMap) as Map<String, dynamic>).cast<String, List<dynamic>>();
    _nameToGlfwName = dynamicGlfwNames.map<String, List<String>>((String key, List<dynamic> value) {
      return MapEntry<String, List<String>>(key, value.cast<String>());
    });
    // Cast GTK dom map
    final Map<String, List<dynamic>> dynamicGtkNames = (json.decode(gtkNameMap) as Map<String, dynamic>).cast<String, List<dynamic>>();
    _nameToGtkName = dynamicGtkNames.map<String, List<String>>((String key, List<dynamic> value) {
      return MapEntry<String, List<String>>(key, value.cast<String>());
    });
    // Cast Windows dom map
    final Map<String, List<dynamic>> dynamicWindowsNames = (json.decode(windowsNameMap) as Map<String, dynamic>).cast<String, List<dynamic>>();
    _nameToWindowsName = dynamicWindowsNames.map<String, List<String>>((String key, List<dynamic> value) {
      return MapEntry<String, List<String>>(key, value.cast<String>());
    });
    data = _readHidEntries(chromiumHidCodes);
  }

  /// Parses the given JSON data and populates the data structure from it.
  KeyData.fromJson(Map<String, dynamic> contentMap) {
    data = <Key>[
      for (final String key in contentMap.keys) Key.fromJsonMapEntry(key, contentMap[key] as Map<String, dynamic>),
    ];
  }

  /// Converts the data structure into a JSON structure that can be parsed by
  /// [KeyData.fromJson].
  Map<String, dynamic> toJson() {
    for (final Key entry in data) {
      // Android Key names
      entry.androidKeyNames = _nameToAndroidName[entry.constantName]?.cast<String>();
      if (entry.androidKeyNames != null && entry.androidKeyNames.isNotEmpty) {
        for (final String androidKeyName in entry.androidKeyNames) {
          if (_nameToAndroidKeyCode[androidKeyName] != null) {
            entry.androidKeyCodes ??= <int>[];
            entry.androidKeyCodes.add(_nameToAndroidKeyCode[androidKeyName]);
          }
          if (_nameToAndroidScanCodes[androidKeyName] != null && _nameToAndroidScanCodes[androidKeyName].isNotEmpty) {
            entry.androidScanCodes ??= <int>[];
            entry.androidScanCodes.addAll(_nameToAndroidScanCodes[androidKeyName]);
          }
        }
      }

      // GLFW key names
      entry.glfwKeyNames = _nameToGlfwName[entry.constantName]?.cast<String>();
      if (entry.glfwKeyNames != null && entry.glfwKeyNames.isNotEmpty) {
        for (final String glfwKeyName in entry.glfwKeyNames) {
          if (_nameToGlfwKeyCode[glfwKeyName] != null) {
            entry.glfwKeyCodes ??= <int>[];
            entry.glfwKeyCodes.add(_nameToGlfwKeyCode[glfwKeyName]);
          }
        }
      }

      // GTK key names
      entry.gtkKeyNames = _nameToGtkName[entry.constantName]?.cast<String>();
      if (entry.gtkKeyNames != null && entry.gtkKeyNames.isNotEmpty) {
        for (final String gtkKeyName in entry.gtkKeyNames) {
          if (_nameToGtkKeyCode[gtkKeyName] != null) {
            entry.gtkKeyCodes ??= <int>[];
            entry.gtkKeyCodes.add(_nameToGtkKeyCode[gtkKeyName]);
          }
        }
      }

      // Windows key names
      entry.windowsKeyNames = _nameToWindowsName[entry.constantName]?.cast<String>();
      if (entry.windowsKeyNames != null && entry.windowsKeyNames.isNotEmpty) {
        for (final String windowsKeyName in entry.windowsKeyNames) {
          if (_nameToWindowsKeyCode[windowsKeyName] != null) {
            entry.windowsKeyCodes ??= <int>[];
            entry.windowsKeyCodes.add(_nameToWindowsKeyCode[windowsKeyName]);
          }
        }
      }
    }

    final Map<String, dynamic> outputMap = <String, dynamic>{};
    for (final Key entry in data) {
      outputMap[entry.constantName] = entry.toJson();
    }
    return outputMap;
  }

  /// The list of keys.
  List<Key> data;

  /// The mapping from the Flutter name (e.g. "eject") to the Android name (e.g.
  /// "MEDIA_EJECT").
  ///
  /// Only populated if data is parsed from the source files, not if parsed from
  /// JSON.
  Map<String, List<String>> _nameToAndroidName;

  /// The mapping from the Flutter name (e.g. "eject") to the GLFW name (e.g.
  /// "GLFW_MEDIA_EJECT").
  ///
  /// Only populated if data is parsed from the source files, not if parsed from
  /// JSON.
  Map<String, List<String>> _nameToGlfwName;

  /// The mapping from the Flutter name (e.g. "eject") to the GTK name (e.g.
  /// "GDK_KEY_Eject").
  ///
  /// Only populated if data is parsed from the source files, not if parsed from
  /// JSON.
  Map<String, List<String>> _nameToGtkName;

  /// The mapping from the Android name (e.g. "MEDIA_EJECT") to the integer scan
  /// code (physical location) of the key.
  ///
  /// Only populated if data is parsed from the source files, not if parsed from
  /// JSON.
  Map<String, List<int>> _nameToAndroidScanCodes;

  /// The mapping from Android name (e.g. "MEDIA_EJECT") to the integer key code
  /// (logical meaning) of the key.
  ///
  /// Only populated if data is parsed from the source files, not if parsed from
  /// JSON.
  Map<String, int> _nameToAndroidKeyCode;

  /// The mapping from GLFW name (e.g. "GLFW_KEY_COMMA") to the integer key code
  /// (logical meaning) of the key.
  ///
  /// Only populated if data is parsed from the source files, not if parsed from
  /// JSON.
  Map<String, int> _nameToGlfwKeyCode;

  /// The mapping from GTK name (e.g. "GTK_KEY_comma") to the integer key code
  /// (logical meaning) of the key.
  ///
  /// Only populated if data is parsed from the source files, not if parsed from
  /// JSON.
  Map<String, int> _nameToGtkKeyCode;

  /// The mapping from Widows name (e.g. "RETURN") to the integer key code
  /// (logical meaning) of the key.
  ///
  /// Only populated if data is parsed from the source files, not if parsed from
  /// JSON.
  Map<String, int> _nameToWindowsKeyCode;

  /// The mapping from the Flutter name (e.g. "enter") to the Windows name (e.g.
  /// "RETURN").
  ///
  /// Only populated if data is parsed from the source files, not if parsed from
  /// JSON.
  Map<String, List<String>> _nameToWindowsName;


  /// Parses entries from Androids Generic.kl scan code data file.
  ///
  /// Lines in this file look like this (without the ///):
  /// key 100   ALT_RIGHT
  /// # key 101 "KEY_LINEFEED"
  ///
  /// We parse the commented out lines as well as the non-commented lines, so so
  /// that we can get names for all of the available scan codes, not just ones
  /// defined for the generic profile.
  ///
  /// Also, note that some keys (notably MEDIA_EJECT) can be mapped to more than
  /// one scan code, so the mapping can't just be 1:1, it has to be 1:many.
  Map<String, List<int>> _readAndroidScanCodes(String keyboardLayout) {
    final RegExp keyEntry = RegExp(r'#?\s*key\s+([0-9]+)\s*"?(?:KEY_)?([0-9A-Z_]+|\(undefined\))"?\s*(FUNCTION)?');
    final Map<String, List<int>> result = <String, List<int>>{};
    keyboardLayout.replaceAllMapped(keyEntry, (Match match) {
      if (match.group(3) == 'FUNCTION') {
        // Skip odd duplicate Android FUNCTION keys (F1-F12 are already defined).
        return '';
      }
      final String name = match.group(2);
      if (name == '(undefined)') {
        // Skip undefined scan codes.
        return '';
      }
      final String androidName = match.group(2);
      result[androidName] ??= <int>[];
      result[androidName].add(int.parse(match.group(1)));
      return null;
    });

    return result;
  }

  /// Parses entries from Android's keycodes.h key code data file.
  ///
  /// Lines in this file look like this (without the ///):
  ///  /** Left Control modifier key. */
  ///  AKEYCODE_CTRL_LEFT       = 113,
  Map<String, int> _readAndroidKeyCodes(String headerFile) {
    final RegExp enumBlock = RegExp(r'enum\s*\{(.*)\};', multiLine: true);
    // Eliminate everything outside of the enum block.
    headerFile = headerFile.replaceAllMapped(enumBlock, (Match match) => match.group(1));
    final RegExp enumEntry = RegExp(r'AKEYCODE_([A-Z0-9_]+)\s*=\s*([0-9]+),?');
    final Map<String, int> result = <String, int>{};
    for (final Match match in enumEntry.allMatches(headerFile)) {
      result[match.group(1)] = int.parse(match.group(2));
    }
    return result;
  }

  /// Parses entries from GLFW's keycodes.h key code data file.
  ///
  /// Lines in this file look like this (without the ///):
  ///  /** Space key. */
  ///  #define GLFW_KEY_SPACE              32,
  Map<String, int> _readGlfwKeyCodes(String headerFile) {
    // Only get the KEY definitions, ignore the rest (mouse, joystick, etc).
    final RegExp definedCodes = RegExp(r'define GLFW_KEY_([A-Z0-9_]+)\s*([A-Z0-9_]+),?');
    final Map<String, dynamic> replaced = <String, dynamic>{};
    for (final Match match in definedCodes.allMatches(headerFile)) {
      replaced[match.group(1)] = int.tryParse(match.group(2)) ?? match.group(2).replaceAll('GLFW_KEY_', '');
    }
    final Map<String, int> result = <String, int>{};
    replaced.forEach((String key, dynamic value) {
      // Some definition values point to other definitions (e.g #define GLFW_KEY_LAST GLFW_KEY_MENU).
      if (value is String) {
        result[key] = replaced[value] as int;
      } else {
        result[key] = value as int;
      }
    });
    return result;
  }

  /// Parses entries from GTK's gdkkeysyms.h key code data file.
  ///
  /// Lines in this file look like this (without the ///):
  ///  /** Space key. */
  ///  #define GDK_KEY_space 0x020
  Map<String, int> _readGtkKeyCodes(String headerFile) {
    final RegExp definedCodes = RegExp(r'#define GDK_KEY_([a-zA-Z0-9_]+)\s*0x([0-9a-f]+),?');
    final Map<String, int> replaced = <String, int>{};
    for (final Match match in definedCodes.allMatches(headerFile)) {
      replaced[match.group(1)] = int.parse(match.group(2), radix: 16);
    }
    return replaced;
  }

  Map<String, int> _readWindowsKeyCodes(String headerFile) {
    final RegExp definedCodes = RegExp(r'define VK_([A-Z0-9_]+)\s*([A-Z0-9_x]+),?');
    final Map<String, int> replaced = <String, int>{};
    for (final Match match in definedCodes.allMatches(headerFile)) {
      replaced[match.group(1)] = int.tryParse(match.group(2));
    }
    // The header doesn't explicitly define the [0-9] and [A-Z], but they mention that the range
    // is equivalent to the ASCII value.
    for (int i = 0x30; i <= 0x39; i++) {
      replaced[String.fromCharCode(i)] = i;
    }
    for (int i = 0x41; i <= 0x5A; i++) {
      replaced[String.fromCharCode(i)] = i;
    }
    return replaced;
  }

  /// Parses entries from Chromium's HID code mapping header file.
  ///
  /// Lines in this file look like this (without the ///):
  ///            USB       evdev   XKB     Win     Mac     Code     Enum
  /// DOM_CODE(0x000010, 0x0000, 0x0000, 0x0000, 0xffff, "Hyper", HYPER),
  List<Key> _readHidEntries(String input) {
    final List<Key> entries = <Key>[];
    final RegExp usbMapRegExp = RegExp(
        r'DOM_CODE\s*\(\s*0x([a-fA-F0-9]+),\s*0x([a-fA-F0-9]+),'
        r'\s*0x([a-fA-F0-9]+),\s*0x([a-fA-F0-9]+),\s*0x([a-fA-F0-9]+),\s*"?([^\s]+?)"?,\s*([^\s]+?)\s*\)',
        multiLine: true);
    final RegExp commentRegExp = RegExp(r'//.*$', multiLine: true);
    input = input.replaceAll(commentRegExp, '');
    input.replaceAllMapped(usbMapRegExp, (Match match) {
      if (match != null) {
        final int usbHidCode = getHex(match.group(1));
        final int macScanCode = getHex(match.group(5));
        final int linuxScanCode = getHex(match.group(2));
        final int xKbScanCode = getHex(match.group(3));
        final int windowsScanCode = getHex(match.group(4));
        final Key newEntry = Key(
          usbHidCode: usbHidCode,
          linuxScanCode: linuxScanCode == 0 ? null : linuxScanCode,
          xKbScanCode: xKbScanCode == 0 ? null : xKbScanCode,
          windowsScanCode: windowsScanCode == 0 ? null : windowsScanCode,
          macOsScanCode: macScanCode == 0xffff ? null : macScanCode,
          iosScanCode: (usbHidCode & 0x070000) == 0x070000 ? (usbHidCode ^ 0x070000) : null,
          name: match.group(6) == 'NULL' ? null : match.group(6),
          // The input data has a typo...
          chromiumName: shoutingToLowerCamel(match.group(7)).replaceAll('Minimium', 'Minimum'),
        );
        if (newEntry.chromiumName == 'none') {
          newEntry.name = 'None';
        }
        if (newEntry.name == 'IntlHash') {
          // Skip key that is not actually generated by any keyboard.
          return '';
        }
        // Remove duplicates: last one wins, so that supplemental codes
        // override.
        entries.removeWhere((Key entry) => entry.usbHidCode == newEntry.usbHidCode);
        entries.add(newEntry);
      }
      return match.group(0);
    });
    return entries;
  }
}

/// A single entry in the key data structure.
///
/// Can be read from JSON with the [Key.fromJsonMapEntry] constructor, or
/// written with the [toJson] method.
class Key {
  /// Creates a single key entry from available data.
  ///
  /// The [usbHidCode] and [chromiumName] parameters must not be null.
  Key({
    String enumName,
    this.name,
    @required this.usbHidCode,
    this.linuxScanCode,
    this.xKbScanCode,
    this.windowsScanCode,
    this.windowsKeyNames,
    this.windowsKeyCodes,
    this.macOsScanCode,
    this.iosScanCode,
    @required this.chromiumName,
    this.androidKeyNames,
    this.androidScanCodes,
    this.androidKeyCodes,
    this.glfwKeyNames,
    this.glfwKeyCodes,
    this.gtkKeyNames,
    this.gtkKeyCodes,
  })  : assert(usbHidCode != null),
        assert(chromiumName != null),
        _constantName = enumName;

  /// Populates the key from a JSON map.
  factory Key.fromJsonMapEntry(String name, Map<String, dynamic> map) {
    return Key(
      enumName: name,
      name: map['names']['domkey'] as String,
      chromiumName: map['names']['chromium'] as String,
      usbHidCode: map['scanCodes']['usb'] as int,
      androidKeyNames: (map['names']['android'] as List<dynamic>)?.cast<String>(),
      androidScanCodes: (map['scanCodes']['android'] as List<dynamic>)?.cast<int>(),
      androidKeyCodes: (map['keyCodes']['android'] as List<dynamic>)?.cast<int>(),
      linuxScanCode: map['scanCodes']['linux'] as int,
      xKbScanCode: map['scanCodes']['xkb'] as int,
      windowsScanCode: map['scanCodes']['windows'] as int,
      windowsKeyCodes: (map['keyCodes']['windows'] as List<dynamic>)?.cast<int>(),
      windowsKeyNames: (map['names']['windows'] as List<dynamic>)?.cast<String>(),
      macOsScanCode: map['scanCodes']['macos'] as int,
      iosScanCode: map['scanCodes']['ios'] as int,
      glfwKeyNames: (map['names']['glfw'] as List<dynamic>)?.cast<String>(),
      glfwKeyCodes: (map['keyCodes']['glfw'] as List<dynamic>)?.cast<int>(),
      gtkKeyNames: (map['names']['gtk'] as List<dynamic>)?.cast<String>(),
      gtkKeyCodes: (map['keyCodes']['gtk'] as List<dynamic>)?.cast<int>(),
    );
  }

  /// The USB HID code of the key
  int usbHidCode;

  /// The Linux scan code of the key, from Chromium's header file.
  int linuxScanCode;
  /// The XKb scan code of the key from Chromium's header file.
  int xKbScanCode;
  /// The Windows scan code of the key from Chromium's header file.
  int windowsScanCode;
  /// The list of Windows key codes matching this key, created by looking up the
  /// Windows name in the Chromium data, and substituting the Windows key code
  /// value.
  List<int> windowsKeyCodes;
  /// The list of names that Windows gives to this key (symbol names minus the
  /// prefix).
  List<String> windowsKeyNames;
  /// The macOS scan code of the key from Chromium's header file.
  int macOsScanCode;
  /// The iOS scan code of the key from UIKey's documentation (USB Hid table)
  int iosScanCode;
  /// The name of the key, mostly derived from the DomKey name in Chromium,
  /// but where there was no DomKey representation, derived from the Chromium
  /// symbol name.
  String name;
  /// The Chromium symbol name for the key.
  String chromiumName;
  /// The list of names that Android gives to this key (symbol names minus the
  /// prefix).
  List<String> androidKeyNames;
  /// The list of Android key codes matching this key, created by looking up the
  /// Android name in the Chromium data, and substituting the Android key code
  /// value.
  List<int> androidKeyCodes;
  /// The list of Android scan codes matching this key, created by looking up
  /// the Android name in the Chromium data, and substituting the Android scan
  /// code value.
  List<int> androidScanCodes;

  /// The list of names that GFLW gives to this key (symbol names minus the
  /// prefix).
  List<String> glfwKeyNames;

  /// The list of GLFW key codes matching this key, created by looking up the
  /// Linux name in the Chromium data, and substituting the GLFW key code
  /// value.
  List<int> glfwKeyCodes;

  /// The list of names that GTK gives to this key (symbol names minus the
  /// prefix).
  List<String> gtkKeyNames;

  /// The list of GTK key codes matching this key, created by looking up the
  /// Linux name in the GTK data, and substituting the GTK key code
  /// value.
  List<int> gtkKeyCodes;

  /// Creates a JSON map from the key data.
  Map<String, dynamic> toJson() {
    return <String, dynamic>{
      'names': <String, dynamic>{
        'domkey': name,
        'android': androidKeyNames,
        'english': commentName,
        'chromium': chromiumName,
        'glfw': glfwKeyNames,
        'gtk': gtkKeyNames,
        'windows': windowsKeyNames,
      },
      'scanCodes': <String, dynamic>{
        'android': androidScanCodes,
        'usb': usbHidCode,
        'linux': linuxScanCode,
        'xkb': xKbScanCode,
        'windows': windowsScanCode,
        'macos': macOsScanCode,
        'ios': iosScanCode,
      },
      'keyCodes': <String, List<int>>{
        'android': androidKeyCodes,
        'glfw': glfwKeyCodes,
        'gtk': gtkKeyCodes,
        'windows': windowsKeyCodes,
      },
    };
  }

  /// Returns the printable representation of this key, if any.
  ///
  /// If there is no printable representation, returns null.
  String get keyLabel => printable[constantName];

  int get flutterId {
    if (printable.containsKey(constantName) && !constantName.startsWith('numpad')) {
      return unicodePlane | (keyLabel.codeUnitAt(0) & valueMask);
    }
    return hidPlane | (usbHidCode & valueMask);
  }

  static String getCommentName(String constantName) {
    String upperCamel = lowerCamelToUpperCamel(constantName);
    upperCamel = upperCamel.replaceAllMapped(RegExp(r'(Digit|Numpad|Lang|Button|Left|Right)([0-9]+)'), (Match match) => '${match.group(1)} ${match.group(2)}');
    return upperCamel.replaceAllMapped(RegExp(r'([A-Z])'), (Match match) => ' ${match.group(1)}').trim();
  }

  /// Gets the name of the key suitable for placing in comments.
  ///
  /// Takes the [constantName] and converts it from lower camel case to capitalized
  /// separate words (e.g. "wakeUp" converts to "Wake Up").
  String get commentName => getCommentName(constantName);

  /// Gets the named used for the key constant in the definitions in
  /// keyboard_keys.dart.
  ///
  /// If set by the constructor, returns the name set, but otherwise constructs
  /// the name from the various different names available, making sure that the
  /// name isn't a Dart reserved word (if it is, then it adds the word "Key" to
  /// the end of the name).
  String get constantName {
    if (_constantName == null) {
      String result;
      if (name == null || name.isEmpty) {
        // If it doesn't have a DomKey name then use the Chromium symbol name.
        result = chromiumName;
      } else {
        result = upperCamelToLowerCamel(name);
      }
      if (kDartReservedWords.contains(result)) {
        return '${result}Key';
      }
      // Don't set enumName: we want it to regen each time if never set, but
      // to stay set if set by the JSON loading.
      return result;
    }
    return _constantName;
  }
  set constantName(String value) => _constantName = value;
  String _constantName;

  @override
  String toString() {
    return """'$constantName': (name: "$name", usbHidCode: ${toHex(usbHidCode)}, """
        'linuxScanCode: ${toHex(linuxScanCode)}, xKbScanCode: ${toHex(xKbScanCode)}, '
        'windowsKeyCode: ${toHex(windowsScanCode)}, macOsScanCode: ${toHex(macOsScanCode)}, '
        'windowsScanCode: ${toHex(windowsScanCode)}, chromiumSymbolName: $chromiumName '
        'iOSScanCode: ${toHex(iosScanCode)})';
  }

  /// Returns the static map of printable representations.
  static Map<String, String> get printable {
    if (_printable == null) {
      final String printableKeys = File(path.join(flutterRoot.path, 'dev', 'tools', 'gen_keycodes', 'data', 'printable.json',)).readAsStringSync();
      final Map<String, dynamic> printable = json.decode(printableKeys) as Map<String, dynamic>;
      _printable = printable.cast<String, String>();
    }
    return _printable;
  }
  static Map<String, String> _printable;

  /// Returns the static map of synonym representations.
  ///
  /// These include synonyms for keys which don't have printable
  /// representations, and appear in more than one place on the keyboard (e.g.
  /// SHIFT, ALT, etc.).
  static Map<String, List<dynamic>> get synonyms {
    if (_synonym == null) {
      final String synonymKeys = File(path.join(flutterRoot.path, 'dev', 'tools', 'gen_keycodes', 'data', 'synonyms.json',)).readAsStringSync();
      final Map<String, dynamic> synonym = json.decode(synonymKeys) as Map<String, dynamic>;
      _synonym = synonym.cast<String, List<dynamic>>();
    }
    return _synonym;
  }
  static Map<String, List<dynamic>> _synonym;

  /// Mask for the 32-bit value portion of the code.
  static const int valueMask = 0x000FFFFFFFF;

  /// The code prefix for keys which have a Unicode representation.
  static const int unicodePlane = 0x00000000000;

  /// The code prefix for keys which do not have a Unicode representation, but
  /// do have a USB HID ID.
  static const int hidPlane = 0x00100000000;

  /// The code prefix for pseudo-keys which represent collections of key synonyms.
  static const int synonymPlane = 0x20000000000;
}
