Git Product home page Git Product logo

protobuf-parser's Introduction

protobuf-parser

Simplified Protocol Buffers Version 3 and gRPC parser using Haskell and Parsec

Usage

> stack run -- --help
Usage: protobuf-parser-exe [-f|--file PATH] [-p|--pretty] [STRING...]

Available options:
  -f,--file PATH           Specify file path to parse
  -p,--pretty              Enable pretty print
  -h,--help                Show this help text
stack run -- -p -f ./test/E2E/protofiles/chat.proto
stack run -- -p "message SearchRequest { int32 page_number = 2; double results_per_page = 3; }"
stack run "import \"foo.proto\"; import \"bar.proto\"; package foobar;"

stack test

Structure

protobuf-parser
├── app
│   └── Main.hs -> CLI Parsing
├── ...
├── src
│   └── Text
│       └── Protobuf
│           ├── Parser -> Parser Combinators
│           │   ├── ...
│           │   └── *.hs
│           ├── Parser.hs -> Complete Protobuf Parser
│           └── Types.hs -> Protobuf Type representation
├── ...
└── test
    ├── E2E
    │   ├── ...
    │   └── protofiles -> Example Protobuf files
    │       └── *.proto
    ├── ...
    └── Unit
        └── ...

Simplifications

This projects acts as a parser combinator showcase project. Therefore, not all features are complete or correct:

  • Only proto3 syntax is supported
  • Not all values are check for correctness
  • Base Lexical Elements do not strictly follow the official spec
  • Proto 3 Ranges do not allow the keyword "min"
  • Empty statements are missing
  • Import weak and public are missing

Grammar

The correct and complete Grammar can be found at the official Protocol Buffers Version 3 Language Specification

Following is basic syntax in Extended Backus-Naur Form (EBNF):

|   alternation
()  grouping
[]  option (zero or one time)
{}  repetition (any number of times)
syntax = "syntax" "=" ("'" "proto3" "'" | '"' "proto3" '"') ";"


import = "import" [ "weak" | "public" ] strLit ";"


package = "package" fullIdent ";"


constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) |
                strLit | boolLit | MessageValue


option = "option" optionName  "=" constant ";"
optionName = ( ident | "(" ["."] fullIdent ")" )


type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64"
      | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64"
      | "bool" | "string" | "bytes" | messageType | enumType
fieldNumber = intLit;

field = [ "repeated" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
fieldOptions = fieldOption { ","  fieldOption }
fieldOption = optionName "=" constant

oneof = "oneof" oneofName "{" { option | oneofField } "}"
oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"

mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" |
          "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string"


reserved = "reserved" ( ranges | strFieldNames ) ";"
ranges = range { "," range }
range =  intLit [ "to" ( intLit | "max" ) ]
strFieldNames = strFieldName { "," strFieldName }
strFieldName = "'" fieldName "'" | '"' fieldName '"'


enum = "enum" enumName enumBody
enumBody = "{" { option | enumField | emptyStatement | reserved } "}"
enumField = ident "=" [ "-" ] intLit [ "[" enumValueOption { ","  enumValueOption } "]" ]";"
enumValueOption = optionName "=" constant


message = "message" messageName messageBody
messageBody = "{" { field | enum | message | option | oneof | mapField |
reserved | emptyStatement } "}"


service = "service" serviceName "{" { option | rpc | emptyStatement } "}"
rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ]
messageType ")" (( "{" {option | emptyStatement } "}" ) | ";")


proto = syntax { import | package | option | topLevelDef | emptyStatement }
topLevelDef = message | enum | service

protobuf-parser's People

Contributors

antonkesy avatar

Watchers

 avatar

protobuf-parser's Issues

[BUG]: Map type fails to parse in message

Protobuf File/Text

message Test {
  map<string, V> t = 0;
}
Parse error: "./test/E2E/protofiles/map.proto" (line 2, column 6):
unexpected "<"
expecting letter or digit, "_", space, "//", "/*", lf new-line, tab or letter

Enum parse error

Enum option and reserved fail to parse:

syntax = "proto3";

enum Data {
  option allow_alias = true;
  reserved 2, 15, 9 to 11, 4294967294 to max;
  DATA_UNSPECIFIED = 0;
  DATA_SEARCH = 1 [deprecated = true];
  DATA_DISPLAY = 2 [
    (string_name) = "display_value"
  ];
}
Parse error: (line 5, column 3):
unexpected "r"
expecting space, "//", "/*", lf new-line, tab or "}"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.