Skip to content

Add QuasiQuoter for proto3 syntax lifting to DotProto#296

Open
riz0id wants to merge 14 commits intomasterfrom
riz0id/proto3-quasiquote
Open

Add QuasiQuoter for proto3 syntax lifting to DotProto#296
riz0id wants to merge 14 commits intomasterfrom
riz0id/proto3-quasiquote

Conversation

@riz0id
Copy link
Collaborator

@riz0id riz0id commented Nov 12, 2025

This pull request adds a quasi-quoter that can be used to embed a *.proto file in Haskell. The use case I needed the proto3 :: QuasiQuoter for was bringing *.proto files used for testing (i.e. files under {githubRoot}/test-file) into the test suite as a series of quasi-quote splices containing the file source in a Haskell module.

This is part of a string of work to remove bootstrapping from the Nix build process as it is the cause of many issues in CI and frequently blocks additions of features. The plan is to:

  1. Move all protobuf files in ./test-files/ to a Haskell module.
  2. Eliminate the need for explicit ./test-files/*. Test files will be rendered from the Haskell splices containing the protobuf source.
  3. Perform as much testing as possible within Haskell test suite so that python, bash, and turtle calls in the test suite for testing code generation can be removed.
  4. Once the necessary turtle calls are removed from the test suite (example) the bootstrapping charge is pushed on to template-haskell where far less moving parts are required to check that our sample protobuf files are being compiled correctly.
  5. With bootstrapping removed the shell.nix and default.nix will be replaced by a flake.nix
  6. CI will be set to follow the unstable nixpkgs flake rather than a particular pinned version on Hydra.

All of this should eliminate future issues in CI and speed up build time significantly.

@riz0id riz0id requested review from j6carey and rkaippully November 12, 2025 19:59
@riz0id riz0id self-assigned this Nov 12, 2025
@riz0id riz0id requested a review from j6carey November 13, 2025 21:54
import qualified Turtle hiding (encodeString)
import qualified Turtle.Compat as Turtle (encodeString)
import Turtle (FilePath, (</>), (<.>))
import NeatInterpolation qualified as Neat
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change just this one import to use ImportQualifiedPost, but not the others?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import was removed and I added it back with post qualification.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to minimize diffs meanwhile. I'm not a huge fan of formatting tools, but I'm fine with manually imposing a style on imports. My current favorite is alphabetized by module name, always using ImportQualifiedPost so that that module name comes first, saves on indentation, and makes it easy to just use a sort-lines feature in whatever editor is handy. For long identifier lists I typically move them to the next line and word-wrap them.

(</>))
import Turtle.Format ((%))
import qualified Turtle.Format as F
import NeatInterpolation qualified as Neat
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change just this one import to use ImportQualifiedPost, but not the others?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the import and added it back with the post qualification. We can format the entire repo with a formatting tool later on I don't know if it matters.

Copy link
Collaborator

@j6carey j6carey Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to minimize diffs meanwhile. I'm not a huge fan of formatting tools, but I'm fine with manually imposing a style on imports. My current favorite is alphabetized by module name, always using ImportQualifiedPost so that that module name comes first, saves on indentation, and makes it easy to just use a sort-lines feature in whatever editor is handy. For long identifier lists I typically move them to the next line and word-wrap them.

@riz0id riz0id mentioned this pull request Nov 15, 2025
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE QuasiQuotes #-}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why move this pragma from its alphabetical position?

{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE QuasiQuotes #-}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why move this pragma out of its alphabetical position?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it and unremoved it.


parseProtoWithFile :: Path -> String -> String -> Either ParseError DotProto
-- | Parse a protobuf source string with an associated module path and file
-- path.
Copy link
Collaborator

@j6carey j6carey Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the module path and file path used for? Just error messages? Whatever the answer, I think it would be good to include that detail in the comment.

)
where

import Control.Applicative (liftA2)
Copy link
Collaborator

@j6carey j6carey Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment only: I guess this is the sort of import that would make warnings-as-errors a pain for hackage maintainers, because it is sometimes redundant and sometimes required, depending upon the version of base.


case parseProtoWithFile pkg (show modName) input of
Left err -> fail (show err)
Right expr -> TH.lift expr No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is probably best to end each line with a newline, in order to be friendly to various tools. Not a big deal, though.

@riz0id riz0id mentioned this pull request Nov 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants