// read files from vscode-languageserver-node, and generate Go rpc stubs
// and data definitions. (and maybe someday unmarshaling code)

// The output is 3 files, tsprotocol.go contains the type definitions
// while tsclient.go and tsserver.go contain the LSP API and stub. An LSP server
// uses both APIs. To read the code, start in this file's main() function.

// The code is rich in heuristics and special cases, some of which are to avoid
// extensive changes to gopls, and some of which are due to the mismatch between
// typescript and Go types. In particular, there is no Go equivalent to union
// types, so each case ought to be considered separately. The Go equivalent of A
// & B could frequently be struct{A;B;}, or it could be the equivalent type
// listing all the members of A and B. Typically the code uses the former, but
// especially if A and B have elements with the same name, it does a version of
// the latter. ClientCapabilities has to be expanded, and ServerCapabilities is
// expanded to make the generated code easier to read.

// for us typescript ignorati, having an import makes this file a module
import * as fs from 'fs';
import * as ts from 'typescript';
import * as u from './util';
import {constName, getComments, goName, loc, strKind} from './util';

var program: ts.Program;

function parse() {
  // this won't complain if some fnames don't exist
  program = ts.createProgram(
      u.fnames,
      {target: ts.ScriptTarget.ES2018, module: ts.ModuleKind.CommonJS});
  program.getTypeChecker();  // finish type checking and assignment
}

// ----- collecting information for RPCs
let req = new Map<string, ts.NewExpression>();               // requests
let not = new Map<string, ts.NewExpression>();               // notifications
let ptypes = new Map<string, [ts.TypeNode, ts.TypeNode]>();  // req, resp types
let receives = new Map<string, 'server'|'client'>();         // who receives it
let rpcTypes = new Set<string>();  // types seen in the rpcs

function findRPCs(node: ts.Node) {
  if (!ts.isModuleDeclaration(node)) {
    return
  }
  if (!ts.isIdentifier(node.name)) {
    throw new Error(
        `expected Identifier, got ${strKind(node.name)} at ${loc(node)}`)
  }
  let reqnot = req
  let v = node.name.getText()
  if (v.endsWith('Notification')) reqnot = not;
  else if (!v.endsWith('Request')) return;

  if (!ts.isModuleBlock(node.body)) {
    throw new Error(
        `expected ModuleBody got ${strKind(node.body)} at ${loc(node)}`)
  }
  let x: ts.ModuleBlock = node.body
  // The story is to expect const method = 'textDocument/implementation'
  // const type = new ProtocolRequestType<...>(method)
  // but the method may be an explicit string
  let rpc: string = '';
  let newNode: ts.NewExpression;
  for (let i = 0; i < x.statements.length; i++) {
    const uu = x.statements[i];
    if (!ts.isVariableStatement(uu)) continue;
    const dl: ts.VariableDeclarationList = uu.declarationList;
    if (dl.declarations.length != 1)
      throw new Error(`expected a single decl at ${loc(dl)}`);
    const decl: ts.VariableDeclaration = dl.declarations[0];
    const name = decl.name.getText()
    // we want the initializers
    if (name == 'method') {  // StringLiteral
      if (!ts.isStringLiteral(decl.initializer))
        throw new Error(`expect StringLiteral at ${loc(decl)}`);
      rpc = decl.initializer.getText()
    }
    else if (name == 'type') {  // NewExpression
      if (!ts.isNewExpression(decl.initializer))
        throw new Error(`expecte new at ${loc(decl)}`);
      const nn: ts.NewExpression = decl.initializer
      newNode = nn
      const mtd = nn.arguments[0];
      if (ts.isStringLiteral(mtd)) rpc = mtd.getText();
      switch (nn.typeArguments.length) {
        case 1:  // exit
          ptypes.set(rpc, [nn.typeArguments[0], null])
          break;
        case 2:  // notifications
          ptypes.set(rpc, [nn.typeArguments[0], null])
          break;
        case 4:  // request with no parameters
          ptypes.set(rpc, [null, nn.typeArguments[0]])
          break;
        case 5:  // request req, resp, partial(?)
          ptypes.set(rpc, [nn.typeArguments[0], nn.typeArguments[1]])
          break;
        default:
          throw new Error(`${nn.typeArguments.length} at ${loc(nn)}`)
      }
    }
  }
  if (rpc == '') throw new Error(`no name found at ${loc(x)}`);
  // remember the implied types
  const [a, b] = ptypes.get(rpc);
  const add = function(n: ts.Node) {
    rpcTypes.add(goName(n.getText()))
  };
  underlying(a, add);
  underlying(b, add);
  rpc = rpc.substring(1, rpc.length - 1);  // 'exit'
  reqnot.set(rpc, newNode)
}

// handle missing typeArguments
function lookUp(n: ts.NewExpression): ts.NodeArray<ts.TypeNode> {
  // parent should be VariableDeclaration. its children should be
  // Identifier('type') ???
  // TypeReference: [Identifier('RequestType1), ]
  // NewExpression (us)
  const p = n.parent;
  if (!ts.isVariableDeclaration(p)) throw new Error(`not variable decl`);
  const tr = p.type;
  if (!ts.isTypeReferenceNode(tr)) throw new Error(`not TypeReference`);
  return tr.typeArguments;
}

