content: 
  module Test.Proto.Parse.Gen
    ( optionId,
      optionName,
      optionQName,
      optionKw,
    )
  where
  
  import Hedgehog (Gen)
  import qualified Hedgehog.Gen as Gen
  import qualified Hedgehog.Range as Range
  
  import Control.Applicative (liftA2)
  import qualified Data.List.NonEmpty as NonEmpty
  
  import Proto3.Suite.DotProto.AST
  
  optionId :: Gen DotProtoIdentifier
  optionId = Gen.choice [optionName, optionQName]
  
  optionQName :: Gen DotProtoIdentifier
  optionQName = liftA2 Qualified optionName optionName
  
  optionName :: Gen DotProtoIdentifier
  optionName =
    Gen.sized $ \s -> do
      let range = Range.linear 1 (fromIntegral s)
      nms <- Gen.nonEmpty range gNameString
      pure $ if null (NonEmpty.tail nms)
        then Single (NonEmpty.head nms)
        else Dots (Path nms)
    where
      gNameString :: Gen String
      gNameString =
        Gen.sized $ \s -> do
          let range = Range.linear 1 (fromIntegral s)
          chr <- Gen.alpha
          chrs <- Gen.list range Gen.alphaNum
          pure (chr : chrs)
  
  optionKw :: Gen String
  optionKw = do
    lspace <- whitespace
    rspace <- whitespace
    pure (lspace ++ "option" ++ rspace)
  
  whitespace :: Gen String
  whitespace =
    Gen.sized $ \s -> do
      len <- Gen.int (Range.linear 0 (fromIntegral s))
      pure (replicate len ' ')
  