{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts #-} {-| This module provides a less verbose API for accessing the options of the various descriptor messages types. There are seven different option types. The EnumValueOptions are not currently settable in the proto file. To access extension keys the descendKey functions are provided as the descend functions ignore them. The 'toDP', 'toEP', 'toSP' are type-specific descents that are demonstrated in the the tests below. They are useful in that they provide more information for the type-checker. The 'toFP', 'toEVP', and 'toMP' are fully type-specific descents but are needed to make the tests below type-check, though they could have been used in 'test4', test5', and 'test7'. > import Text.DescriptorProtos.Options > import Text.DescriptorProtos(fileDescriptorProto) > > test1 :: D.FileOptions > test1 = options fileDescriptorProto > > test2 :: Maybe D.MessageOptions > test2 = return fileDescriptorProto >>= descend "FieldDescriptorProto" >>= return . options > > test3 :: Maybe D.EnumOptions > test3 = return fileDescriptorProto >>= toDP "FieldDescriptorProto" >>= descend "Type" >>= return . options > > test4 :: Maybe D.EnumValueOptions > test4 = return fileDescriptorProto >>= toDP "FieldDescriptorProto" >>= toEP "Type" >>= descend "TYPE_DOUBLE" >>= return . options > > test5 :: Maybe D.FieldOptions > test5 = return fileDescriptorProto >>= toDP "DescriptorProto" >>= toDP "ExtensionRange" >>= descend "start" >>= return . options > > test6 :: Maybe D.ServiceOptions > test6 = return fileDescriptorProto >>= descend "ImaginaryService" >>= return . options > > test7 :: Maybe D.MethodOptions > test7 = return fileDescriptorProto >>= toSP "ImaginaryService" >>= descend "ImaginaryMethod" >>= return . options -} module Text.DescriptorProtos.Options(descend,descendKey ,toDP,toEP,toSP,toFP,toEVP,toMP ,NameAndOptions(name,options),DescendClass(descend'),DescendKey(descendKey') ,D.FileDescriptorProto,D.DescriptorProto,D.EnumDescriptorProto ,D.EnumValueDescriptorProto,D.FieldDescriptorProto ,D.ServiceDescriptorProto,D.MethodDescriptorProto ,D.EnumOptions,D.EnumValueOptions,D.FieldOptions ,D.FileOptions,D.MessageOptions,D.MethodOptions,D.ServiceOptions) where import qualified Text.DescriptorProtos.DescriptorProto as D(DescriptorProto) import qualified Text.DescriptorProtos.DescriptorProto as D.DescriptorProto(DescriptorProto(..)) import qualified Text.DescriptorProtos.DescriptorProto.ExtensionRange as D(ExtensionRange(ExtensionRange)) import qualified Text.DescriptorProtos.DescriptorProto.ExtensionRange as D.ExtensionRange(ExtensionRange(..)) import qualified Text.DescriptorProtos.EnumDescriptorProto as D(EnumDescriptorProto(EnumDescriptorProto)) import qualified Text.DescriptorProtos.EnumDescriptorProto as D.EnumDescriptorProto(EnumDescriptorProto(..)) import qualified Text.DescriptorProtos.EnumValueDescriptorProto as D(EnumValueDescriptorProto) import qualified Text.DescriptorProtos.EnumValueDescriptorProto as D.EnumValueDescriptorProto(EnumValueDescriptorProto(..)) import qualified Text.DescriptorProtos.FieldDescriptorProto as D(FieldDescriptorProto) import qualified Text.DescriptorProtos.FieldDescriptorProto as D.FieldDescriptorProto(FieldDescriptorProto(..)) import qualified Text.DescriptorProtos.FieldDescriptorProto.Type as D(Type) import Text.DescriptorProtos.FieldDescriptorProto.Type as D.Type(Type(..)) import qualified Text.DescriptorProtos.FileDescriptorProto as D(FileDescriptorProto) import qualified Text.DescriptorProtos.FileDescriptorProto as D.FileDescriptorProto(FileDescriptorProto(..)) import qualified Text.DescriptorProtos.MethodDescriptorProto as D(MethodDescriptorProto) import qualified Text.DescriptorProtos.MethodDescriptorProto as D.MethodDescriptorProto(MethodDescriptorProto(..)) import qualified Text.DescriptorProtos.ServiceDescriptorProto as D(ServiceDescriptorProto) import qualified Text.DescriptorProtos.ServiceDescriptorProto as D.ServiceDescriptorProto(ServiceDescriptorProto(..)) import qualified Text.DescriptorProtos.UninterpretedOption as D(UninterpretedOption) import qualified Text.DescriptorProtos.UninterpretedOption as D.UninterpretedOption(UninterpretedOption(..)) import qualified Text.DescriptorProtos.UninterpretedOption.NamePart as D(NamePart(NamePart)) import qualified Text.DescriptorProtos.UninterpretedOption.NamePart as D.NamePart(NamePart(..)) import qualified Text.DescriptorProtos.EnumOptions as D(EnumOptions) import qualified Text.DescriptorProtos.EnumOptions as D.EnumOptions(EnumOptions(..)) import qualified Text.DescriptorProtos.EnumValueOptions as D(EnumValueOptions) import qualified Text.DescriptorProtos.EnumValueOptions as D.EnumValueOptions(EnumValueOptions(..)) import qualified Text.DescriptorProtos.FieldOptions as D(FieldOptions) import qualified Text.DescriptorProtos.FieldOptions as D.FieldOptions(FieldOptions(..)) import qualified Text.DescriptorProtos.FileOptions as D(FileOptions) import qualified Text.DescriptorProtos.FileOptions as D.FileOptions(FileOptions(..)) import qualified Text.DescriptorProtos.MessageOptions as D(MessageOptions) import qualified Text.DescriptorProtos.MessageOptions as D.MessageOptions(MessageOptions(..)) import qualified Text.DescriptorProtos.MethodOptions as D(MethodOptions) import qualified Text.DescriptorProtos.MethodOptions as D.MethodOptions(MethodOptions(..)) import qualified Text.DescriptorProtos.ServiceOptions as D(ServiceOptions) import qualified Text.DescriptorProtos.ServiceOptions as D.ServiceOptions(ServiceOptions(..)) import Text.DescriptorProtos(fileDescriptorProto) -- for testing import Data.Maybe(listToMaybe) import Text.ProtocolBuffers(fromString,Utf8,getVal,Seq) import qualified Data.Foldable as F(toList) class DescendClass a c where descend' :: a -> Utf8 -> (Maybe c) descend :: DescendClass a c => String -> a -> Maybe c descend = flip descend' . fromString class DescendKey a where descendKey' :: a -> Utf8 -> Maybe D.FieldDescriptorProto descendKey :: DescendKey a => String -> a -> Maybe D.FieldDescriptorProto descendKey = flip descendKey' . fromString class NameAndOptions a opt | a -> opt, opt -> a where name :: a -> Utf8 options :: a -> opt -- helper search :: (NameAndOptions a b) => Seq a -> Utf8 -> Maybe a search s n = listToMaybe [ m | m <- F.toList s, n == name m ] instance DescendClass D.DescriptorProto D.DescriptorProto where descend' dp = search (D.DescriptorProto.nested_type dp) instance DescendClass D.DescriptorProto D.EnumDescriptorProto where descend' dp = search (D.DescriptorProto.enum_type dp) instance DescendClass D.DescriptorProto D.FieldDescriptorProto where descend' dp = search (D.DescriptorProto.field dp) instance DescendClass D.FileDescriptorProto D.DescriptorProto where descend' dp = search (D.FileDescriptorProto.message_type dp) instance DescendClass D.FileDescriptorProto D.EnumDescriptorProto where descend' dp = search (D.FileDescriptorProto.enum_type dp) instance DescendClass D.FileDescriptorProto D.ServiceDescriptorProto where descend' dp = search (D.FileDescriptorProto.service dp) instance DescendClass D.EnumDescriptorProto D.EnumValueDescriptorProto where descend' dp = search (D.EnumDescriptorProto.value dp) instance DescendClass D.ServiceDescriptorProto D.MethodDescriptorProto where descend' dp = search (D.ServiceDescriptorProto.method dp) instance DescendKey D.FileDescriptorProto where descendKey' dp = search (D.FileDescriptorProto.extension dp) instance DescendKey D.DescriptorProto where descendKey' dp = search (D.DescriptorProto.extension dp) instance NameAndOptions D.FileDescriptorProto D.FileOptions where name = flip getVal D.FileDescriptorProto.name options = flip getVal D.FileDescriptorProto.options instance NameAndOptions D.DescriptorProto D.MessageOptions where name = flip getVal D.DescriptorProto.name options = flip getVal D.DescriptorProto.options instance NameAndOptions D.FieldDescriptorProto D.FieldOptions where name = flip getVal D.FieldDescriptorProto.name options = flip getVal D.FieldDescriptorProto.options instance NameAndOptions D.ServiceDescriptorProto D.ServiceOptions where name = flip getVal D.ServiceDescriptorProto.name options = flip getVal D.ServiceDescriptorProto.options instance NameAndOptions D.MethodDescriptorProto D.MethodOptions where name = flip getVal D.MethodDescriptorProto.name options = flip getVal D.MethodDescriptorProto.options instance NameAndOptions D.EnumValueDescriptorProto D.EnumValueOptions where name = flip getVal D.EnumValueDescriptorProto.name options = flip getVal D.EnumValueDescriptorProto.options instance NameAndOptions D.EnumDescriptorProto D.EnumOptions where name = flip getVal D.EnumDescriptorProto.name options = flip getVal D.EnumDescriptorProto.options toDP :: DescendClass a D.DescriptorProto => String -> a -> Maybe D.DescriptorProto toDP s a = descend' a (fromString s) toEP :: DescendClass a D.EnumDescriptorProto => String -> a -> Maybe D.EnumDescriptorProto toEP s a = descend' a (fromString s) toSP :: String -> D.FileDescriptorProto -> Maybe D.ServiceDescriptorProto toSP s a = descend' a (fromString s) toFP :: String -> D.DescriptorProto -> Maybe D.FieldDescriptorProto toFP s a = descend' a (fromString s) toEVP :: String -> D.EnumDescriptorProto -> Maybe D.EnumValueDescriptorProto toEVP s a = descend' a (fromString s) toMP :: String -> D.ServiceDescriptorProto -> Maybe D.MethodDescriptorProto toMP s a = descend' a (fromString s) test1 :: D.FileOptions test1 = options fileDescriptorProto test2 :: Maybe D.MessageOptions test2 = return fileDescriptorProto >>= descend "FieldDescriptorProto" >>= return . options test3 :: Maybe D.EnumOptions test3 = return fileDescriptorProto >>= toDP "FieldDescriptorProto" >>= descend "Type" >>= return . options test4 :: Maybe D.EnumValueOptions test4 = return fileDescriptorProto >>= toDP "FieldDescriptorProto" >>= toEP "Type" >>= descend "TYPE_DOUBLE" >>= return . options test5 :: Maybe D.FieldOptions test5 = return fileDescriptorProto >>= toDP "DescriptorProto" >>= toDP "ExtensionRange" >>= descend "start" >>= return . options test6 :: Maybe D.ServiceOptions test6 = return fileDescriptorProto >>= descend "ImaginaryService" >>= return . options test7 :: Maybe D.MethodOptions test7 = return fileDescriptorProto >>= toSP "ImaginaryService" >>= descend "ImaginaryMethod" >>= return . options