function setReceives() {
  // mark them all as server, then adjust the client ones.
  // it would be nice to have some independent check on this
  // (this logic fails if the server ever sends $/canceRequest
  //  or $/progress)
  req.forEach((_, k) => {receives.set(k, 'server')});
  not.forEach((_, k) => {receives.set(k, 'server')});
  receives.set('window/showMessage', 'client');
  receives.set('window/showMessageRequest', 'client');
  receives.set('window/logMessage', 'client');
  receives.set('telemetry/event', 'client');
  receives.set('client/registerCapability', 'client');
  receives.set('client/unregisterCapability', 'client');
  receives.set('workspace/workspaceFolders', 'client');
  receives.set('workspace/configuration', 'client');
  receives.set('workspace/applyEdit', 'client');
  receives.set('textDocument/publishDiagnostics', 'client');
  // a small check
  receives.forEach((_, k) => {
    if (!req.get(k) && !not.get(k)) throw new Error(`missing ${k}}`);
    if (req.get(k) && not.get(k)) throw new Error(`dup ${k}`);
  })
}

interface Data {
  me: ts.Node;   // root node for this type
  name: string;  // Go name
  generics: ts.NodeArray<ts.TypeParameterDeclaration>;
  as: ts.NodeArray<ts.HeritageClause>;  // inheritance
  // Interface
  properties: ts.NodeArray<ts.TypeElement>;  // ts.PropertySignature
  alias: ts.TypeNode;                        // type alias
  // module
  statements: ts.NodeArray<ts.Statement>;
  enums: ts.NodeArray<ts.EnumMember>;
  // class
  members: ts.NodeArray<ts.PropertyDeclaration>;
}
function newData(n: ts.Node, nm: string): Data {
  return {
    me: n, name: goName(nm),
        generics: ts.createNodeArray<ts.TypeParameterDeclaration>(), as: ts.createNodeArray<ts.HeritageClause>(),
        properties: ts.createNodeArray<ts.TypeElement>(), alias: undefined,
        statements: ts.createNodeArray<ts.Statement>(),
        enums: ts.createNodeArray<ts.EnumMember>(),
        members: ts.createNodeArray<ts.PropertyDeclaration>(),
  }
}

// for debugging, produce a skeleton description
function strData(d: Data): string {
  const f = function(na: ts.NodeArray<any>): number {
    return na.length
  };
  return `D(${d.name}) g;${f(d.generics)} a:${f(d.as)} p:${f(d.properties)} s:${
      f(d.statements)} e:${f(d.enums)} m:${f(d.members)} ${
      d.alias != undefined}`
}

let data = new Map<string, Data>();            // parsed data types
let seenTypes = new Map<string, Data>();       // type names we've seen
let extraTypes = new Map<string, string[]>();  // to avoid struct params

// look at top level data definitions
function genTypes(node: ts.Node) {
  // Ignore top-level items that can't produce output
  if (ts.isExpressionStatement(node) || ts.isFunctionDeclaration(node) ||
      ts.isImportDeclaration(node) || ts.isVariableStatement(node) ||
      ts.isExportDeclaration(node) || ts.isEmptyStatement(node) ||
      node.kind == ts.SyntaxKind.EndOfFileToken) {
    return;
  }
  if (ts.isInterfaceDeclaration(node)) {
    const v: ts.InterfaceDeclaration = node;
    // need to check the members, many of which are disruptive
    let mems: ts.TypeElement[] = [];
    const f = function(t: ts.TypeElement) {
      if (ts.isPropertySignature(t)) {
        mems.push(t);
      } else if (ts.isMethodSignature(t) || ts.isCallSignatureDeclaration(t)) {
        return;
      } else if (ts.isIndexSignatureDeclaration(t)) {
        // probably safe to ignore these
        // [key: string]: boolean | number | string | undefined;
        // and InitializeResult: [custom: string]: any;]
        return
      } else
        throw new Error(`unexpected ${strKind(t)}`)
    };
    v.members.forEach(f);
    if (mems.length == 0 && !v.heritageClauses &&
        v.name.getText() != 'InitializedParams') {
      return  // really? (Don't seem to need any of these)
    };
    // Found one we want
    let x = newData(v, goName(v.name.getText()));
    x.properties = ts.createNodeArray<ts.TypeElement>(mems);
    if (v.typeParameters) x.generics = v.typeParameters;
    if (v.heritageClauses) x.as = v.heritageClauses;
    if (x.generics.length > 1) {  // Unneeded
      // Item interface Item<K, V>...
      return
    };
    if (data.has(x.name)) {  // modifying one we've seen
      x = dataMerge(x, data.get(x.name));
    }
    data.set(x.name, x);
  } else if (ts.isTypeAliasDeclaration(node)) {
    const v: ts.TypeAliasDeclaration = node;
    let x = newData(v, v.name.getText());
    x.alias = v.type;
    // if type is a union of constants, we (mostly) don't want it
    // (at the top level)
    // Unfortunately this is false for TraceValues
    if (ts.isUnionTypeNode(v.type) &&
        v.type.types.every((n: ts.TypeNode) => ts.isLiteralTypeNode(n))) {
      if (x.name != 'TraceValues') return;
    }
    if (v.typeParameters) {
      x.generics = v.typeParameters;
    }
    if (data.has(x.name)) x = dataMerge(x, data.get(x.name));
    if (x.generics.length > 1) {
      return
    };
    data.set(x.name, x);
  } else if (ts.isModuleDeclaration(node)) {
    const v: ts.ModuleDeclaration = node;
    if (!ts.isModuleBlock(v.body)) {
      throw new Error(`${loc(v)} not ModuleBlock, but ${strKind(v.body)}`)
    }
    const b: ts.ModuleBlock = v.body;
    var s: ts.Statement[] = [];
    // we don't want most of these
    const fx = function(x: ts.Statement) {
      if (ts.isFunctionDeclaration(x)) {
        return
      };
      if (ts.isTypeAliasDeclaration(x) || ts.isModuleDeclaration(x)) {
        return
      };
      if (!ts.isVariableStatement(x))
        throw new Error(
            `expected VariableStatment ${loc(x)} ${strKind(x)} ${x.getText()}`);
      if (hasNewExpression(x)) {
        return
      };
      s.push(x);
    };
    b.statements.forEach(fx)
    if (s.length == 0) {
      return
    };
    let m = newData(node, v.name.getText());
    m.statements = ts.createNodeArray<ts.Statement>(s);
    if (data.has(m.name)) m = dataMerge(m, data.get(m.name));
    data.set(m.name, m);
  } else if (ts.isEnumDeclaration(node)) {
    const nm = node.name.getText();
    let v = newData(node, nm);
    v.enums = node.members;
    if (data.has(nm)) {
      v = dataMerge(v, data.get(nm));
    }
    data.set(nm, v);
  } else if (ts.isClassDeclaration(node)) {
    const v: ts.ClassDeclaration = node;
    var d: ts.PropertyDeclaration[] = [];
    // look harder at the PropertyDeclarations.
    const wanted = function(c: ts.ClassElement): string {
      if (ts.isConstructorDeclaration(c)) {
        return ''
      };
      if (ts.isMethodDeclaration(c)) {
        return ''
      };
      if (ts.isGetAccessor(c)) {
        return ''
      };
      if (ts.isSetAccessor(c)) {
        return ''
      };
      if (ts.isPropertyDeclaration(c)) {
        d.push(c);
        return strKind(c)
      };
      throw new Error(`Class decl ${strKind(c)} `)
    };
    v.members.forEach((c, i) => wanted(c));
    if (d.length == 0) {
      return
    };  // don't need it, maybe
    let c = newData(v, v.name.getText());
    c.members = ts.createNodeArray<ts.PropertyDeclaration>(d);
    if (v.typeParameters) {
      c.generics = v.typeParameters
    }
    if (c.generics.length > 1) {
      return
    }
    if (v.heritageClauses) {
      c.as = v.heritageClauses
    }
    if (data.has(c.name))
      throw new Error(`Class dup ${loc(c.me)} and ${loc(data.get(c.name).me)}`);
    data.set(c.name, c);
  } else {
    throw new Error(`unexpected ${strKind(node)} ${loc(node)} `)
  }
}

