@@ -5,14 +5,17 @@ module Main (main) where
55
66import Prelude
77
8- import Control.Monad.Rec.Class (tailRecM , Step (..))
8+ import Control.Monad.Rec.Class (class MonadRec , Step (..), tailRecM )
9+ import Control.Monad.Trans.Class (lift )
910import Data.Array (catMaybes , concat , fold , mapWithIndex )
1011import Data.Array as Array
1112import Data.ArrayBuffer.ArrayBuffer as AB
1213import Data.ArrayBuffer.Builder (execPutM )
1314import Data.ArrayBuffer.DataView as DV
15+ import Data.ArrayBuffer.Types as ABT
1416import Data.CodePoint.Unicode as Unicode
1517import Data.Either (Either (..), either )
18+ import Data.List as List
1619import Data.Maybe (Maybe (..), fromMaybe , maybe )
1720import Data.Newtype (unwrap )
1821import Data.String (Pattern (..))
@@ -22,11 +25,12 @@ import Data.String.Regex as String.Regex
2225import Data.String.Regex.Flags as String.Regex.Flags
2326import Data.Traversable (sequence , traverse )
2427import Data.Tuple (Tuple (..))
28+ import Data.UInt as UInt
2529import Data.UInt64 (UInt64 )
2630import Data.UInt64 as UInt64
2731import Effect (Effect )
2832import Effect.Aff (runAff_ , throwError , error )
29- import Effect.Class (liftEffect )
33+ import Effect.Class (class MonadEffect , liftEffect )
3034import Effect.Class.Console as Console
3135import Google.Protobuf.Compiler.Plugin (CodeGeneratorRequest (..), CodeGeneratorResponse , CodeGeneratorResponse_File (..), mkCodeGeneratorResponse , parseCodeGeneratorRequest , putCodeGeneratorResponse )
3236import Google.Protobuf.Descriptor (DescriptorProto (..), EnumDescriptorProto (..), EnumValueDescriptorProto (..), FieldDescriptorProto (..), FieldDescriptorProto_Label (..), FieldDescriptorProto_Type (..), FieldOptions (..), FileDescriptorProto (..), OneofDescriptorProto (..), SourceCodeInfo (..), SourceCodeInfo_Location (..))
@@ -35,7 +39,13 @@ import Node.Buffer as Buffer
3539import Node.Path (basenameWithoutExt )
3640import Node.Process (stdin , stdout )
3741import Node.Stream.Aff (readSome , write )
38- import Parsing (runParserT )
42+ import Parsing (ParserT , fail , runParserT )
43+ import Parsing.Combinators (try , many )
44+ import Parsing.DataView (takeN )
45+ import Partial.Unsafe (unsafePartial )
46+ import Protobuf.Internal.Common (label )
47+ import Protobuf.Internal.Decode (decodeString , decodeTag32 )
48+ import Protobuf.Internal.Runtime (parseLenDel )
3949import Unsafe.Coerce (unsafeCoerce )
4050
4151
@@ -51,12 +61,15 @@ main = runAff_ (either (unsafeCoerce >>> Console.error) (\_ -> pure unit)) do
5161 {buffers:b,readagain} <- readSome stdin
5262 let bs' = bs <> b
5363 ab <- liftEffect $ toArrayBuffer =<< Buffer .concat bs'
54- runParserT (DV .whole ab) (parseCodeGeneratorRequest (AB .byteLength ab)) >>= case _ of
64+ bsize <- unsafePartial $ liftEffect $ Buffer .size $ Array .unsafeIndex b 0
65+ Console .error $ " read " <> show bsize <> " to " <> show (AB .byteLength ab)
66+ runParserT (DV .whole ab) (parseCodeGeneratorRequestComplete (AB .byteLength ab)) >>= case _ of
5567 Left err -> do
5668 if not readagain then do
5769 void $ throwError $ error " stdin is not readable."
5870 pure (Done unit)
5971 else if (Array .length bs') < 10000 then do
72+ Console .error $ show err
6073 -- What we want to do here is detect whether this parsing error was
6174 -- because we read to the end of the buffer and need to read more.
6275 -- But we don't have a good way to do that right now, so we assume
@@ -68,11 +81,82 @@ main = runAff_ (either (unsafeCoerce >>> Console.error) (\_ -> pure unit)) do
6881 else do
6982 void $ throwError $ error $ show err
7083 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)
84+ Right unit -> do
85+ runParserT (DV .whole ab) (parseCodeGeneratorRequest (AB .byteLength ab)) >>= case _ of
86+ Left err -> do
87+ void $ throwError $ error $ show err
88+ pure (Done unit)
89+ Right request -> do
90+ Console .error $ " parsed request, generating response"
91+ responseBuf <- execPutM $ putCodeGeneratorResponse (generate request)
92+ buf :: Buffer <- liftEffect $ fromArrayBuffer responseBuf
93+ write stdout [buf]
94+ pure (Done unit)
95+
96+ -- | This is a parser which will succeed only if parseCodeGeneratorRequest will succeed.
97+ -- | It is faster than parseCodeGeneratorRequest.
98+ -- | It uses extra assumptions about the order of the CodeGeneratorRequest fields.
99+ -- -- | Returns True if parseCodeGeneratorRequest will succeed.
100+ -- -- | Returns False if parseCodeGeneratorRequest might succeed with more input.
101+ parseCodeGeneratorRequestComplete
102+ :: forall m . MonadEffect m
103+ => MonadRec m
104+ => ABT.ByteLength
105+ -> ParserT ABT.DataView m Unit
106+ parseCodeGeneratorRequestComplete length = label " parseCodeGeneratorRequestComplete / " $ do
107+
108+ files_to_generate <- label " file_to_generate / " $ many $ try $ do
109+ Tuple fieldNumber wireType <- decodeTag32
110+ if fieldNumber == UInt .fromInt 1 then do decodeString else fail (show fieldNumber)
111+ -- lift $ Console.error $ "files_to_generate " <> s
112+
113+ if List .length files_to_generate == 0 then do fail " No files_to_generate" else pure unit
114+
115+ _ <- label " compiler_version / " $ do
116+ Tuple fieldNumber wireType <- decodeTag32
117+ if fieldNumber == UInt .fromInt 3 then do parseLenDel takeN else fail (show fieldNumber)
118+
119+ _ <- label " parameter / " $ do
120+ Tuple fieldNumber wireType <- decodeTag32
121+ if fieldNumber == UInt .fromInt 2 then do decodeString else fail (show fieldNumber)
122+
123+ proto_files <- label " proto_file / " $ many $ try $ do
124+ Tuple fieldNumber wireType <- decodeTag32
125+ if fieldNumber == UInt .fromInt 15 then do parseLenDel takeN else fail (show fieldNumber)
126+
127+ if List .length proto_files == 0 then do fail " No proto_files" else pure unit
128+
129+ source_file_descriptors <- label " source_file_descriptors / " $ many $ try $ do
130+ Tuple fieldNumber wireType <- decodeTag32
131+ if fieldNumber == UInt .fromInt 17 then do parseLenDel takeN else fail (show fieldNumber)
132+
133+ -- if Array.length source_file_descriptors == 0 then do fail "No source_file_descriptors" else pure unit
134+
135+ pure unit
136+
137+ -- Prelude.parseMessage CodeGeneratorRequest defaultCodeGeneratorRequest parseField length
138+ -- where
139+ -- parseField
140+ -- :: Prelude.FieldNumberInt
141+ -- -> Prelude.WireType
142+ -- -> Prelude.ParserT Prelude.DataView m (Prelude.Builder CodeGeneratorRequestR CodeGeneratorRequestR)
143+ -- parseField 1 Prelude.LenDel = Prelude.label "file_to_generate / " $ do
144+ -- x <- Prelude.decodeString
145+ -- pure $ Prelude.modify (Prelude.Proxy :: Prelude.Proxy "file_to_generate") $ Prelude.flip Prelude.snoc x
146+ -- parseField 2 Prelude.LenDel = Prelude.label "parameter / " $ do
147+ -- x <- Prelude.decodeString
148+ -- pure $ Prelude.modify (Prelude.Proxy :: Prelude.Proxy "parameter") $ \_ -> Prelude.Just x
149+ -- parseField 15 Prelude.LenDel = Prelude.label "proto_file / " $ do
150+ -- x <- Prelude.parseLenDel Google.Protobuf.parseFileDescriptorProto
151+ -- pure $ Prelude.modify (Prelude.Proxy :: Prelude.Proxy "proto_file") $ Prelude.flip Prelude.snoc x
152+ -- parseField 17 Prelude.LenDel = Prelude.label "source_file_descriptors / " $ do
153+ -- x <- Prelude.parseLenDel Google.Protobuf.parseFileDescriptorProto
154+ -- pure $ Prelude.modify (Prelude.Proxy :: Prelude.Proxy "source_file_descriptors") $ Prelude.flip Prelude.snoc x
155+ -- parseField 3 Prelude.LenDel = Prelude.label "compiler_version / " $ do
156+ -- x <- Prelude.parseLenDel parseVersion
157+ -- pure $ Prelude.modify (Prelude.Proxy :: Prelude.Proxy "compiler_version") $ Prelude.Just Prelude.<<< Prelude.maybe x (mergeVersion x)
158+ -- parseField fieldNumber wireType = Prelude.parseFieldUnknown fieldNumber wireType
159+
76160
77161generate :: CodeGeneratorRequest -> CodeGeneratorResponse
78162generate (CodeGeneratorRequest { proto_file }) = do
0 commit comments