function generateHookMap(sourceAST) {
  const hookNamesMapping = getHookNamesMappingFromAST(sourceAST);
  const namesMap = new Map();
  const names = [];
  const mappings = [];
  let currentLine = null;
  hookNamesMapping.forEach(({
    name,
    start
  }) => {
    let nameIndex = namesMap.get(name);

    if (nameIndex == null) {
      names.push(name);
      nameIndex = names.length - 1;
      namesMap.set(name, nameIndex);
    } // TODO: We add a -1 at the end of the entry so we can later
    // encode/decode the mappings by reusing the encode/decode functions
    // from the `sourcemap-codec` library. This library expects segments
    // of specific sizes (i.e. of size 4) in order to encode them correctly.
    // In the future, when we implement our own encoding, we will not
    // need this restriction and can remove the -1 at the end.


    const entry = [start.line, start.column, nameIndex, -1];

    if (currentLine !== start.line) {
      currentLine = start.line;
      mappings.push([entry]);
    } else {
      const current = mappings[mappings.length - 1];
      current.push(entry);
    }
  });
  return {
    names,
    mappings
  };
}
Given a parsed source code AST, returns a "Hook Map", which is a
mapping which maps locations in the source code to their to their
corresponding Hook name, if there is a relevant Hook name for that
location (see getHookNamesMappingFromAST for details on the
representation of the mapping).

The format of the Hook Map follows a similar format as the `name`
and `mappings` fields in the Source Map spec, where `names` is an
array of strings, and `mappings` contains segments lines, columns,
and indices into the `names` array.

E.g.:
  {
    names: ["<no-hook>", "state"],
    mappings: [
      [ -> line 1
        [1, 0, 0],  -> line, col, name index
      ],
      [ -> line 2
        [2, 5, 1],  -> line, col, name index
        [2, 15, 0],  -> line, col, name index
      ],
    ],
  }