// Typescript can accumulate
function dataMerge(a: Data, b: Data): Data {
  // maybe they are textually identical? (it happens)
  const [at, bt] = [a.me.getText(), b.me.getText()];
  if (at == bt) {
    return a;
  }
  const ax = `(${a.statements.length},${a.properties.length})`
  const bx = `(${b.statements.length},${b.properties.length})`
  // console.log(`397
  // ${a.name}${ax}${bx}\n${a.me.getText()}\n${b.me.getText()}\n`)
  switch (a.name) {
    case 'InitializeError':
    case 'MessageType':
    case 'CompletionItemTag':
    case 'SymbolTag':
    case 'CodeActionKind':
      // want the Module
      return a.statements.length > 0 ? a : b;
    case 'CancellationToken':
      // want the Interface
      return a.properties.length > 0 ? a : b;
    case 'TextDocumentContentChangeEvent':  // almost the same
      return a;
  }
  console.log(
      `${strKind(a.me)} ${strKind(b.me)} ${a.name} ${loc(a.me)} ${loc(b.me)}`)
  throw new Error(`Fix dataMerge for ${a.name}`)
}

// is a node an ancestor of a NewExpression
function hasNewExpression(n: ts.Node): boolean {
  let ans = false;
  n.forEachChild((n: ts.Node) => {
    if (ts.isNewExpression(n)) ans = true;
  })
  return ans
}

function checkOnce() {
  // Data for all the rpc types?
  rpcTypes.forEach(s => {
    if (!data.has(s)) throw new Error(`checkOnce, ${s}?`)
  });
}

// helper function to find underlying types
function underlying(n: ts.Node, f: (n: ts.Node) => void) {
  if (!n) return;
  const ff = function(n: ts.Node) {
    underlying(n, f)
  };
  if (ts.isIdentifier(n)) {
    f(n)
  } else if (
      n.kind == ts.SyntaxKind.StringKeyword ||
      n.kind == ts.SyntaxKind.NumberKeyword ||
      n.kind == ts.SyntaxKind.AnyKeyword ||
      n.kind == ts.SyntaxKind.NullKeyword ||
      n.kind == ts.SyntaxKind.BooleanKeyword ||
      n.kind == ts.SyntaxKind.ObjectKeyword ||
      n.kind == ts.SyntaxKind.VoidKeyword) {
    // nothing to do
  } else if (ts.isTypeReferenceNode(n)) {
    f(n.typeName)
  } else if (ts.isArrayTypeNode(n)) {
    underlying(n.elementType, f)
  } else if (ts.isHeritageClause(n)) {
    n.types.forEach(ff);
  } else if (ts.isExpressionWithTypeArguments(n)) {
    underlying(n.expression, f)
  } else if (ts.isPropertySignature(n)) {
    underlying(n.type, f)
  } else if (ts.isTypeLiteralNode(n)) {
    n.members.forEach(ff)
  } else if (ts.isUnionTypeNode(n) || ts.isIntersectionTypeNode(n)) {
    n.types.forEach(ff)
  } else if (ts.isIndexSignatureDeclaration(n)) {
    underlying(n.type, f)
  } else if (ts.isParenthesizedTypeNode(n)) {
    underlying(n.type, f)
  } else if (
      ts.isLiteralTypeNode(n) || ts.isVariableStatement(n) ||
      ts.isTupleTypeNode(n)) {
    // we only see these in moreTypes, but they are handled elsewhere
    return;
  } else if (ts.isEnumMember(n)) {
    if (ts.isStringLiteral(n.initializer)) return;
    throw new Error(`EnumMember ${strKind(n.initializer)} ${n.name.getText()}`)
  } else {
    throw new Error(`saw ${strKind(n)} in underlying. ${n.getText()}`)
  }
}

