(*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *)

(* In order to minimize the frequency with which we unnecessarily compare
   equivalent structures, we assign structures created at the top level of a
   source program an id of their location instead of an int. This way, if we
   see the structure twice between the merge and check phases, we consider them
   equal just by looking at their ids *)
type id =
  | Source of ALoc.id
  | Generated of int

let compare_id a b =
  match (a, b) with
  | (Source a, Source b) -> ALoc.quick_compare (a :> ALoc.t) (b :> ALoc.t)
  | (Generated a, Generated b) -> a - b
  | (Source _, Generated _) -> -1
  | (Generated _, Source _) -> 1

let equal_id a b = compare_id a b = 0

let generate_id () = Generated (Reason.mk_id ())

let id_of_aloc_id aloc_id = Source aloc_id

let string_of_id = function
  | Generated id -> string_of_int id
  | Source id -> Reason.string_of_aloc (id :> ALoc.t)
