@@ -5,12 +5,13 @@ module Main (main) where
5
5
6
6
import Prelude
7
7
8
- import Control.Monad.Rec.Class (tailRecM , Step (..))
8
+ import Control.Monad.Rec.Class (class MonadRec , Step (..), tailRecM )
9
9
import Data.Array (catMaybes , concat , fold , mapWithIndex )
10
10
import Data.Array as Array
11
11
import Data.ArrayBuffer.ArrayBuffer as AB
12
12
import Data.ArrayBuffer.Builder (execPutM )
13
13
import Data.ArrayBuffer.DataView as DV
14
+ import Data.ArrayBuffer.Types as ABT
14
15
import Data.CodePoint.Unicode as Unicode
15
16
import Data.Either (Either (..), either )
16
17
import Data.Maybe (Maybe (..), fromMaybe , maybe )
@@ -22,20 +23,25 @@ import Data.String.Regex as String.Regex
22
23
import Data.String.Regex.Flags as String.Regex.Flags
23
24
import Data.Traversable (sequence , traverse )
24
25
import Data.Tuple (Tuple (..))
26
+ import Data.UInt as UInt
25
27
import Data.UInt64 (UInt64 )
26
28
import Data.UInt64 as UInt64
27
29
import Effect (Effect )
28
30
import Effect.Aff (runAff_ , throwError , error )
29
- import Effect.Class (liftEffect )
31
+ import Effect.Class (class MonadEffect , liftEffect )
30
32
import Effect.Class.Console as Console
31
- import Google.Protobuf.Compiler.Plugin (CodeGeneratorRequest (..), CodeGeneratorResponse , CodeGeneratorResponse_File (..), mkCodeGeneratorResponse , parseCodeGeneratorRequest , putCodeGeneratorResponse )
33
+ import Google.Protobuf.Compiler.Plugin (CodeGeneratorRequest (..), CodeGeneratorResponse , CodeGeneratorResponse_File (..), mkCodeGeneratorResponse , parseCodeGeneratorRequest , putCodeGeneratorResponse , parseVersion )
32
34
import Google.Protobuf.Descriptor (DescriptorProto (..), EnumDescriptorProto (..), EnumValueDescriptorProto (..), FieldDescriptorProto (..), FieldDescriptorProto_Label (..), FieldDescriptorProto_Type (..), FieldOptions (..), FileDescriptorProto (..), OneofDescriptorProto (..), SourceCodeInfo (..), SourceCodeInfo_Location (..))
33
35
import Node.Buffer (Buffer , toArrayBuffer , fromArrayBuffer )
34
36
import Node.Buffer as Buffer
35
37
import Node.Path (basenameWithoutExt )
36
38
import Node.Process (stdin , stdout )
37
39
import Node.Stream.Aff (readSome , write )
38
- import Parsing (runParserT )
40
+ import Parsing (ParserT , fail , runParserT )
41
+ import Parsing.DataView (takeN )
42
+ import Protobuf.Internal.Common (label )
43
+ import Protobuf.Internal.Decode (decodeString , decodeTag32 )
44
+ import Protobuf.Internal.Runtime (parseLenDel , manyLength )
39
45
import Unsafe.Coerce (unsafeCoerce )
40
46
41
47
@@ -51,7 +57,7 @@ main = runAff_ (either (unsafeCoerce >>> Console.error) (\_ -> pure unit)) do
51
57
{buffers:b,readagain} <- readSome stdin
52
58
let bs' = bs <> b
53
59
ab <- liftEffect $ toArrayBuffer =<< Buffer .concat bs'
54
- runParserT (DV .whole ab) (parseCodeGeneratorRequest (AB .byteLength ab)) >>= case _ of
60
+ runParserT (DV .whole ab) (parseCodeGeneratorRequestComplete (AB .byteLength ab)) >>= case _ of
55
61
Left err -> do
56
62
if not readagain then do
57
63
void $ throwError $ error " stdin is not readable."
@@ -68,11 +74,48 @@ main = runAff_ (either (unsafeCoerce >>> Console.error) (\_ -> pure unit)) do
68
74
else do
69
75
void $ throwError $ error $ show err
70
76
pure (Done unit)
71
- Right request -> do
72
- responseBuf <- execPutM $ putCodeGeneratorResponse (generate request)
73
- buf :: Buffer <- liftEffect $ fromArrayBuffer responseBuf
74
- write stdout [buf]
75
- pure (Done unit)
77
+ Right unit -> do
78
+ runParserT (DV .whole ab) (parseCodeGeneratorRequest (AB .byteLength ab)) >>= case _ of
79
+ Left err -> do
80
+ void $ throwError $ error $ show err
81
+ pure (Done unit)
82
+ Right request -> do
83
+ responseBuf <- execPutM $ putCodeGeneratorResponse (generate request)
84
+ buf :: Buffer <- liftEffect $ fromArrayBuffer responseBuf
85
+ write stdout [buf]
86
+ pure (Done unit)
87
+
88
+ -- | This is a parser which will succeed only if parseCodeGeneratorRequest will succeed.
89
+ -- | It is faster than parseCodeGeneratorRequest.
90
+ -- | We use this parser to determine if we have read the whole request from stdin.
91
+ -- | If this parser fails then we need to read more from stdin.
92
+ parseCodeGeneratorRequestComplete
93
+ :: forall m . MonadEffect m
94
+ => MonadRec m
95
+ => ABT.ByteLength
96
+ -> ParserT ABT.DataView m Unit
97
+ parseCodeGeneratorRequestComplete length = label " parseCodeGeneratorRequestComplete / " $ do
98
+ _ <- flip manyLength length do
99
+ Tuple fieldNumber _wireType <- decodeTag32
100
+ case UInt .toInt fieldNumber of
101
+ 1 -> do -- file_to_generate
102
+ _ <- decodeString
103
+ pure unit
104
+ 2 -> do -- parameter
105
+ _ <- decodeString
106
+ pure unit
107
+ 3 -> do -- compiler_version
108
+ _ <- parseLenDel parseVersion
109
+ pure unit
110
+ 15 -> do -- proto_file
111
+ _ <- parseLenDel takeN
112
+ pure unit
113
+ 17 -> do -- source_file_descriptors
114
+ _ <- parseLenDel takeN
115
+ pure unit
116
+ _ -> do
117
+ fail " unexpected field number"
118
+ pure unit
76
119
77
120
generate :: CodeGeneratorRequest -> CodeGeneratorResponse
78
121
generate (CodeGeneratorRequest { proto_file }) = do
0 commit comments