// find all the types implied by seenTypes.
// Simplest way to the transitive closure is to stabilize the size of seenTypes
// but it is slow
function moreTypes() {
  const extra = function(s: string) {
    if (!data.has(s)) throw new Error(`moreTypes needs ${s}`);
    seenTypes.set(s, data.get(s))
  };
  rpcTypes.forEach(extra);  // all the types needed by the rpcs
  // needed in enums.go (or elsewhere)
  extra('InitializeError')
  extra('WatchKind')
  extra('FoldingRangeKind')
  // not sure why these weren't picked up
  extra('FileSystemWatcher')
  extra('DidChangeWatchedFilesRegistrationOptions')
  let old = 0
  do {
    old = seenTypes.size

    const m = new Map<string, Data>();
    const add = function(n: ts.Node) {
      const nm = goName(n.getText());
      if (seenTypes.has(nm) || m.has(nm)) return;
      // For generic parameters, this might set it to undefined
      m.set(nm, data.get(nm));
    };
    // expect all the heritage clauses have single Identifiers
    const h = function(n: ts.Node) {
      underlying(n, add);
    };
    const f = function(x: ts.NodeArray<ts.Node>) {
      x.forEach(h)
    };
    seenTypes.forEach((d: Data) => d && f(d.as))
    // find the types in the properties
    seenTypes.forEach((d: Data) => d && f(d.properties))
    // and in the alias and in the statements and in the enums
    seenTypes.forEach((d: Data) => d && underlying(d.alias, add))
    seenTypes.forEach((d: Data) => d && f(d.statements))
    seenTypes.forEach((d: Data) => d && f(d.enums))
    m.forEach((d, k) => seenTypes.set(k, d))
  }
  while (seenTypes.size != old)
    ;
}

let typesOut = new Array<string>();
let constsOut = new Array<string>();

// generate Go types
function toGo(d: Data, nm: string) {
  if (!d) return;  // this is probably a generic T
  if (d.alias) {
    goTypeAlias(d, nm);
  } else if (d.statements.length > 0) {
    goModule(d, nm);
  } else if (d.enums.length > 0) {
    goEnum(d, nm);
  } else if (
      d.properties.length > 0 || d.as.length > 0 || nm == 'InitializedParams') {
    goInterface(d, nm);
  } else
    throw new Error(
        `more cases in toGo ${nm} ${d.as.length} ${d.generics.length} `)
}

// these fields need a *
var starred: [string, string][] = [
  ['TextDocumentContentChangeEvent', 'range'], ['CodeAction', 'command'],
  ['DidSaveTextDocumentParams', 'text'], ['CompletionItem', 'command'],
  ['CompletionItem', 'textEdit']
];

// generate Go code for an interface
function goInterface(d: Data, nm: string) {
  let ans = `type ${goName(nm)} struct {\n`;

  // generate the code for each member
  const g = function(n: ts.TypeElement) {
    if (!ts.isPropertySignature(n))
      throw new Error(`expected PropertySignature got ${strKind(n)} `);
    ans = ans.concat(getComments(n));
    const json = u.JSON(n);
    // SelectionRange is a recursive type
    let gt = goType(n.type, n.name.getText());
    if (gt == d.name) gt = '*' + gt;  // avoid recursive types
    // there are several cases where a * is needed
    starred.forEach(([a, b]) => {
      if (d.name == a && n.name.getText() == b) gt = '*' + gt
    });
    ans = ans.concat(`${goName(n.name.getText())} ${gt}`, json, '\n')
  };
  d.properties.forEach(g)
  // heritage clauses become embedded types
  // check they are all Identifiers
  const f = function(n: ts.ExpressionWithTypeArguments) {
    if (!ts.isIdentifier(n.expression))
      throw new Error(`Interface ${nm} heritage ${strKind(n.expression)} `);
    ans = ans.concat(goName(n.expression.getText()), '\n')
  };
  d.as.forEach((n: ts.HeritageClause) => n.types.forEach(f))
  ans = ans.concat(`}\n`);
  typesOut.push(getComments(d.me))
  typesOut.push(ans)
}

// generate Go code for a module (const declarations)
// Generates type definitions, and named constants
function goModule(d: Data, nm: string) {
  if (d.generics.length > 0 || d.as.length > 0) {
    throw new Error(`goModule: unexpected for ${nm}
  `)
  }
  // all the statements should be export const <id>: value
  //   or value = value
  // They are VariableStatements with x.declarationList having a single
  //   VariableDeclaration
  let isNumeric = false;
  const f = function(n: ts.Statement, i: number) {
    if (!ts.isVariableStatement(n)) {
      throw new Error(` ${nm} ${i} expected VariableStatement,
      got ${strKind(n)}`);
    }
    const c = getComments(n)
    const v = n.declarationList.declarations[0];  // only one

    if (!v.initializer)
      throw new Error(`no initializer ${nm} ${i} ${v.name.getText()}`);
    isNumeric = strKind(v.initializer) == 'NumericLiteral';
    if (c != '') constsOut.push(c);  // no point if there are no comments
    // There are duplicates.
    const cname = constName(goName(v.name.getText()), nm);
    let val = v.initializer.getText()
    val = val.split('\'').join('"')  // useless work for numbers
    constsOut.push(`${cname} ${nm} = ${val}`)
  };
  d.statements.forEach(f)
  typesOut.push(getComments(d.me))
  // Or should they be type aliases?
  typesOut.push(`type ${nm} ${isNumeric ? 'float64' : 'string'}`)
}

