module Unison.PartialDeclNameLookup
  ( PartialDeclNameLookup (..),
    Unison.PartialDeclNameLookup.empty,
    expectDeclName,
    expectConstructorNames,
  )
where

import Data.Map.Strict qualified as Map
import Unison.Name (Name)
import Unison.Prelude

-- | Like a @DeclNameLookup@, but "partial" / more lenient - because we don't require the LCA of a merge to have a full
-- @DeclNameLookup@.
data PartialDeclNameLookup = PartialDeclNameLookup
  { PartialDeclNameLookup -> Map Name Name
constructorToDecl :: !(Map Name Name),
    PartialDeclNameLookup -> Map Name [Maybe Name]
declToConstructors :: !(Map Name [Maybe Name])
  }
  deriving stock ((forall x. PartialDeclNameLookup -> Rep PartialDeclNameLookup x)
-> (forall x. Rep PartialDeclNameLookup x -> PartialDeclNameLookup)
-> Generic PartialDeclNameLookup
forall x. Rep PartialDeclNameLookup x -> PartialDeclNameLookup
forall x. PartialDeclNameLookup -> Rep PartialDeclNameLookup x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PartialDeclNameLookup -> Rep PartialDeclNameLookup x
from :: forall x. PartialDeclNameLookup -> Rep PartialDeclNameLookup x
$cto :: forall x. Rep PartialDeclNameLookup x -> PartialDeclNameLookup
to :: forall x. Rep PartialDeclNameLookup x -> PartialDeclNameLookup
Generic)

empty :: PartialDeclNameLookup
empty :: PartialDeclNameLookup
empty =
  Map Name Name -> Map Name [Maybe Name] -> PartialDeclNameLookup
PartialDeclNameLookup Map Name Name
forall k a. Map k a
Map.empty Map Name [Maybe Name]
forall k a. Map k a
Map.empty

expectDeclName :: (HasCallStack) => PartialDeclNameLookup -> Name -> Name
expectDeclName :: HasCallStack => PartialDeclNameLookup -> Name -> Name
expectDeclName PartialDeclNameLookup {Map Name Name
$sel:constructorToDecl:PartialDeclNameLookup :: PartialDeclNameLookup -> Map Name Name
constructorToDecl :: Map Name Name
constructorToDecl} Name
x =
  case Name -> Map Name Name -> Maybe Name
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
x Map Name Name
constructorToDecl of
    Maybe Name
Nothing -> String -> Name
forall a. HasCallStack => String -> a
error (String -> String -> String
reportBug String
"E874908" (String
"Expected constructor name key " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Name -> String
forall a. Show a => a -> String
show Name
x String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" in partial decl name lookup"))
    Just Name
y -> Name
y

expectConstructorNames :: (HasCallStack) => PartialDeclNameLookup -> Name -> [Maybe Name]
expectConstructorNames :: HasCallStack => PartialDeclNameLookup -> Name -> [Maybe Name]
expectConstructorNames PartialDeclNameLookup {Map Name [Maybe Name]
$sel:declToConstructors:PartialDeclNameLookup :: PartialDeclNameLookup -> Map Name [Maybe Name]
declToConstructors :: Map Name [Maybe Name]
declToConstructors} Name
x =
  case Name -> Map Name [Maybe Name] -> Maybe [Maybe Name]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
x Map Name [Maybe Name]
declToConstructors of
    Maybe [Maybe Name]
Nothing -> String -> [Maybe Name]
forall a. HasCallStack => String -> a
error (String -> String -> String
reportBug String
"E800097" (String
"Expected decl name key " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Name -> String
forall a. Show a => a -> String
show Name
x String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" in partial decl name lookup"))
    Just [Maybe Name]
y -> [Maybe Name]
y