{- 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. -} {-# OPTIONS_GHC -Wno-orphans #-} -- Thrift symbol ids can be of three forms -- repo/thrift/FILE -- repo/thrift/FILE/NAME -- NAME can refer to a union, struct, exception, service, constant, typedef -- there's no possible ambiguity as these names are guaranteed to be unique -- in a file -- repo/thrift/FILE/NAME/MEMBER -- MEMBER can be a struct/union/exception field, an enum value, -- or a service function -- -- The symbol id is ambiguous, repo/thrift/a.thrift/b.thrift/c can refer to -- field c in struct b.thrift, or struct c in file b.thrift. -- TODO add more structure to disambiguate -- module Glean.Glass.SymbolId.Fbthrift ({- instances -}) where import Data.Maybe import Data.Text ( intercalate, stripSuffix ) import Glean.Glass.SymbolId.Class import Glean.Glass.Types (Name(..)) import qualified Glean import qualified Glean.Schema.Fbthrift.Types as Thrift import Glean.Glass.Utils ( pathFragments ) import qualified Glean.Schema.Src.Types as Src instance Symbol Thrift.XRefTarget where toSymbol x = case x of Thrift.XRefTarget_include_ thrift_file -> toSymbolPredicate thrift_file Thrift.XRefTarget_named named -> toSymbolPredicate named Thrift.XRefTarget_exception_ exception_ -> toSymbolPredicate exception_ Thrift.XRefTarget_service_ service_ -> toSymbolPredicate service_ Thrift.XRefTarget_constant constant -> toSymbolPredicate constant Thrift.XRefTarget_enumValue enumvalue -> toSymbolPredicate enumvalue Thrift.XRefTarget_function_ fn -> toSymbolPredicate fn Thrift.XRefTarget_field fn -> toSymbolPredicate fn Thrift.XRefTarget_EMPTY -> return [] instance Symbol Src.File where toSymbol k = pathFragments <$> Glean.keyOf k instance Symbol Thrift.File where toSymbol f = toSymbolPredicate f instance Symbol Thrift.NamedDecl_key where toSymbol (Thrift.NamedDecl_key (Thrift.NamedType qualname _kind)) = toSymbolPredicate qualname instance Symbol Thrift.EnumValue_key where toSymbol (Thrift.EnumValue_key (Thrift.NamedType qualname _kind) name) = qualname <:> name instance Symbol Thrift.FieldDecl_key where toSymbol (Thrift.FieldDecl_key qualname _kind name) = qualname <:> name instance Symbol Thrift.Constant_key where toSymbol (Thrift.Constant_key qualname) = toSymbolPredicate qualname instance Symbol Thrift.ServiceName where toSymbol = toSymbolPredicate instance Symbol Thrift.ServiceName_key where toSymbol (Thrift.ServiceName_key qualname) = toSymbolPredicate qualname instance Symbol Thrift.FunctionName_key where toSymbol (Thrift.FunctionName_key service name) = service <:> name instance Symbol Thrift.ExceptionName_key where toSymbol (Thrift.ExceptionName_key qualname) = toSymbolPredicate qualname instance Symbol Thrift.QualName_key where toSymbol (Thrift.QualName_key file name) = file <:> name instance Symbol Thrift.QualName where toSymbol = toSymbolPredicate instance Symbol Thrift.Identifier where toSymbol identifier = do n <- Glean.keyOf identifier return [n] instance ToQName Thrift.XRefTarget where toQName e = case e of Thrift.XRefTarget_include_ file -> do thriftFile <- Glean.keyOf file path <- Glean.keyOf thriftFile return $ case reverse (pathFragments path) of [] -> Left "QName not supported for empty thrift path" (h:t) -> Right (Name h, Name (intercalate "." (reverse t))) Thrift.XRefTarget_named x -> Glean.keyOf x >>= toQName Thrift.XRefTarget_exception_ x -> Glean.keyOf x >>= toQName Thrift.XRefTarget_service_ x -> Glean.keyOf x >>= toQName Thrift.XRefTarget_constant x -> Glean.keyOf x >>= toQName Thrift.XRefTarget_enumValue x -> Glean.keyOf x >>= toQName Thrift.XRefTarget_function_ x -> Glean.keyOf x >>= toQName Thrift.XRefTarget_field x -> Glean.keyOf x >>= toQName Thrift.XRefTarget_EMPTY -> return $ Left "unknown thrift.Declaration" instance ToQName Thrift.NamedDecl_key where toQName (Thrift.NamedDecl_key (Thrift.NamedType qname _kind)) = do toQName =<< Glean.keyOf qname instance ToQName Thrift.ExceptionName_key where toQName (Thrift.ExceptionName_key qname ) = do toQName =<< Glean.keyOf qname instance ToQName Thrift.ServiceName_key where toQName (Thrift.ServiceName_key qname ) = do toQName =<< Glean.keyOf qname instance ToQName Thrift.FunctionName_key where toQName (Thrift.FunctionName_key service name ) = do eName <- toQName =<< Glean.keyOf service case eName of Left err -> pure (Left err) Right (service, _ ) -> do str <- Glean.keyOf name return $ Right (Name str, service) instance ToQName Thrift.Constant_key where toQName (Thrift.Constant_key qname ) = do toQName =<< Glean.keyOf qname instance ToQName Thrift.EnumValue_key where toQName (Thrift.EnumValue_key (Thrift.NamedType qname _kind) ident) = do Thrift.QualName_key _file parent <- Glean.keyOf qname name <- Glean.keyOf ident parentName <- Glean.keyOf parent return $ Right (Name name, Name parentName) instance ToQName Thrift.FieldDecl_key where toQName (Thrift.FieldDecl_key qname _kind ident) = do Thrift.QualName_key _file parent <- Glean.keyOf qname name <- Glean.keyOf ident parentName <- Glean.keyOf parent return $ Right (Name name, Name parentName) instance ToQName Thrift.QualName_key where toQName (Thrift.QualName_key file ident) = do path <- Glean.keyOf =<< Glean.keyOf file let parent = case pathFragments path of [] -> "" xs -> let f = last xs in fromMaybe f (stripSuffix ".thrift" f) str <- Glean.keyOf ident return (Right (Name str, Name parent))