// generate Go code for an enum. Both types and named constants
function goEnum(d: Data, nm: string) {
  let isNumeric = false
  const f = function(v: ts.EnumMember, j: number) {  // same as goModule
    if (!v.initializer)
      throw new Error(`goEnum no initializer ${nm} ${j} ${v.name.getText()}`);
    isNumeric = strKind(v.initializer) == 'NumericLiteral';
    const c = getComments(v);
    const cname = constName(goName(v.name.getText()), nm);
    let val = v.initializer.getText()
    val = val.split('\'').join('"')  // replace quotes. useless work for numbers
    constsOut.push(`${c}${cname} ${nm} = ${val}`)
  };
  d.enums.forEach(f)
  typesOut.push(getComments(d.me))
  // Or should they be type aliases?
  typesOut.push(`type ${nm} ${isNumeric ? 'float64' : 'string'}`)
}

// generate code for a type alias
function goTypeAlias(d: Data, nm: string) {
  if (d.as.length != 0 || d.generics.length != 0) {
    if (nm != 'ServerCapabilities')
      throw new Error(`${nm} has extra fields(${d.as.length},${
          d.generics.length}) ${d.me.getText()}`);
  }
  typesOut.push(getComments(d.me))
  // d.alias doesn't seem to have comments
  let aliasStr = goName(nm) == "DocumentURI" ? " " : " = "
  typesOut.push(`type ${goName(nm)}${aliasStr}${goType(d.alias, nm)}\n`)
}

// return a go type and maybe an assocated javascript tag
function goType(n: ts.TypeNode, nm: string): string {
  if (n.getText() == 'T') return 'interface{}';  // should check it's generic
  if (ts.isTypeReferenceNode(n)) {
    return goName(n.typeName.getText());  // avoid <T>
  } else if (ts.isUnionTypeNode(n)) {
    return goUnionType(n, nm);
  } else if (ts.isIntersectionTypeNode(n)) {
    return goIntersectionType(n, nm);
  } else if (strKind(n) == 'StringKeyword') {
    return 'string';
  } else if (strKind(n) == 'NumberKeyword') {
    return 'float64';
  } else if (strKind(n) == 'BooleanKeyword') {
    return 'bool';
  } else if (strKind(n) == 'AnyKeyword') {
    return 'interface{}';
  } else if (strKind(n) == 'NullKeyword') {
    return 'nil'
  } else if (strKind(n) == 'VoidKeyword' || strKind(n) == 'NeverKeyword') {
    return 'void'
  } else if (strKind(n) == 'ObjectKeyword') {
    return 'interface{}'
  } else if (ts.isArrayTypeNode(n)) {
    return `[]${goType(n.elementType, nm)}`
  } else if (ts.isParenthesizedTypeNode(n)) {
    return goType(n.type, nm)
  } else if (ts.isLiteralTypeNode(n)) {
    return strKind(n.literal) == 'StringLiteral' ? 'string' : 'float64';
  } else if (ts.isTypeLiteralNode(n)) {
    // these are anonymous structs
    const v = goTypeLiteral(n, nm);
    return v
  } else if (ts.isTupleTypeNode(n)) {
    if (n.getText() == '[number, number]') return '[]float64';
    throw new Error(`goType unexpected Tuple ${n.getText()}`)
  }
  throw new Error(`${strKind(n)} goType unexpected ${n.getText()} for ${nm}`)
}

// The choice is uniform interface{}, or some heuristically assigned choice,
// or some better sytematic idea I haven't thought of. Using interface{}
// is, in practice, impossibly complex in the existing code.
function goUnionType(n: ts.UnionTypeNode, nm: string): string {
  const help = `/*${n.getText()}*/`  // show the original as a comment
  // handle all the special cases
  switch (n.types.length) {
    case 2:
      const a = strKind(n.types[0])
      const b = strKind(n.types[1])
      if (a == 'NumberKeyword' && b == 'StringKeyword') {  // ID
        return `interface{} ${help}`
      }
      if (b == 'NullKeyword') {
        if (nm == 'textDocument/codeAction') {
          // (Command | CodeAction)[] | null
          return `[]CodeAction ${help}`
        }
        let v = goType(n.types[0], 'a')
        if (v.startsWith(`[]interface`)) v = v.slice(2, v.length)
        return `${v} ${help}`
      }
      if (a == 'BooleanKeyword') {  // believe the weaker type is wanted
        if (nm == 'codeActionProvider') return `interface{} ${help}`;
        if (nm == 'renameProvider') return `interface{} ${help}`;
        return `${goType(n.types[0], 'b')} ${help}`
      }
      if (b == 'ArrayType') return `${goType(n.types[1], 'c')} ${help}`;
      if (a == 'TypeReference' && a == b) return `interface{} ${help}`;
      if (a == 'StringKeyword') return `string ${help}`;
      if (a == 'TypeLiteral' && nm == 'TextDocumentContentChangeEvent') {
        return `${goType(n.types[0], nm)}`
      }
      throw new Error(`724 ${a} ${b} ${n.getText()} ${loc(n)}`);
    case 3:
      const aa = strKind(n.types[0])
      const bb = strKind(n.types[1])
      const cc = strKind(n.types[2])
      if (nm == 'textDocument/prepareRename') {
        // want Range, not interface{}
        return `${goType(n.types[0], nm)} ${help}`
      }
      if (nm == 'DocumentFilter') {
        // not really a union. the first is enough, up to a missing
        // omitempty but avoid repetitious comments
        return `${goType(n.types[0], 'g')}`
      }
      if (nm == 'textDocument/documentSymbol') {
        return `${goType(n.types[1], 'h')} ${help}`
      }
      if (aa == 'TypeReference' && bb == 'ArrayType' && cc == 'NullKeyword') {
        return `${goType(n.types[0], 'd')} ${help}`
      }
      if (aa == 'TypeReference' && bb == aa && cc == 'ArrayType') {
        // should check that this is Hover.Contents
        return `${goType(n.types[0], 'e')} ${help}`
      }
      if (aa == 'ArrayType' && bb == 'TypeReference' && cc == 'NullKeyword') {
        // check this is nm == 'textDocument/completion'
        return `${goType(n.types[1], 'f')} ${help}`
      }
      if (aa == 'LiteralType' && bb == aa && cc == aa) return `string ${help}`;
      break;
    case 4:
      if (nm == 'documentChanges') return `TextDocumentEdit ${help} `;
    default:
      throw new Error(`goUnionType ${n.types.length} `)
  }

  // Result will be interface{} with a comment
  let isLiteral = true;
  let literal = 'string';
  let res = `interface{ } /* `
  n.types.forEach((v: ts.TypeNode, i: number) => {
    // might get an interface inside:
    //  (Command | CodeAction)[] | null
    let m = goType(v, nm);
    if (m.indexOf('interface') != -1) {
      // avoid nested comments
      m = m.split(' ')[0];
    }
    m = m.split('\n').join('; ')  // sloppy: struct{;
    res = res.concat(`${i == 0 ? '' : ' | '}`, m)
    if (!ts.isLiteralTypeNode(v)) isLiteral = false;
    else literal = strKind(v.literal) == 'StringLiteral' ? 'string' : 'number';
  });
  if (!isLiteral) {
    return res + '*/';
  }
  // trace?: 'off' | 'messages' | 'verbose' should get string
  return `${literal} /* ${n.getText()} */`
}

