content: {-
    Copyright (c) Meta Platforms, Inc. and affiliates.
    All rights reserved.
  
    This source code is licensed under the BSD-style license found in the
    LICENSE file in the root directory of this source tree.
  -}
  
  {-# LANGUAGE TypeApplications #-}
  module Glean.Util.ToAngle
    ( ToAngle(..)
    , ToAngleFull(..)
    , Normalize(..)
    , Prune(..)
    ) where
  
  import Glean
  import Glean.Angle
  
  import qualified Glean.Schema.Anglelang.Types as Anglelang
  import qualified Glean.Schema.Src.Types as Src
  import qualified Glean.Schema.Csharp.Types as CSharp
  import qualified Glean.Schema.Cxx1.Types as Cxx
  import qualified Glean.Schema.Erlang.Types as Erlang
  import qualified Glean.Schema.Fbthrift.Types as Fbthrift
  import qualified Glean.Schema.Flow.Types as Flow
  import qualified Glean.Schema.Graphql.Types as GraphQL
  import qualified Glean.Schema.Hack.Types as Hack
  import qualified Glean.Schema.JavaAlpha.Types as Java
  import qualified Glean.Schema.KotlinAlpha.Types as Kotlin
  import qualified Glean.Schema.Lsif.Types as Lsif
  import qualified Glean.Schema.Python.Types as Py
  import qualified Glean.Schema.Scip.Types as Scip
  
  import qualified Glean.Schema.CodeAnglelang.Types as Anglelang
  import qualified Glean.Schema.Code.Types as Code
  import qualified Glean.Schema.CodeHack.Types as Hack
  import qualified Glean.Schema.CodePython.Types as Py
  import qualified Glean.Schema.CodeCxx.Types as Cxx
  import qualified Glean.Schema.CodeGraphql.Types as GraphQL
  import qualified Glean.Schema.CodePp.Types as Pp
  import qualified Glean.Schema.CodeBuck.Types as Buck
  import qualified Glean.Schema.CodeFlow.Types as Flow
  import qualified Glean.Schema.CodeFbthrift.Types as Fbthrift
  import qualified Glean.Schema.CodeHs.Types as Hs
  import Data.Text (Text)
  
  class ToAngle a where
    -- | Convert a value to a query for that value. Useful when we want to
    -- use a result we got back from a query in another query.
    --
    -- Returns a shallow query and will use fact IDs instead
    -- of matching by structure, so the resulting query only works on the
    -- same DB that the value was obtained from. See also toAngleFull.
    toAngle :: a -> Angle a
  
  class ToAngleFull a where
    -- | Convert a value to a query for that value. Useful when we want to
    -- use a result we got back from a query in another query.
    --
    -- Return deep queries, provided the parameter is fully
    -- resolved. Useful for querying a different db from the one the value
    -- was obtained. See also toAngle.
    toAngleFull :: a -> Angle a
  
  class Normalize a where
    -- | Return a canonical representation of Glean fact where
    -- identifiers are replaced with 0. Useful for comparing facts generated
    -- from different dbs, as long as the facts are fully computed (all keys
    -- are present).
    normalize :: a -> a
  
  instance Normalize Glean.Id where
    normalize _ = 0
  
  -- | Prune keys, leaving only fact IDs. Useful for hashing values cheaply.
  class Prune a where
    prune :: a -> a
  
  instance Prune Code.Entity where
    prune e = case e of
      Code.Entity_hack (Hack.Entity_decl x) ->
        Code.Entity_hack (Hack.Entity_decl (prune x))
      Code.Entity_python (Py.Entity_decl x) ->
        Code.Entity_python (Py.Entity_decl (prune x))
      Code.Entity_cxx x ->
        Code.Entity_cxx (prune x)
      x -> x
  
  -- | Generically get an Angle key query
  mkKey :: Glean.Predicate p => p -> Angle (Glean.KeyType p)
  mkKey x = asPredicate (factId (Glean.getId x))
  
  -- Haskell types
  
  instance Normalize Nat where
    normalize = id
  
  instance Normalize Bool where
    normalize = id
  
  -- Src
  
  instance Normalize Src.FileLocation where
    normalize (Src.FileLocation x y) =
      Src.FileLocation (normalize x) (normalize y)
  
  instance Normalize Src.ByteSpan where
    normalize (Src.ByteSpan x y) =
      Src.ByteSpan (normalize x) (normalize y)
  
  instance Normalize Src.Range where
    normalize (Src.Range a b c d e) =
      Src.Range
        (normalize a)
        (normalize b)
        (normalize c)
        (normalize d)
        (normalize e)
  
  -- C pre-processor
  
  instance ToAngle Pp.Entity where
    toAngle e = case e of
      Pp.Entity_define x -> alt @"define" (mkKey x)
      Pp.Entity_undef x -> alt @"undef" (mkKey x)
      Pp.Entity_include_ x -> alt @"include_" (mkKey x)
      Pp.Entity_EMPTY -> error "unknown code.pp.Entity"
  
  -- Cxx
  
  instance ToAngle Cxx.Entity where
    toAngle e = case e of
      Cxx.Entity_decl x -> alt @"decl" (toAngle x)
      Cxx.Entity_defn x -> alt @"defn" (toAngle x)
      Cxx.Entity_enumerator x -> alt @"enumerator" (mkKey x)
      Cxx.Entity_objcSelectorSlot x -> alt @"objcSelectorSlot" (toAngle x)
      Cxx.Entity_EMPTY -> error "unknown Entity"
  
  instance Prune Cxx.Entity where
    prune e = case e of
      Cxx.Entity_decl x ->
        Cxx.Entity_decl (prune x)
      Cxx.Entity_defn x ->
        Cxx.Entity_defn (prune x)
      Cxx.Entity_enumerator x ->
        Cxx.Entity_enumerator (mkFact (getId x) Nothing Nothing)
      Cxx.Entity_objcSelectorSlot x ->
        Cxx.Entity_objcSelectorSlot x
      Cxx.Entity_EMPTY -> error "unknown Entity"
  
  instance ToAngle Cxx.Declaration where
    toAngle e = case e of
      Cxx.Declaration_namespace_ x -> alt @"namespace_" (mkKey x)
      Cxx.Declaration_usingDeclaration x -> alt @"usingDeclaration" (mkKey x)
      Cxx.Declaration_usingDirective x -> alt @"usingDirective" (mkKey x)
      Cxx.Declaration_record_ x -> alt @"record_" (mkKey x)
      Cxx.Declaration_enum_ x -> alt @"enum_" (mkKey x)
      Cxx.Declaration_function_ x -> alt @"function_" (mkKey x)
      Cxx.Declaration_variable x -> alt @"variable" (mkKey x)
      Cxx.Declaration_objcContainer x -> alt @"objcContainer" (mkKey x)
      Cxx.Declaration_objcMethod x -> alt @"objcMethod" (mkKey x)
      Cxx.Declaration_objcProperty x -> alt @"objcProperty" (mkKey x)
      Cxx.Declaration_typeAlias x -> alt @"typeAlias" (mkKey x)
      Cxx.Declaration_namespaceAlias x -> alt @"namespaceAlias" (mkKey x)
      Cxx.Declaration_EMPTY -> error "unknown Declaration"
  
  instance Prune Cxx.Declaration where
    prune e = case e of
      Cxx.Declaration_namespace_ x ->
        Cxx.Declaration_namespace_ (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_usingDeclaration x ->
        Cxx.Declaration_usingDeclaration (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_usingDirective x ->
        Cxx.Declaration_usingDirective (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_record_ x ->
        Cxx.Declaration_record_ (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_enum_ x ->
        Cxx.Declaration_enum_ (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_function_ x ->
        Cxx.Declaration_function_ (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_variable x ->
        Cxx.Declaration_variable (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_objcContainer x ->
        Cxx.Declaration_objcContainer (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_objcMethod x ->
        Cxx.Declaration_objcMethod (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_objcProperty x ->
        Cxx.Declaration_objcProperty (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_typeAlias x ->
        Cxx.Declaration_typeAlias (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_namespaceAlias x ->
        Cxx.Declaration_namespaceAlias (mkFact (getId x) Nothing Nothing)
      Cxx.Declaration_EMPTY -> error "unknown Declaration"
  
  instance ToAngle Cxx.Definition where
    toAngle e = case e of
      Cxx.Definition_record_ x -> alt @"record_" (mkKey x)
      Cxx.Definition_function_ x -> alt @"function_" (mkKey x)
      Cxx.Definition_enum_ x -> alt @"enum_" (mkKey x)
      Cxx.Definition_objcMethod x -> alt @"objcMethod" (mkKey x)
      Cxx.Definition_objcContainer x -> alt @"objcContainer" (mkKey x)
      Cxx.Definition_variable x -> alt @"variable" (mkKey x)
      Cxx.Definition_namespace_ x -> alt @"namespace_" (mkKey x)
      Cxx.Definition_EMPTY -> error "unknown Definition"
  
  instance Prune Cxx.Definition where
    prune e = case e of
      Cxx.Definition_record_ x ->
        Cxx.Definition_record_ (mkFact (getId x) Nothing Nothing)
      Cxx.Definition_function_ x ->
        Cxx.Definition_function_ (mkFact (getId x) Nothing Nothing)
      Cxx.Definition_enum_ x ->
        Cxx.Definition_enum_ (mkFact (getId x) Nothing Nothing)
      Cxx.Definition_objcMethod x ->
        Cxx.Definition_objcMethod (mkFact (getId x) Nothing Nothing)
      Cxx.Definition_objcContainer x ->
        Cxx.Definition_objcContainer (mkFact (getId x) Nothing Nothing)
      Cxx.Definition_variable x ->
        Cxx.Definition_variable (mkFact (getId x) Nothing Nothing)
      Cxx.Definition_namespace_ x ->
        Cxx.Definition_namespace_ (mkFact (getId x) Nothing Nothing)
      Cxx.Definition_EMPTY -> error "unknown Definition"
  
  instance ToAngle Cxx.ObjcMethodEntity where
    toAngle e = case e of
      Cxx.ObjcMethodEntity_decl x -> alt @"decl" (mkKey x)
      Cxx.ObjcMethodEntity_defn x -> alt @"defn" (mkKey x)
      Cxx.ObjcMethodEntity_EMPTY -> error "unknown ObjcMethodEntity"
  
  instance ToAngle Cxx.ObjcSelectorSlotEntity where
    toAngle (Cxx.ObjcSelectorSlotEntity method idx) =
      rec $
        field @"objcMethod" (toAngle method) $
        field @"index" (nat $ fromNat idx)
      end
  
  instance Normalize Cxx.Declaration where
    normalize (Cxx.Declaration_objcContainer x) =
      Cxx.Declaration_objcContainer $ normalize x
    normalize (Cxx.Declaration_objcMethod x) =
      Cxx.Declaration_objcMethod $ normalize x
    normalize (Cxx.Declaration_objcProperty x) =
      Cxx.Declaration_objcProperty $ normalize x
    normalize (Cxx.Declaration_record_ x) =
      Cxx.Declaration_record_ $ normalize x
    normalize (Cxx.Declaration_enum_ x) =
      Cxx.Declaration_enum_ $ normalize x
    normalize (Cxx.Declaration_function_ x) =
      Cxx.Declaration_function_ $ normalize x
    normalize Cxx.Declaration_EMPTY = error "unknown Declaration"
    normalize _ = error "expected Objc Declaration"
  
  instance Normalize Cxx.RecordDeclaration where
    normalize (Cxx.RecordDeclaration x y) =
      Cxx.RecordDeclaration (normalize x) (normalize y)
  
  instance Normalize Cxx.RecordDeclaration_key where
    normalize (Cxx.RecordDeclaration_key x y z) =
      Cxx.RecordDeclaration_key (normalize x) (normalize y) (normalize z)
  
  instance Normalize Cxx.EnumDeclaration where
    normalize (Cxx.EnumDeclaration x y) =
      Cxx.EnumDeclaration (normalize x) (normalize y)
  
  instance Normalize Cxx.EnumDeclaration_key where
    normalize (Cxx.EnumDeclaration_key x y z t) =
      Cxx.EnumDeclaration_key
        (normalize x)
        (normalize y)
        (normalize z)
        (normalize t)
  
  instance Normalize Cxx.FunctionDeclaration where
    normalize (Cxx.FunctionDeclaration x y) =
      Cxx.FunctionDeclaration (normalize x) (normalize y)
  
  instance Normalize Cxx.FunctionDeclaration_key where
    normalize (Cxx.FunctionDeclaration_key x y z t) =
      Cxx.FunctionDeclaration_key
        (normalize x)
        (normalize y)
        (normalize z)
        (normalize t)
  
  instance Normalize Cxx.QName where
    normalize (Cxx.QName x y) = Cxx.QName (normalize x) (normalize y)
  
  instance Normalize Cxx.QName_key where
    normalize (Cxx.QName_key x y) =
      Cxx.QName_key (normalize x) (normalize y)
  
  instance Normalize Cxx.Scope where
    normalize (Cxx.Scope_namespace_ x) = Cxx.Scope_namespace_ (normalize x)
    normalize (Cxx.Scope_recordWithAccess x) =
      Cxx.Scope_recordWithAccess (normalize x)
    normalize (Cxx.Scope_global_ x) = Cxx.Scope_global_ x
    normalize (Cxx.Scope_local x) = Cxx.Scope_local (normalize x)
    normalize Cxx.Scope_EMPTY = error "unknown Scope"
  
  instance Normalize Cxx.Scope_recordWithAccess_ where
    normalize (Cxx.Scope_recordWithAccess_ x y) =
      Cxx.Scope_recordWithAccess_ (normalize x) (normalize y)
  
  instance Normalize Cxx.NamespaceQName where
    normalize (Cxx.NamespaceQName x y) =
      Cxx.NamespaceQName (normalize x) (normalize y)
  
  instance Normalize Cxx.NamespaceQName_key where
    normalize (Cxx.NamespaceQName_key x y) =
      Cxx.NamespaceQName_key (normalize x) (normalize y)
  
  instance Normalize Cxx.FunctionQName where
    normalize (Cxx.FunctionQName x y) =
      Cxx.FunctionQName (normalize x) (normalize y)
  
  instance Normalize Cxx.FunctionQName_key where
    normalize (Cxx.FunctionQName_key x y) =
      Cxx.FunctionQName_key (normalize x) (normalize y)
  
  instance Normalize Cxx.FunctionName where
    normalize (Cxx.FunctionName x y) =
      Cxx.FunctionName (normalize x) (normalize y)
  
  instance Normalize Cxx.FunctionName_key where
    normalize (Cxx.FunctionName_key_name x) =
      Cxx.FunctionName_key_name (normalize x)
    normalize (Cxx.FunctionName_key_operator_ x) =
      Cxx.FunctionName_key_operator_ (normalize x)
    normalize (Cxx.FunctionName_key_literalOperator x) =
      Cxx.FunctionName_key_literalOperator (normalize x)
    normalize (Cxx.FunctionName_key_constructor x) =
      Cxx.FunctionName_key_constructor x
    normalize (Cxx.FunctionName_key_destructor x) =
      Cxx.FunctionName_key_destructor x
    normalize (Cxx.FunctionName_key_conversionOperator x) =
      Cxx.FunctionName_key_conversionOperator (normalize x)
    normalize Cxx.FunctionName_key_EMPTY = error "unknown FunctionName"
  
  instance Normalize Cxx.RecordKind where
    normalize (Cxx.RecordKind_struct_ x) = Cxx.RecordKind_struct_ x
    normalize (Cxx.RecordKind_class_ x) = Cxx.RecordKind_class_ x
    normalize (Cxx.RecordKind_union_ x) = Cxx.RecordKind_union_ x
    normalize Cxx.RecordKind_EMPTY = error "unknown RecordKind"
  
  instance Normalize Cxx.MethodSignature where
    normalize (Cxx.MethodSignature x y z t) =
      Cxx.MethodSignature
        (normalize x)
        (normalize y)
        (normalize z)
        (normalize t)
  
  instance Normalize Cxx.RefQualifier where
    normalize Cxx.RefQualifier_None_ = Cxx.RefQualifier_None_
    normalize Cxx.RefQualifier_LValue = Cxx.RefQualifier_LValue
    normalize Cxx.RefQualifier_RValue = Cxx.RefQualifier_RValue
    normalize (Cxx.RefQualifier__UNKNOWN _) = error "unknown RefQualifier"
  
  instance Normalize Cxx.Access where
    normalize Cxx.Access_Public = Cxx.Access_Public
    normalize Cxx.Access_Private = Cxx.Access_Private
    normalize Cxx.Access_Protected = Cxx.Access_Protected
    normalize (Cxx.Access__UNKNOWN _) = error "unknown Access"
  
  instance Normalize Cxx.ObjcContainerDeclaration where
    normalize (Cxx.ObjcContainerDeclaration x y) =
      Cxx.ObjcContainerDeclaration (normalize x) (normalize y)
  
  instance Normalize Cxx.ObjcMethodDeclaration where
    normalize (Cxx.ObjcMethodDeclaration x y) =
      Cxx.ObjcMethodDeclaration (normalize x) (normalize y)
  
  instance Normalize Cxx.ObjcPropertyDeclaration where
    normalize (Cxx.ObjcPropertyDeclaration x y) =
      Cxx.ObjcPropertyDeclaration (normalize x) (normalize y)
  
  instance Normalize Cxx.ObjcContainerDeclaration_key where
    normalize (Cxx.ObjcContainerDeclaration_key x y) =
      Cxx.ObjcContainerDeclaration_key
        (normalize x)
        (normalize y)
  
  instance Normalize Cxx.ObjcMethodDeclaration_key where
    normalize (Cxx.ObjcMethodDeclaration_key a b c d e f g h) =
      Cxx.ObjcMethodDeclaration_key
        (normalize a)
        (normalize b)
        (normalize c)
        (normalize d)
        (normalize e)
        (normalize f)
        (normalize g)
        (normalize h)
  
  instance Normalize Cxx.ObjcPropertyDeclaration_key where
    normalize (Cxx.ObjcPropertyDeclaration_key a b c d e f g h) =
      Cxx.ObjcPropertyDeclaration_key
        (normalize a)
        (normalize b)
        (normalize c)
        (normalize d)
        (normalize e)
        (normalize f)
        (normalize g)
        (normalize h)
  
  instance Normalize Cxx.ObjcContainerId where
    normalize (Cxx.ObjcContainerId_protocol x) =
      Cxx.ObjcContainerId_protocol (normalize x)
    normalize (Cxx.ObjcContainerId_interface_ x) =
      Cxx.ObjcContainerId_interface_ (normalize x)
    normalize (Cxx.ObjcContainerId_implementation x) =
      Cxx.ObjcContainerId_implementation (normalize x)
    normalize (Cxx.ObjcContainerId_categoryInterface x) =
      Cxx.ObjcContainerId_categoryInterface (normalize x)
    normalize (Cxx.ObjcContainerId_extensionInterface x) =
      Cxx.ObjcContainerId_extensionInterface (normalize x)
    normalize (Cxx.ObjcContainerId_categoryImplementation x) =
      Cxx.ObjcContainerId_categoryImplementation (normalize x)
    normalize Cxx.ObjcContainerId_EMPTY = error "unknown ObjcContainerId"
  
  instance Normalize Cxx.ObjcCategoryId where
    normalize (Cxx.ObjcCategoryId x y) =
      Cxx.ObjcCategoryId (normalize x) (normalize y)
  
  instance Normalize Cxx.ObjcSelector where
    normalize (Cxx.ObjcSelector x y) =
      Cxx.ObjcSelector (normalize x) (normalize y)
  
  instance Normalize Cxx.Name where
    normalize (Cxx.Name x y) = Cxx.Name (normalize x) (normalize y)
  
  instance Normalize Cxx.Type where
    normalize (Cxx.Type x y) = Cxx.Type (normalize x) (normalize y)
  
  instance Normalize Cxx.Signature where
    normalize (Cxx.Signature x y) = Cxx.Signature (normalize x) (normalize y)
  
  instance Normalize Cxx.Signature_key where
    normalize (Cxx.Signature_key x y) =
      Cxx.Signature_key (normalize x) (normalize y)
  
  instance Normalize Cxx.Parameter where
    normalize (Cxx.Parameter x y) = Cxx.Parameter (normalize x) (normalize y)
  
  instance ToAngleFull Cxx.Declaration where
    toAngleFull
        (Cxx.Declaration_objcContainer (Cxx.ObjcContainerDeclaration _ (Just x))) =
      alt @"objcContainer" (toAngleFull x)
    toAngleFull
        (Cxx.Declaration_objcMethod (Cxx.ObjcMethodDeclaration _ (Just x))) =
      alt @"objcMethod" (toAngleFull x)
    toAngleFull
        (Cxx.Declaration_objcProperty (Cxx.ObjcPropertyDeclaration _ (Just x))) =
      alt @"objcProperty" (toAngleFull x)
    toAngleFull (Cxx.Declaration_record_ x) = alt @"record_" (mkKey x)
    toAngleFull (Cxx.Declaration_enum_ x) = alt @"enum_" (mkKey x)
    toAngleFull (Cxx.Declaration_function_ x) = alt @"function_" (mkKey x)
    toAngleFull Cxx.Declaration_EMPTY = error "unknown Declaration"
    toAngleFull _ = error "toAngleFull not implemented"
  
  instance ToAngleFull Cxx.ObjcContainerDeclaration_key where
    toAngleFull (Cxx.ObjcContainerDeclaration_key x y) =
      rec $
        field @"id" (toAngleFull x) $
        field @"source" (toAngleFull y)
      end
  
  instance ToAngleFull Cxx.ObjcMethodDeclaration_key where
    toAngleFull
        (Cxx.ObjcMethodDeclaration_key
          (Cxx.ObjcSelector _ (Just x)) _ z _ _ _ _ _) =
      rec $
        field @"selector" (toAngleFull x) $
        field @"container" (toAngleFull z)
      end
    toAngleFull _ = error "toAngleFull not implemented"
  
  instance ToAngleFull Cxx.ObjcPropertyDeclaration_key where
    toAngleFull
        (Cxx.ObjcPropertyDeclaration_key (Cxx.Name _ (Just x)) y _ _ _ _ _ _) =
      rec $
        field @"name" (toAngleFull x) $
        field @"container" (toAngleFull y)
      end
    toAngleFull _ = error "toAngleFull not implemented"
  
  instance ToAngleFull Cxx.ObjcContainerId where
    toAngleFull (Cxx.ObjcContainerId_protocol (Cxx.Name _ (Just x))) =
      alt @"protocol" (toAngleFull x)
    toAngleFull (Cxx.ObjcContainerId_interface_ (Cxx.Name _ (Just x))) =
      alt @"interface_" (toAngleFull x)
    toAngleFull (Cxx.ObjcContainerId_categoryInterface x) =
      alt @"categoryInterface" (toAngleFull x)
    toAngleFull (Cxx.ObjcContainerId_categoryImplementation x) =
      alt @"categoryImplementation" (toAngleFull x)
    toAngleFull (Cxx.ObjcContainerId_extensionInterface (Cxx.Name _ (Just x))) =
      alt @"extensionInterface" (toAngleFull x)
    toAngleFull (Cxx.ObjcContainerId_implementation (Cxx.Name _ (Just x))) =
      alt @"implementation" (toAngleFull x)
    toAngleFull Cxx.ObjcContainerId_EMPTY = error "unknown ObjcContainerId"
    toAngleFull _ = error "toAngleFull not implemented"
  
  instance ToAngleFull Cxx.ObjcCategoryId where
    toAngleFull (Cxx.ObjcCategoryId (Cxx.Name _ (Just x)) (Cxx.Name _ (Just y))) =
      rec $
        field @"className" (toAngleFull x) $
        field @"categoryName" (toAngleFull y)
      end
    toAngleFull _ = error "toAngleFull not implemented"
  
  instance ToAngleFull Src.Range where
    toAngleFull (Src.Range (Src.File _ (Just f)) x y z t) =
      rec $
        field @"file" (toAngleFull f) $
        field @"lineBegin" (toAngleFull x) $
        field @"columnBegin" (toAngleFull y) $
        field @"lineEnd" (toAngleFull z) $
        field @"columnEnd" (toAngleFull t)
      end
    toAngleFull _ = error "toAngleFull not implemented"
  
  instance ToAngleFull Nat where
    toAngleFull x = nat $ fromNat x
  
  instance ToAngleFull a => ToAngleFull [a] where
    toAngleFull = array . map toAngleFull
  
  -- Erlang
  
  instance ToAngle Erlang.Declaration where
    toAngle d = case d of
      Erlang.Declaration_func x -> alt @"func" (mkKey x)
      Erlang.Declaration_EMPTY -> error "unknown Declaration"
  
  -- Angle
  instance ToAngle Anglelang.Entity where
    toAngle e = rec $ field @"decl" (toAngle decl) end
      where decl = Anglelang.entity_decl e
  
  instance ToAngle Anglelang.Declaration where
    toAngle x = case x of
      Anglelang.Declaration_pred x -> alt @"pred" (mkKey x)
      Anglelang.Declaration_ty x -> alt @"ty" (mkKey x)
      Anglelang.Declaration_schema x -> alt @"schema" (mkKey x)
      Anglelang.Declaration_evolve x -> alt @"evolve" (mkKey x)
      Anglelang.Declaration_derive_ x -> alt @"derive_" (mkKey x)
      Anglelang.Declaration_imp x -> alt @"imp" (factId (Glean.getId x))
      Anglelang.Declaration_EMPTY -> error "unknown Declaration"
  
  -- Buck
  
  instance ToAngle Buck.Entity where
    toAngle e = case e of
      Buck.Entity_locator x -> alt @"locator" (mkKey x)
      Buck.Entity_file x -> alt @"file" (mkKey x)
      Buck.Entity_definition x -> alt @"definition" (mkKey x)
      Buck.Entity_EMPTY -> error "unknown entity"
  
  -- Flow
  
  instance ToAngle Flow.Entity where
    toAngle e = case e of
      Flow.Entity_decl x -> alt @"decl" (toAngle x)
      Flow.Entity_module_ x -> alt @"module_" (mkKey x)
      Flow.Entity_EMPTY -> error "unknown Entity"
  
  instance ToAngle Flow.SomeDeclaration where
    toAngle e = case e of
      Flow.SomeDeclaration_localDecl x -> alt @"localDecl" (mkKey x)
      Flow.SomeDeclaration_memberDecl x -> alt @"memberDecl" (mkKey x)
      Flow.SomeDeclaration_typeDecl x -> alt @"typeDecl" (mkKey x)
      Flow.SomeDeclaration_EMPTY -> error "unknown SomeDeclaration"
  
  -- GraphQL
  
  instance ToAngle GraphQL.Entity where
    toAngle e = case e of
      GraphQL.Entity_decl x -> alt @"decl" (toAngle x)
      GraphQL.Entity_EMPTY -> error "unknown Entity"
  
  instance ToAngle GraphQL.Declaration where
    toAngle e = case e of
      GraphQL.Declaration_operation_ x -> alt @"operation_" (mkKey x)
      GraphQL.Declaration_fragment_ x -> alt @"fragment_" (mkKey x)
      GraphQL.Declaration_field_ x -> alt @"field_" (mkKey x)
      GraphQL.Declaration_enum_ x -> alt @"enum_" (mkKey x)
      GraphQL.Declaration_directive_ x -> alt @"directive_" (mkKey x)
      GraphQL.Declaration_EMPTY -> error "unknown GraphQL.Declaration"
  
  -- Hack
  
  instance ToAngle Hack.Declaration where
    toAngle e = case e of
      Hack.Declaration_classConst x -> alt @"classConst" (mkKey x)
      Hack.Declaration_container x -> alt @"container" (toAngle x)
      Hack.Declaration_enumerator x -> alt @"enumerator" (mkKey x)
      Hack.Declaration_function_ x -> alt @"function_" (mkKey x)
      Hack.Declaration_globalConst x -> alt @"globalConst" (mkKey x)
      Hack.Declaration_method x -> alt @"method" (mkKey x)
      Hack.Declaration_module x -> alt @"module" (mkKey x)
      Hack.Declaration_namespace_ x -> alt @"namespace_" (mkKey x)
      Hack.Declaration_property_ x -> alt @"property_" (mkKey x)
      Hack.Declaration_typeConst x -> alt @"typeConst" (mkKey x)
      Hack.Declaration_typedef_ x -> alt @"typedef_" (mkKey x)
      Hack.Declaration_EMPTY -> error "unknown Declaration"
  
  instance Prune Hack.Declaration where
    prune d = case d of
      Hack.Declaration_classConst x ->
        Hack.Declaration_classConst (mkFact (getId x) Nothing Nothing)
      Hack.Declaration_container x ->
        Hack.Declaration_container (prune x)
      Hack.Declaration_enumerator x ->
        Hack.Declaration_enumerator (mkFact (getId x) Nothing Nothing)
      Hack.Declaration_function_ x ->
        Hack.Declaration_function_ (mkFact (getId x) Nothing Nothing)
      Hack.Declaration_globalConst x ->
        Hack.Declaration_globalConst (mkFact (getId x) Nothing Nothing)
      Hack.Declaration_method x ->
        Hack.Declaration_method (mkFact (getId x) Nothing Nothing)
      Hack.Declaration_module x ->
        Hack.Declaration_module (mkFact (getId x) Nothing Nothing)
      Hack.Declaration_namespace_ x ->
        Hack.Declaration_namespace_ (mkFact (getId x) Nothing Nothing)
      Hack.Declaration_property_ x ->
        Hack.Declaration_property_ (mkFact (getId x) Nothing Nothing)
      Hack.Declaration_typeConst x ->
        Hack.Declaration_typeConst (mkFact (getId x) Nothing Nothing)
      Hack.Declaration_typedef_ x ->
        Hack.Declaration_typedef_ (mkFact (getId x) Nothing Nothing)
      Hack.Declaration_EMPTY -> error "unknown Declaration"
  
  instance ToAngle Hack.ContainerDeclaration where
    toAngle e = case e of
      Hack.ContainerDeclaration_class_ x -> alt @"class_" (mkKey x)
      Hack.ContainerDeclaration_enum_ x -> alt @"enum_" (mkKey x)
      Hack.ContainerDeclaration_interface_ x -> alt @"interface_" (mkKey x)
      Hack.ContainerDeclaration_trait x -> alt @"trait" (mkKey x)
      Hack.ContainerDeclaration_EMPTY -> error "unknown ContainerDeclaration"
  
  instance Prune Hack.ContainerDeclaration where
    prune e = case e of
      Hack.ContainerDeclaration_class_ x ->
        Hack.ContainerDeclaration_class_ (mkFact (getId x) Nothing Nothing)
      Hack.ContainerDeclaration_enum_ x ->
        Hack.ContainerDeclaration_enum_ (mkFact (getId x) Nothing Nothing)
      Hack.ContainerDeclaration_interface_ x ->
        Hack.ContainerDeclaration_interface_ (mkFact (getId x) Nothing Nothing)
      Hack.ContainerDeclaration_trait x ->
        Hack.ContainerDeclaration_trait (mkFact (getId x) Nothing Nothing)
      Hack.ContainerDeclaration_EMPTY -> error "unknown ContainerDeclaration"
  
  -- Haskell
  
  instance ToAngle Hs.Entity where
    toAngle (Hs.Entity_name x) = alt @"name" (mkKey x)
    toAngle (Hs.Entity_mod x) = alt @"mod" (mkKey x)
    toAngle x = error $ "unknown Hs.Entity: " <> show x
  
  -- Python
  
  instance ToAngle Py.Declaration where
    toAngle (Py.Declaration_cls x) = alt @"cls" (mkKey x)
    toAngle (Py.Declaration_func x) = alt @"func" (mkKey x)
    toAngle (Py.Declaration_module x) = alt @"module" (mkKey x)
    toAngle (Py.Declaration_variable x) = alt @"variable" (mkKey x)
    toAngle (Py.Declaration_imp x) = alt @"imp" (mkKey x)
    toAngle Py.Declaration_EMPTY = error "unknown Declaration"
  
  instance Prune Py.Declaration where
    prune (Py.Declaration_cls x) =
      Py.Declaration_cls (mkFact (getId x) Nothing Nothing)
    prune (Py.Declaration_func x) =
      Py.Declaration_func (mkFact (getId x) Nothing Nothing)
    prune (Py.Declaration_module x) =
      Py.Declaration_module (mkFact (getId x) Nothing Nothing)
    prune (Py.Declaration_variable x) =
      Py.Declaration_variable (mkFact (getId x) Nothing Nothing)
    prune (Py.Declaration_imp x) =
      Py.Declaration_imp (mkFact (getId x) Nothing Nothing)
    prune Py.Declaration_EMPTY = error "unknown Declaration"
  
  -- Src
  
  instance Normalize Src.File where
    normalize (Src.File _ (Just k)) = Src.File 0 (Just k)
    normalize  _ = error "Not fully resolved"
  
  instance ToAngleFull Src.File where
    toAngleFull (Src.File _ (Just k)) = predicate $ string k
    toAngleFull  _ = error "Not fully resolved"
  
  -- Fbthrift
  
  instance Normalize Fbthrift.File where
    normalize (Fbthrift.File _ (Just k)) = Fbthrift.File 0 (Just (normalize k))
    normalize  _ = error "Not fully resolved"
  
  instance Normalize Fbthrift.QualName_key where
    normalize
      (Fbthrift.QualName_key (Fbthrift.File _ (Just file))
      (Fbthrift.Identifier _ (Just identifier))) =
      Fbthrift.QualName_key (Fbthrift.File 0 (Just (normalize file)))
      (Fbthrift.Identifier 0 (Just identifier))
    normalize  _ = error "Not fully resolved"
  
  instance Normalize Fbthrift.ExceptionName_key where
    normalize (Fbthrift.ExceptionName_key (Fbthrift.QualName _ (Just qualname)))
      =
      Fbthrift.ExceptionName_key (Fbthrift.QualName 0 (Just (normalize qualname)))
    normalize  _ = error "Not fully resolved"
  
  instance Normalize Fbthrift.ServiceName_key where
    normalize (Fbthrift.ServiceName_key (Fbthrift.QualName _ (Just qualname)))
      =
      Fbthrift.ServiceName_key (Fbthrift.QualName 0 (Just (normalize qualname)))
    normalize  _ = error "Not fully resolved"
  
  instance Normalize Fbthrift.NamedDecl_key where
    normalize
      (Fbthrift.NamedDecl_key
        (Fbthrift.NamedType (Fbthrift.QualName _ (Just qualname)) kind)) =
      Fbthrift.NamedDecl_key
        (Fbthrift.NamedType
          (Fbthrift.QualName 0 (Just (normalize qualname))) kind)
    normalize  _ = error "Not fully resolved"
  
  instance Normalize Fbthrift.FunctionName_key where
    normalize
      (Fbthrift.FunctionName_key (Fbthrift.ServiceName _ (Just service_))
        (Fbthrift.Identifier _ (Just identifier))) =
      Fbthrift.FunctionName_key (Fbthrift.ServiceName 0
        (Just (normalize service_))) (Fbthrift.Identifier 0 (Just identifier))
    normalize  _ = error "Not fully resolved"
  
  instance Normalize Fbthrift.FieldDecl_key where
    normalize
      (Fbthrift.FieldDecl_key
        (Fbthrift.QualName _ (Just qualname))
         kind
        (Fbthrift.Identifier _ (Just identifier))) =
      Fbthrift.FieldDecl_key
        (Fbthrift.QualName 0 (Just (normalize qualname)))
        kind
        (Fbthrift.Identifier 0 (Just identifier))
    normalize  _ = error "Not fully resolved"
  
  instance Normalize Fbthrift.EnumValue_key where
    normalize
      (Fbthrift.EnumValue_key
        (Fbthrift.NamedType (Fbthrift.QualName _ (Just qualname)) kind)
        (Fbthrift.Identifier _ (Just identifier))) =
      Fbthrift.EnumValue_key
        (Fbthrift.NamedType
          (Fbthrift.QualName 0 (Just (normalize qualname))) kind)
        (Fbthrift.Identifier 0 (Just identifier))
    normalize  _ = error "Not fully resolved"
  
  instance Normalize Fbthrift.Constant_key where
    normalize (Fbthrift.Constant_key (Fbthrift.QualName _ (Just qualname))) =
      Fbthrift.Constant_key (Fbthrift.QualName 0 (Just (normalize qualname)))
    normalize  _ = error "Not fully resolved"
  
  instance Normalize Fbthrift.XRefTarget where
    normalize
      (Fbthrift.XRefTarget_function_
        (Fbthrift.FunctionName _ (Just x))) =
      Fbthrift.XRefTarget_function_ (Fbthrift.FunctionName 0 (Just (normalize x)))
    normalize (Fbthrift.XRefTarget_service_
        (Fbthrift.ServiceName _ (Just x))) =
      Fbthrift.XRefTarget_service_ (Fbthrift.ServiceName 0 (Just (normalize x)))
    normalize (Fbthrift.XRefTarget_exception_
        (Fbthrift.ExceptionName _ (Just x))) =
      Fbthrift.XRefTarget_exception_
        (Fbthrift.ExceptionName 0 (Just (normalize x)))
    normalize (Fbthrift.XRefTarget_named
        (Fbthrift.NamedDecl _ (Just x))) =
      Fbthrift.XRefTarget_named (Fbthrift.NamedDecl 0 (Just (normalize x)))
    normalize
      (Fbthrift.XRefTarget_field
        (Fbthrift.FieldDecl _ (Just x))) =
      Fbthrift.XRefTarget_field (Fbthrift.FieldDecl 0 (Just (normalize x)))
    normalize
      (Fbthrift.XRefTarget_enumValue
        (Fbthrift.EnumValue _ (Just x))) =
      Fbthrift.XRefTarget_enumValue (Fbthrift.EnumValue 0 (Just (normalize x)))
    normalize
      (Fbthrift.XRefTarget_constant
        (Fbthrift.Constant _ (Just x))) =
      Fbthrift.XRefTarget_constant (Fbthrift.Constant 0 (Just (normalize x)))
    normalize
      (Fbthrift.XRefTarget_include_
        (Fbthrift.File _ (Just x))) =
      Fbthrift.XRefTarget_include_ (Fbthrift.File 0 (Just (normalize x)))
    normalize _  = error "Not fully resolved"
  
  instance ToAngleFull Fbthrift.File where
    toAngleFull (Fbthrift.File _ (Just k)) = predicate $ toAngleFull k
    toAngleFull  _ = error "Not fully resolved"
  
  instance ToAngleFull Fbthrift.QualName_key where
    toAngleFull
      (Fbthrift.QualName_key (Fbthrift.File _ (Just file))
      (Fbthrift.Identifier _ (Just identifier))) = rec $
          field @"file" (sig (toAngleFull file)) $
          field @"name" (string identifier)
      end
    toAngleFull  _ = error "Not fully resolved"
  
  instance ToAngleFull Fbthrift.ServiceName_key where
    toAngleFull (Fbthrift.ServiceName_key (Fbthrift.QualName _ (Just qualname)))
      = rec $
          field @"name" (toAngleFull qualname)
      end
    toAngleFull  _ = error "Not fully resolved"
  
  instance ToAngleFull Fbthrift.NamedDecl_key where
    toAngleFull
      (Fbthrift.NamedDecl_key
        (Fbthrift.NamedType (Fbthrift.QualName _ (Just qualname)) kind)) =
        let namedType :: Angle Fbthrift.NamedType = rec $
              field @"name" (toAngleFull qualname) $
              field @"kind" (enum kind)
              end
        in
        rec $
          field @"name" namedType
      end
    toAngleFull  _ = error "Not fully resolved"
  
  instance ToAngleFull Fbthrift.EnumValue_key where
    toAngleFull
      (Fbthrift.EnumValue_key
        (Fbthrift.NamedType (Fbthrift.QualName _ (Just qualname)) kind)
        (Fbthrift.Identifier _ (Just identifier))
        ) =
        let namedType :: Angle Fbthrift.NamedType = rec $
              field @"name" (toAngleFull qualname) $
              field @"kind" (enum kind)
              end
        in
        rec $
          field @"enum_" namedType $
          field @"name" (string identifier)
      end
    toAngleFull  _ = error "Not fully resolved"
  
  
  instance ToAngleFull Fbthrift.ExceptionName_key where
    toAngleFull (Fbthrift.ExceptionName_key (Fbthrift.QualName _ (Just qualname)))
      = rec $
          field @"name" (toAngleFull qualname)
      end
    toAngleFull  _ = error "Not fully resolved"
  
  instance ToAngleFull Fbthrift.FunctionName_key where
    toAngleFull
      (Fbthrift.FunctionName_key (Fbthrift.ServiceName _ (Just service_))
      (Fbthrift.Identifier _ (Just identifier))) = rec $
        field @"service_" (toAngleFull service_) $
        field @"name" (string identifier)
      end
    toAngleFull  _ = error "Not fully resolved"
  
  instance ToAngleFull Fbthrift.FieldDecl_key where
    toAngleFull
      (Fbthrift.FieldDecl_key
        (Fbthrift.QualName _ (Just qualname))
        kind
        (Fbthrift.Identifier _ (Just identifier))) =
        rec $
          field @"qname" (toAngleFull qualname) $
          field @"kind" (enum kind) $
          field @"name" (string identifier)
        end
    toAngleFull  _ = error "Not fully resolved"
  
  instance ToAngleFull Fbthrift.Constant_key where
    toAngleFull
      (Fbthrift.Constant_key
        (Fbthrift.QualName _ (Just qualname))) =
        rec $
          field @"name" (toAngleFull qualname)
        end
    toAngleFull  _ = error "Not fully resolved"
  
  instance ToAngleFull Fbthrift.XRefTarget where
    toAngleFull
      (Fbthrift.XRefTarget_function_ (Fbthrift.FunctionName _ (Just x))) =
      alt @"function_" (toAngleFull x)
    toAngleFull
      (Fbthrift.XRefTarget_service_ (Fbthrift.ServiceName _ (Just x))) =
      alt @"service_" (toAngleFull x)
    toAngleFull
      (Fbthrift.XRefTarget_exception_ (Fbthrift.ExceptionName _ (Just x))) =
      alt @"exception_" (toAngleFull x)
    toAngleFull
      (Fbthrift.XRefTarget_named (Fbthrift.NamedDecl _ (Just x))) =
      alt @"named" (toAngleFull x)
    toAngleFull
      (Fbthrift.XRefTarget_field (Fbthrift.FieldDecl _ (Just x))) =
      alt @"field" (toAngleFull x)
    toAngleFull
      (Fbthrift.XRefTarget_enumValue (Fbthrift.EnumValue _ (Just x))) =
      alt @"enumValue" (toAngleFull x)
    toAngleFull
      (Fbthrift.XRefTarget_constant (Fbthrift.Constant _ (Just x))) =
      alt @"constant" (toAngleFull x)
    toAngleFull
      (Fbthrift.XRefTarget_include_ (Fbthrift.File _ (Just x))) =
      alt @"include_" (toAngleFull x)
    toAngleFull _  = error "Not fully resolved"
  
  instance ToAngle Fbthrift.XRefTarget where
    toAngle (Fbthrift.XRefTarget_include_ x) = alt @"include_" (mkKey x)
    toAngle (Fbthrift.XRefTarget_named x) = alt @"named" (mkKey x)
    toAngle (Fbthrift.XRefTarget_exception_ x) = alt @"exception_" (mkKey x)
    toAngle (Fbthrift.XRefTarget_service_ x) = alt @"service_" (mkKey x)
    toAngle (Fbthrift.XRefTarget_constant x) = alt @"constant" (mkKey x)
    toAngle (Fbthrift.XRefTarget_enumValue x) = alt @"enumValue" (mkKey x)
    toAngle (Fbthrift.XRefTarget_function_ x) = alt @"function_" (mkKey x)
    toAngle (Fbthrift.XRefTarget_field x) = alt @"field" (mkKey x)
    toAngle Fbthrift.XRefTarget_EMPTY = error "unknown Entity"
  
  -- Python
  
  instance ToAngleFull Py.Declaration where
    toAngleFull (Py.Declaration_cls (Py.ClassDeclaration _  (Just k))) =
      alt @"cls" (toAngleFull k)
    toAngleFull (Py.Declaration_func (Py.FunctionDeclaration _  (Just k))) =
      alt @"func" (toAngleFull k)
    toAngleFull (Py.Declaration_module (Py.Module _  (Just k))) =
      alt @"module" (toAngleFull k)
    toAngleFull (Py.Declaration_variable (Py.VariableDeclaration _  (Just k))) =
      alt @"variable" (toAngleFull k)
    toAngleFull (Py.Declaration_imp (Py.ImportStatement _  (Just k))) =
      alt @"imp" (toAngleFull k)
    toAngleFull Py.Declaration_EMPTY = error "unknown Entity"
    toAngleFull _  = error "Not fully resolved"
  
  instance ToAngleFull Py.ImportStatement_key where
    toAngleFull
     (Py.ImportStatement_key
       (Py.Name _ (Just from)) (Py.Name _ (Just as))) = rec $
         field @"from_name" (string from) $
         field @"as_name" (string as)
      end
    toAngleFull _ = error "Not fully resolved"
  
  instance ToAngleFull Py.Module_key where
    toAngleFull (Py.Module_key ((Py.Name _ (Just k)))) = rec $
      field @"name" (string k)
      end
    toAngleFull _ = error "Not fully resolved"
  
  instance ToAngleFull Py.FunctionDeclaration_key where
    toAngleFull (Py.FunctionDeclaration_key ((Py.Name _ (Just k)))) = rec $
      field @"name" (string k)
      end
    toAngleFull _ = error "Not fully resolved"
  
  instance ToAngleFull Py.VariableDeclaration_key where
    toAngleFull (Py.VariableDeclaration_key ((Py.Name _ (Just k)))) = rec $
      field @"name" (string k)
      end
    toAngleFull _ = error "Not fully resolved"
  
  instance ToAngleFull Py.ClassDeclaration_key where
    toAngleFull (Py.ClassDeclaration_key ((Py.Name _ (Just k))) _bases) = rec $
      field @"name" (string k)
      end
    toAngleFull _ = error "Not fully resolved"
  
  instance Normalize Py.Name where
    normalize (Py.Name _ (Just k)) = Py.Name 0 (Just k)
    normalize _ = error "Not fully resolved"
  
  instance Normalize Py.Declaration where
    normalize (Py.Declaration_cls cls) = Py.Declaration_cls $ normalize cls
    normalize (Py.Declaration_func f) = Py.Declaration_func $ normalize f
    normalize (Py.Declaration_variable v) = Py.Declaration_variable $ normalize v
    normalize (Py.Declaration_module m) = Py.Declaration_module $ normalize m
    normalize (Py.Declaration_imp i) = Py.Declaration_imp $ normalize i
    normalize Py.Declaration_EMPTY = error "unknown entity"
  
  instance Normalize Py.ImportStatement where
    normalize (Py.ImportStatement _ (Just k)) =
      Py.ImportStatement 0 (Just (normalize k))
    normalize _ = error "Not fully resolved"
  
  instance Normalize Py.ImportStatement_key where
    normalize (Py.ImportStatement_key f a) =
      Py.ImportStatement_key (normalize f) (normalize a)
  
  instance Normalize Py.ClassDeclaration where
    normalize (Py.ClassDeclaration _ (Just k)) =
      Py.ClassDeclaration 0 (Just (normalize k))
    normalize _ = error "Not fully resolved"
  
  instance Normalize Py.ClassDeclaration_key where
    normalize (Py.ClassDeclaration_key name _base) =
      Py.ClassDeclaration_key (normalize name) (Just [])
  
  instance Normalize Py.VariableDeclaration where
    normalize (Py.VariableDeclaration _ (Just k)) =
      Py.VariableDeclaration 0 (Just (normalize k))
    normalize _ = error "Not fully resolved"
  
  instance Normalize Py.VariableDeclaration_key where
    normalize (Py.VariableDeclaration_key name) =
      Py.VariableDeclaration_key (normalize name)
  
  instance Normalize Py.FunctionDeclaration where
    normalize (Py.FunctionDeclaration _ (Just k)) =
      Py.FunctionDeclaration 0 (Just (normalize k))
    normalize _ = error "Not fully resolved"
  
  instance Normalize Py.FunctionDeclaration_key where
    normalize (Py.FunctionDeclaration_key name) =
      Py.FunctionDeclaration_key (normalize name)
  
  instance Normalize Py.Module where
    normalize (Py.Module _ (Just k)) =
      Py.Module 0 (Just (normalize k))
    normalize _ = error "Not fully resolved"
  
  instance Normalize Py.Module_key where
    normalize (Py.Module_key name) =
      Py.Module_key (normalize name)
  
  
  -- Java
  
  instance ToAngle Java.Declaration where
    toAngle (Java.Declaration_class_ x) = alt @"class_" (mkKey x)
    toAngle (Java.Declaration_interface_ x) = alt @"interface_" (mkKey x)
    toAngle (Java.Declaration_enum_ x) = alt @"enum_" (mkKey x)
    toAngle (Java.Declaration_method x) = alt @"method" (mkKey x)
    toAngle (Java.Declaration_ctor x) = alt @"ctor" (mkKey x)
    toAngle (Java.Declaration_field x) = alt @"field" (mkKey x)
    toAngle (Java.Declaration_param x) = alt @"param" (mkKey x)
    toAngle (Java.Declaration_local x) = alt @"local" (mkKey x)
    toAngle Java.Declaration_EMPTY = error "unknown Declaration"
  
  -- Kotlin
  
  instance ToAngle Kotlin.Declaration where
    toAngle (Kotlin.Declaration_class_ x) = alt @"class_" (mkKey x)
    toAngle (Kotlin.Declaration_method x) = alt @"method" (mkKey x)
    toAngle (Kotlin.Declaration_variable x) = alt @"variable" (mkKey x)
    toAngle Kotlin.Declaration_EMPTY = error "unknown Declaration"
  
  -- C#
  
  instance ToAngle CSharp.Definition where
    toAngle (CSharp.Definition_type atype) = alt @"type" (toAngle atype)
    toAngle (CSharp.Definition_method x) = alt @"method" (mkKey x)
    toAngle (CSharp.Definition_field x) = alt @"field" (mkKey x)
    toAngle (CSharp.Definition_parameter x) = alt @"parameter" (mkKey x)
    toAngle (CSharp.Definition_typeParameter x) = alt @"typeParameter" (mkKey x)
    toAngle (CSharp.Definition_local x) = alt @"local" (mkKey x)
    toAngle (CSharp.Definition_property x) = alt @"property" (mkKey x)
    toAngle CSharp.Definition_EMPTY = error "unknown Definition"
  
  instance ToAngle CSharp.AType where
    toAngle (CSharp.AType_arrayType x) = alt @"arrayType" (mkKey x)
    toAngle (CSharp.AType_namedType x) = alt @"namedType" (toAngle x)
    toAngle (CSharp.AType_functionPointerType x) =
      alt @"functionPointerType" (mkKey x)
    toAngle (CSharp.AType_pointerType x) = alt @"pointerType" (mkKey x)
    toAngle (CSharp.AType_typeParameter x) = alt @"typeParameter" (mkKey x)
    toAngle CSharp.AType_EMPTY = error "unknown AType"
  
  instance ToAngle CSharp.NamedType where
    toAngle (CSharp.NamedType_class_ x) = alt @"class_" (mkKey x)
    toAngle (CSharp.NamedType_interface_ x) = alt @"interface_" (mkKey x)
    toAngle (CSharp.NamedType_record_ x) = alt @"record_" (mkKey x)
    toAngle (CSharp.NamedType_struct_ x) = alt @"struct_" (mkKey x)
    toAngle CSharp.NamedType_EMPTY = error "unknown NamedType"
  
  -- LSIF and SCIP languages
  
  instance ToAngle Lsif.SomeEntity where
    toAngle e = case e of
      Lsif.SomeEntity_defn x -> alt @"defn" (mkKey x)
      Lsif.SomeEntity_decl x -> alt @"decl" (mkKey x)
      Lsif.SomeEntity_EMPTY -> error "unknown Lsif.SomeEntity"
  
  instance ToAngle Scip.SomeEntity where
    toAngle (Scip.SomeEntity defn) = rec $ field @"defn" (mkKey defn) end
      -- note: singleton type, not a sum.
  
  -- Codemarkup
  
  instance ToAngleFull Code.Entity where
    toAngleFull entity = case entity of
      Code.Entity_fbthrift (Fbthrift.Entity_decl x) ->
        alt @"fbthrift" (alt @"decl" (toAngleFull x))
      Code.Entity_python (Py.Entity_decl x) ->
        alt @"python" (alt @"decl" (toAngleFull x))
      Code.Entity_cxx (Cxx.Entity_decl x) ->
        alt @"cxx" (alt @"decl" (toAngleFull x))
      _ -> error "Only thrift or python entities are expected"
  
  instance ToAngleFull Code.SymbolId where
    toAngleFull (Code.SymbolId_cxx x) = alt @"cxx" (toAngleFull x)
    toAngleFull (Code.SymbolId_scip x) = alt @"scip" (toAngleFull x)
    toAngleFull (Code.SymbolId_swift x) = alt @"swift" (toAngleFull x)
    toAngleFull Code.SymbolId_EMPTY = error "unknown Code.SymbolId"
  
  instance ToAngleFull Scip.Symbol where
    toAngleFull (Scip.Symbol _ (Just x)) = predicate $ toAngleFull x
    toAngleFull _ = error "Not fully resolved"
  
  instance Normalize Code.SymbolId  where
    normalize (Code.SymbolId_cxx x) = Code.SymbolId_cxx (normalize x)
    normalize (Code.SymbolId_scip x) = Code.SymbolId_scip (normalize x)
    normalize (Code.SymbolId_swift x) = Code.SymbolId_swift (normalize x)
    normalize Code.SymbolId_EMPTY = Code.SymbolId_EMPTY
  
  instance Normalize Scip.Symbol where
    normalize (Scip.Symbol _ x) = Scip.Symbol 0 (normalize x)
  
  
  instance Normalize Code.Entity where
      normalize entity = case entity of
        Code.Entity_fbthrift (Fbthrift.Entity_decl x) ->
          Code.Entity_fbthrift (Fbthrift.Entity_decl (normalize x))
        Code.Entity_python (Py.Entity_decl x) ->
          Code.Entity_python (Py.Entity_decl (normalize x))
        Code.Entity_cxx (Cxx.Entity_decl x) ->
          Code.Entity_cxx (Cxx.Entity_decl (normalize x))
        _ -> error $
          "Only thrift or python or cxx entities are expected, got: " <> show entity
  
  instance ToAngleFull Text where
    toAngleFull x = string x
  
  instance Normalize Text where
    normalize x = x
  
  instance (Functor f, Normalize x) => Normalize (f x) where
    normalize x = normalize <$> x
  