{- 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 TypeFamilies #-} {-# LANGUAGE ConstraintKinds #-} -- Copyright 2004-present Facebook. All Rights Reserved. {-# OPTIONS_GHC -Wno-star-is-type -Wno-orphans #-} module Glean.Glass.Attributes.Class ( ToAttributes(..) , LogAttr(..) , RefEntitySymbol , DefEntitySymbol , extendAttributes , attrListToMap , attrMapToList ) where import qualified Data.Map as Map import qualified Data.Aeson as A import qualified Glean import qualified Glean.Haxl.Repos as Glean import qualified Haxl.DataSource.Glean as Glean (HasRepo) import Glean.Glass.Types import Glean.Glass.SourceControl ( SourceControl ) import qualified Glean.Schema.Src.Types as Src ( File ) import qualified Glean.Schema.Code.Types as Code -- | Class for defining log structures that can be converted to JSON text class LogAttr a where -- | Convert the structure to a single JSON-formatted text string toLogText :: a -> A.Value instance LogAttr () where toLogText _ = A.Null -- | Class for querying attributes and converting them to thrift class LogAttr (AttrLog key) => ToAttributes key where type AttrRep key :: * type FileAttrRep key :: * type AttrLog key :: * -- | Fetch the metadata about the attributes for this file -- e.g. a list of available denominators/slices queryMetadataForFile :: key -> Maybe Int -> Glean.IdOf Src.File -> AttributeOptions -> Revision -> Glean.RepoHaxl u w [FileAttrRep key] fileAttrsToAttributeList :: key -> [FileAttrRep key] -> Maybe AttributeList -- | Fetch the data for this attribute type for a file queryForFile :: (SourceControl scm, Glean.HasRepo u) => key -> Maybe Int -> Glean.IdOf Src.File -> AttributeOptions -> scm -> RepoName -> Path -> Revision -> [FileAttrRep key] -> Glean.RepoHaxl u w [AttrRep key] -- | Add attributes to symbols augmentSymbols :: key -> [AttrRep key] -> [RefEntitySymbol] -> [DefEntitySymbol] -> AttributeOptions -> ([RefEntitySymbol], [DefEntitySymbol], AttrLog key) type RefEntitySymbol = (Code.Entity, ReferenceRangeSymbolX) type DefEntitySymbol = (Code.Entity, DefinitionSymbolX) -- | Given some definitions, combine their attributes from any additional -- ones in the attribute maps. Helper for implementing augmentSymbols. extendAttributes :: Ord k => (SymbolId -> Code.Entity -> k) -> Map.Map k Attributes -> [RefEntitySymbol] -> [DefEntitySymbol] -> ([RefEntitySymbol], [DefEntitySymbol]) extendAttributes keyFn attrMap theRefs theDefs = (refs, defs) where defs = map (uncurry extendDef) theDefs refs = map (uncurry extendRef) theRefs extend symId entity def = case Map.lookup (keyFn symId entity) attrMap of Nothing -> def Just attr -> attrMapToList attr <> def extendRef entity ref@ReferenceRangeSymbolX{..} = (entity,) $ ref { referenceRangeSymbolX_attributes = attrs } where attrs = extend referenceRangeSymbolX_sym entity referenceRangeSymbolX_attributes extendDef entity def@DefinitionSymbolX{..} = (entity,) $ def { definitionSymbolX_attributes = attrs } where attrs = extend definitionSymbolX_sym entity definitionSymbolX_attributes instance Prelude.Semigroup AttributeList where AttributeList a <> AttributeList b = AttributeList (a <> b) -- | Convert between attribute bag representations attrMapToList :: Attributes -> AttributeList attrMapToList (Attributes attrMap) = AttributeList $ map pair $ Map.toList attrMap where pair (k,v) = KeyedAttribute k v -- | Convert attribute list to map keyed by attr key attrListToMap :: AttributeList -> Attributes attrListToMap (AttributeList elems) = Attributes $ Map.fromList $ map unpair elems where unpair (KeyedAttribute k v) = (k,v)