// some of the intersection types A&B are ok as struct{A;B;} and some
// could be expanded, and ClientCapabilites has to be expanded,
// at least for workspace. It's possible to check algorithmically,
// but much simpler just to check explicity.
function goIntersectionType(n: ts.IntersectionTypeNode, nm: string): string {
  if (nm == 'ClientCapabilities') return expandIntersection(n);
  if (nm == 'ServerCapabilities') return expandIntersection(n);
  let inner = '';
  n.types.forEach(
      (t: ts.TypeNode) => {inner = inner.concat(goType(t, nm), '\n')});
  return `struct{ \n${inner}} `
}

// for each of the itersected types, extract its components (each will
// have a Data with properties) extract the properties, and keep track
// of them by name. The names that occur once can be output. The names
// that occur more than once need to be combined.
function expandIntersection(n: ts.IntersectionTypeNode): string {
  const bad = function(n: ts.Node, s: string) {
    return new Error(`expandIntersection ${strKind(n)} ${s}`)
  };
  let props = new Map<string, ts.PropertySignature[]>();
  for (const tp of n.types) {
    if (!ts.isTypeReferenceNode(tp)) throw bad(tp, 'A');
    const d = data.get(goName(tp.typeName.getText()));
    for (const p of d.properties) {
      if (!ts.isPropertySignature(p)) throw bad(p, 'B');
      let v = props.get(p.name.getText()) || [];
      v.push(p);
      props.set(p.name.getText(), v);
    }
  }
  let ans = 'struct {\n';
  for (const [k, v] of Array.from(props)) {
    if (v.length == 1) {
      const a = v[0];
      ans = ans.concat(getComments(a));
      ans = ans.concat(`${goName(k)} ${goType(a.type, k)} ${u.JSON(a)}\n`)
      continue
    }
    ans = ans.concat(`${goName(k)} struct {\n`)
    for (let i = 0; i < v.length; i++) {
      const a = v[i];
      if (ts.isTypeReferenceNode(a.type)) {
        ans = ans.concat(getComments(a))
        ans = ans.concat(goName(a.type.typeName.getText()), '\n');
      } else if (ts.isTypeLiteralNode(a.type)) {
        if (a.type.members.length != 1) throw bad(a.type, 'C');
        const b = a.type.members[0];
        if (!ts.isPropertySignature(b)) throw bad(b, 'D');
        ans = ans.concat(getComments(b));
        ans = ans.concat(
            goName(b.name.getText()), ' ', goType(b.type, 'a'), u.JSON(b), '\n')
      } else if (a.type.kind == ts.SyntaxKind.ObjectKeyword) {
        ans = ans.concat(getComments(a))
        ans = ans.concat(
            goName(a.name.getText()), ' ', 'interface{}', u.JSON(a), '\n')
      } else {
        throw bad(a.type, `E ${a.getText()} in ${goName(k)} at ${loc(a)}`)
      }
    }
    ans = ans.concat('}\n');
  }
  ans = ans.concat('}\n');
  return ans
}

function goTypeLiteral(n: ts.TypeLiteralNode, nm: string): string {
  let ans: string[] = [];  // in case we generate a new extra type
  let res = 'struct{\n'    // the actual answer usually
  const g = function(nx: ts.TypeElement) {
    // add the json, as in goInterface(). Strange inside union types.
    if (ts.isPropertySignature(nx)) {
      let json = u.JSON(nx);
      let typ = goType(nx.type, nx.name.getText())
      const v = getComments(nx) || '';
      starred.forEach(([a, b]) => {
        if (a != nm || b != typ.toLowerCase()) return;
        typ = '*' + typ;
        json = json.substring(0, json.length - 2) + ',omitempty"`'
      })
      res = res.concat(`${v} ${goName(nx.name.getText())} ${typ}`, json, '\n')
      ans.push(`${v}${goName(nx.name.getText())} ${typ} ${json}\n`)
    } else if (ts.isIndexSignatureDeclaration(nx)) {
      if (nx.getText() == '[uri: string]: TextEdit[];') {
        res = 'map[string][]TextEdit';
        ans.push(`map[string][]TextEdit`);  // this is never used
        return
      }
      throw new Error(` handle ${nx.getText()}`)
    } else
      throw new Error(`TypeLiteral had ${strKind(nx)}`)
  };
  n.members.forEach(g)
  // for some the generated type is wanted, for others it's not needed
  if (!nm.startsWith('workspace')) {
    if (res.startsWith('struct')) return res + '}';  // map[] is special
    return res
  }
  extraTypes.set(goName(nm) + 'Gn', ans)
  return goName(nm) + 'Gn'
}

// print all the types and constants and extra types
function outputTypes() {
  // generate go types alphabeticaly
  let v = Array.from(seenTypes.keys());
  v.sort();
  v.forEach((x) => toGo(seenTypes.get(x), x))
  u.prgo(u.computeHeader(true))
  typesOut.forEach((s) => {
    u.prgo(s);
    // it's more convenient not to have to think about trailing newlines
    // when generating types, but doc comments can't have an extra \n
    if (s.indexOf('/**') < 0) u.prgo('\n');
  })
  u.prgo('\nconst (\n');
  constsOut.forEach((s) => {
    u.prgo(s);
    u.prgo('\n')
  })
  u.prgo(')\n');
  u.prgo('// Types created to name formal parameters and embedded structs\n')
  extraTypes.forEach((v, k) => {
    u.prgo(` type ${k} struct {\n`)
    v.forEach((s) => {
      u.prgo(s);
      u.prgo('\n')
    });
    u.prgo('}\n')
  });
}

// client and server ------------------

interface side {
  methods: string[];
  cases: string[];
  calls: string[];
  name: string;    // client or server
  goName: string;  // Client or Server
  outputFile?: string;
  fd?: number
}
let client: side = {
  methods: [],
  cases: [],
  calls: [],
  name: 'client',
  goName: 'Client',
};
let server: side = {
  methods: [],
  cases: [],
  calls: [],
  name: 'server',
  goName: 'Server',
};

// commonly used output
const notNil = `if r.Params != nil {
  r.Reply(ctx, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params"))
  return true
}`;

// Go code for notifications. Side is client or server, m is the request
// method
function goNot(side: side, m: string) {
  if (m == '$/cancelRequest') return;  // handled specially in protocol.go
  const n = not.get(m);
  const a = goType(n.typeArguments[0], m);
  const nm = methodName(m);
  side.methods.push(sig(nm, a, ''));
  const caseHdr = ` case "${m}":  // notif`;
  let case1 = notNil;
  if (a != '' && a != 'void') {
    case1 = `var params ${a}
    if err := json.Unmarshal(*r.Params, &params); err != nil {
      sendParseError(ctx, r, err)
      return true
    }
    if err := h.${side.name}.${nm}(ctx, &params); err != nil {
      log.Error(ctx, "", err)
    }
    return true`;
  } else {
    case1 = `if err := h.${side.name}.${nm}(ctx); err != nil {
      log.Error(ctx, "", err)
    }
    return true`;
  }
  side.cases.push(`${caseHdr}\n${case1}`);

  const arg3 = a == '' || a == 'void' ? 'nil' : 'params';
  side.calls.push(`
  func (s *${side.name}Dispatcher) ${sig(nm, a, '', true)} {
    return s.Conn.Notify(ctx, "${m}", ${arg3})
  }`);
}

// Go code for requests.
function goReq(side: side, m: string) {
  const n = req.get(m);
  const nm = methodName(m);
  if (nm.indexOf('/') >= 0) {
    console.log(`980 ${m} ${n.getText()} ${loc(n)} `)
  }
  let a = goType(n.typeArguments[0], m);
  let b = goType(n.typeArguments[1], m);
  if (n.getText().includes('Type0')) {
    b = a;
    a = '';  // workspace/workspaceFolders and shutdown
  }
  u.prb(`${side.name} req ${a != ''}, ${b != ''} ${nm} ${m} ${loc(n)} `)
  side.methods.push(sig(nm, a, b));

  const caseHdr = `case "${m}": // req`;
  let case1 = notNil;
  if (a != '') {
    if (extraTypes.has('Param' + nm)) a = 'Param' + nm
      case1 = `var params ${a}
    if err := json.Unmarshal(*r.Params, &params); err != nil {
      sendParseError(ctx, r, err)
      return true
    }`;
  }
  const arg2 = a == '' ? '' : ', &params';
  let case2 = `if err := h.${side.name}.${nm}(ctx${arg2}); err != nil {
    log.Error(ctx, "", err)
  }`;
  if (b != '' && b != 'void') {
    case2 = `resp, err := h.${side.name}.${nm}(ctx${arg2})
    if err := r.Reply(ctx, resp, err); err != nil {
      log.Error(ctx, "", err)
    }
    return true`;
  } else {  // response is nil
    case2 = `err := h.${side.name}.${nm}(ctx${arg2})
    if err := r.Reply(ctx, nil, err); err != nil {
      log.Error(ctx, "", err)
    }
    return true`
  }

  side.cases.push(`${caseHdr}\n${case1}\n${case2}`);

  const callHdr = `func (s *${side.name}Dispatcher) ${sig(nm, a, b, true)} {`;
  let callBody = `return s.Conn.Call(ctx, "${m}", nil, nil)\n}`;
  if (b != '' && b != 'void') {
    const p2 = a == '' ? 'nil' : 'params';
    let theRet = `result`;
    if (indirect(b)) theRet = '&result';
    callBody = `var result ${b}
			if err := s.Conn.Call(ctx, "${m}", ${
        p2}, &result); err != nil {
				return nil, err
      }
      return ${theRet}, nil
    }`;
  } else if (a != '') {
    callBody = `return s.Conn.Call(ctx, "${m}", params, nil) // Call, not Notify
  }`
  }
  side.calls.push(`${callHdr}\n${callBody}\n`);
}

// make sure method names are unique
let seenNames = new Set<string>();
function methodName(m: string): string {
  let i = m.indexOf('/');
  let s = m.substring(i + 1);
  let x = s[0].toUpperCase() + s.substring(1);
  const j = x.indexOf('/')
  if (j >= 0) {
    let suffix = x.substring(j + 1)
    suffix = suffix[0].toUpperCase() + suffix.substring(1)
    let prefix = x.substring(0, j)
    x = prefix + suffix
  }
  if (seenNames.has(x)) {
    // Resolve, ResolveCodeLens, ResolveDocumentLink
    if (!x.startsWith('Resolve')) throw new Error(`expected Resolve, not ${x}`)
      x += m[0].toUpperCase() + m.substring(1, i)
  }
  seenNames.add(x);
  return x;
}

// used in sig and in goReq
function indirect(s: string): boolean {
  if (s == '' || s == 'void') return false;
  const skip = (x: string) => s.startsWith(x);
  if (skip('[]') || skip('interface') || skip('Declaration') ||
      skip('Definition') || skip('DocumentSelector'))
    return false;
  return true
}

// Go signatures for methods.
function sig(nm: string, a: string, b: string, names?: boolean): string {
  if (a.indexOf('struct') != -1) {
    const v = a.split('\n')
    extraTypes.set(`Param${nm}`, v.slice(1, v.length - 1))
    a = 'Param' + nm
  }
  if (a == 'void')
    a = '';
  else if (a != '') {
    if (names)
      a = ', params *' + a;
    else
      a = ', *' + a;
  }
  let ret = 'error';
  if (b != '' && b != 'void') {
    // avoid * when it is senseless
    if (indirect(b)) b = '*' + b;
    ret = `(${b}, error)`;
  }
  let start = `${nm}(`;
  if (names) {
    start = start + 'ctx ';
  }
  return `${start}context.Context${a}) ${ret}`;
}

// write the request/notification code
function output(side: side) {
  // make sure the output file exists
  if (!side.outputFile) {
    side.outputFile = `ts${side.name}.go`;
    side.fd = fs.openSync(side.outputFile, 'w');
  }
  const f = function(s: string) {
    fs.writeSync(side.fd, s);
    fs.writeSync(side.fd, '\n');
  };
  f(u.computeHeader(false));
  f(`
        import (
          "context"
          "encoding/json"

          "golang.org/x/tools/internal/jsonrpc2"
          "golang.org/x/tools/internal/telemetry/log"
          "golang.org/x/tools/internal/xcontext"
        )
        `);
  const a = side.name[0].toUpperCase() + side.name.substring(1)
  f(`type ${a} interface {`);
  side.methods.forEach((v) => {f(v)});
  f('}\n');
  f(`func (h ${
      side.name}Handler) Deliver(ctx context.Context, r *jsonrpc2.Request, delivered bool) bool {
            if delivered {
              return false
            }
            if ctx.Err() != nil {
              ctx := xcontext.Detach(ctx)
              r.Reply(ctx, nil, jsonrpc2.NewErrorf(RequestCancelledError, ""))
              return true
            }
            switch r.Method {`);
  side.cases.forEach((v) => {f(v)});
  f(`
        }
      }`);
  f(`
        type ${side.name}Dispatcher struct {
          *jsonrpc2.Conn
        }
        `);
  side.calls.forEach((v) => {f(v)});
}

// Handling of non-standard requests, so we can add gopls-specific calls.
function nonstandardRequests() {
  server.methods.push(
      'NonstandardRequest(ctx context.Context, method string, params interface{}) (interface{}, error)')
  server.calls.push(
      `func (s *serverDispatcher) NonstandardRequest(ctx context.Context, method string, params interface{}) (interface{}, error) {
      var result interface{}
      if err := s.Conn.Call(ctx, method, params, &result); err != nil {
        return nil, err
      }
      return result, nil
    }
  `)
  client.cases.push(`default:
    return false`)
  server.cases.push(`default:
  var params interface{}
  if err := json.Unmarshal(*r.Params, &params); err != nil {
    sendParseError(ctx, r, err)
    return true
  }
  resp, err := h.server.NonstandardRequest(ctx, r.Method, params)
  if err := r.Reply(ctx, resp, err); err != nil {
    log.Error(ctx, "", err)
  }
  return true
`)
}

// ----- remember it's a scripting language
function main() {
  if (u.gitHash != u.git()) {
    throw new Error(
        `git hash mismatch, wanted\n${u.gitHash} but source is at\n${u.git()}`);
  }
  u.createOutputFiles()
  parse()
  u.printAST(program)
  // find the Requests and Nofificatations
  for (const sourceFile of program.getSourceFiles()) {
    if (!sourceFile.isDeclarationFile) {
      ts.forEachChild(sourceFile, findRPCs)
    }
  }
  // separate RPCs into client and server
  setReceives();
  // visit every sourceFile collecting top-level type definitions
  for (const sourceFile of program.getSourceFiles()) {
    if (!sourceFile.isDeclarationFile) {
      ts.forEachChild(sourceFile, genTypes)
    }
  }
  // check that each thing occurs exactly once, and put pointers into
  // seenTypes
  checkOnce();
  // for each of Client and Server there are 3 parts to the output:
  // 1. type X interface {methods}
  // 2. func (h *serverHandler) Deliver(...) { switch r.method }
  // 3. func (x *xDispatcher) Method(ctx, parm)
  not.forEach(  // notifications
      (v, k) => {
          receives.get(k) == 'client' ? goNot(client, k) : goNot(server, k)});
  req.forEach(  // requests
      (v, k) => {
          receives.get(k) == 'client' ? goReq(client, k) : goReq(server, k)});
  nonstandardRequests();
  // find all the types implied by seenTypes and rpcs to try to avoid
  // generating types that aren't used
  moreTypes();
  // and print the Go code
  outputTypes()
  console.log(`seen ${seenTypes.size + extraTypes.size}`)
  output(client);
  output(server);
}

main()