A Protobuf parser

A Protobuf parser for Go

This package contains a cleanroom Protobuf parser for Go using Participle.

This was originally an example within Participle.

Tests

Conformance tests are pulled from protoc and can be run with go test -tags conformance .. These are currently failing and will be enabled by default once passing. You can re-sync the upstream tests by running make -C testdata.

Comments
  • Complete options handling

    Complete options handling

    Complete the options handling in the compiler for all Options types, all options value types and for complex nested options. In the process, remove the special handling of all the known option fields since the method for parsing extension fields of options also applies to known fields.

    This parses a superset of options compared to what protoc handles. protoc does not allow the same option to be specified multiple times, even if that comes from first specifying a nested field of a message-based option value and then another specifying the whole message. The code here does parse that and just merges all the specified options. Buyer beware.


    The PR is split into separate commits which should make it easier to understand the separate bits of functionality.

    make lint is currently failing because the current version (1.43.0) is incompatible with Go 1.18 (latest). We'll either need to go back to 1.17 or wait for a new lint.

  • Add (transitive) imports to compiler package

    Add (transitive) imports to compiler package

    Rework compiler package for imports. Create new function

    compiler.NewFileDescriptorSet(filenames, importPaths, includeImports)
    

    and load .proto dependencies from file.

  • Make all conformance tests pass

    Make all conformance tests pass

    Apply a bunch of fixes so that all the conformance tests pass, and remove the code that skips the listed ones.

    • Extend the current patch (and rename) to turn off message_set_wire_format in all places, enabling the tests that were skipped purely because of that.
    • Fix handling of groups in oneofs.
    • Fix unquoting in the parser.
    • Fix formatting of field default values.
    • Specially handle the json_name field option.

    Fixes: https://github.com/alecthomas/protobuf/issues/38

  • Handle options on group fields

    Handle options on group fields

    A group is both a message and a field. Handle options on the field portion of the group. The message options within the group braces are already handled.

    Fixes: https://github.com/alecthomas/protobuf/issues/35

  • Extension range options apply to all comma separated ranges

    Extension range options apply to all comma separated ranges

    The syntax for extension ranges is:

      extensions a to max [options];
    

    or

      extensions a, b to c, d to max [options];
    

    When there are comma separated ranges, the options apply to all the ranges, not just the last one. The current parse tree attaches the options to the last of the range rather than all the ranges.

    Also the parser.Range struct includes the Options, which is also used for reserved ranges. These do not have options.

    I think the current code:

    type Extensions struct {
            Pos lexer.Position
            Extensions []*Range `"extensions" @@ { "," @@ }`
    }
    
    type Range struct {
            Start   int     `@Int`
            End     *int    `  [ "to" ( @Int`
            Max     bool    `           | @"max" ) ]`
            Options Options `[ "[" @@ { "," @@ } "]" ]`
    }
    

    should be

    type Extensions struct {
            Pos lexer.Position
            Extensions []*Range `"extensions" @@ { "," @@ }`
            Options Options `[ "[" @@ { "," @@ } "]" ]`
    }
    
    type Range struct {
            Start   int     `@Int`
            End     *int    `  [ "to" ( @Int`
            Max     bool    `           | @"max" ) ]`
    }
    
  • parser: Handle trailing comments in prototext options

    parser: Handle trailing comments in prototext options

    Parse trailing comments after the last field in a prototext option. This is useful for commenting out the last field of a prototext option, which is a time-honoured debugging tradition. It must be supported.

  • Add map<key,value> to compiler

    Add map to compiler

    Add map<key,value> to compiler which again required slightly bigger surgery as it is represented in protos as follows:

    For maps fields:
        map<KeyType, ValueType> map_field = 1;
    The parsed descriptor looks like:
        message MapFieldEntry {
            option map_entry = true;
            optional KeyType key = 1;
            optional ValueType value = 2;
        }
        repeated MapFieldEntry map_field = 1;
    
  • Add proto2 group to FileDescriptor

    Add proto2 group to FileDescriptor

    Add proto2 group to FileDescriptor in compiler package. This was bigger surgery than expected as groups can nest other messages, groups or enums. Additionally when groups are referenced as types they are classified as Messages. I've tried to cover most cases in the golden tests.

  • Initial compiler

    Initial compiler

    This PR is part 1 of many to get protobuf to generate FileDescriptor output.

    This PR deals with: scalar types, packages, Message definition and all kinds of nesting.

    It does not yet deal with imports, enums, extensions, services, options,.... 😅

  • byte escaped strings fail parsing

    byte escaped strings fail parsing

    This fails to parse

    optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"];
    

    with error

    testdata/conformance/unittest.proto:619:47: invalid quoted string "\"\\0\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\xfe\"": invalid syntax
    

    We will need to write a custom unquoter to fix this

  • Search global types before dynamic registry

    Search global types before dynamic registry

    When looking up the Registry for extensions and messages, first look in protoreflect.GlobalTypes so that concrete types are used where they are present in the program binary. This helps when the compiler is used as library in another program that has some concrete types built in (i.e. it has linked with generated protobuf code).

    This issue has become apparent when working github.com/foxygoat/jig directly with proto files. The dynamically generated FileDescriptorSet could not be type asserted against *annotations.HttpRule (source).

  • Poor performance with many *.proto files

    Poor performance with many *.proto files

    Initial performance tests have shown that single proto files with big dependency try (~2000 files) perform as was as protoc (seconds). However when compiling all these files individually, e.g. as

    protoc --include_imports -o all-protoc.pb -I . $(find . -name '*.proto')
    protobuf --include-imports -o all-protobuf.pb -I . $(find . -name '*.proto')
    

    protoc performs significantly faster (still seconds, whereas protobuf takes 10s of seconds).

    The cause for this may be found with how we build up ASTs in the compiler (possible duplicates!): https://github.com/alecthomas/protobuf/blob/master/compiler/compiler.go#L480

  • Known types should be limited via imports

    Known types should be limited via imports

    The compiler has a global types map that it populates with fully-qualified type names as it walks the parse tree. A subsequent pass then looks up this global map to resolve relative names to full names and their types. This means a file will see all types in the entire import hierarchy as valid. However the only types available to a .proto file are those defined in that file, those in any files it imports and those in any public imports of our imports.

    The types map should not be global, but per-file instead, tracking the types each file provides (either by defining them or publicly importing them) and looking up that and the type maps of the imports of a file.

go command line option parser

go-flags: a go library for parsing command line arguments This library provides similar functionality to the builtin flag library of go, but provides

Jan 4, 2023
Fully featured Go (golang) command line option parser with built-in auto-completion support.

go-getoptions Go option parser inspired on the flexibility of Perl’s GetOpt::Long. Table of Contents Quick overview Examples Simple script Program wit

Dec 14, 2022
CONTRIBUTIONS ONLY: A Go (golang) command line and flag parser

CONTRIBUTIONS ONLY What does this mean? I do not have time to fix issues myself. The only way fixes or new features will be added is by people submitt

Dec 29, 2022
Kong is a command-line parser for Go
Kong is a command-line parser for Go

Kong is a command-line parser for Go Introduction Help Help as a user of a Kong application Defining help in Kong Command handling Switch on the comma

Dec 27, 2022
HAProxy configuration parser
HAProxy configuration parser

HAProxy configuration parser autogenerated code if you change types/types.go you need to run go run generate/go-generate.go $(pwd) Contributing For co

Dec 14, 2022
Brigodier is a command parser & dispatcher, designed and developed for command lines such as for Discord bots or Minecraft chat commands. It is a complete port from Mojang's "brigadier" into Go.

brigodier Brigodier is a command parser & dispatcher, designed and developed to provide a simple and flexible command framework. It can be used in man

Dec 15, 2022
A simple command line time description parser

Zeit Zeit is an extremely simple command line application to read a natural language time description and output it as a timestamp. The main usecase f

Aug 21, 2021
APFS parser written in pure Go

[WIP] go-apfs ?? APFS parser written in pure Go Originally from this ipsw branch Install go get github.com/blacktop/go-apfs apfs cli Install go instal

Dec 24, 2022
A golang tag key value parser

tag_parser A golang tag key value parser Installation go get github.com/gvassili/tag_parser Example package main import ( "fmt" "github.com/gvass

Nov 24, 2021
Config File Parser

Config File Parser Speed It was Implemented by binary tree and only suitable for small project. Ignore Any line starting with specific prefix will be

May 20, 2022
YANG parser and compiler to produce Go language objects

Current support for goyang is for the latest 3 Go releases. goyang YANG parser and compiler for Go programs. The yang package (pkg/yang) is used to co

Dec 12, 2022
Golisp-wtf - A lisp interpreter (still just a parser) implementation in golang. You may yell "What the fuck!?.." when you see the shitty code.

R6RS Scheme Lisp dialect interpreter This is an implementation of a subset of R6RS Scheme Lisp dialect in golang. The work is still in progress. At th

Jan 7, 2022
Ghissue - This repo contains a github issue parser, that is useful for Enterprise Github accounts.

Ghissue - This repo contains a github issue parser, that is useful for Enterprise Github accounts. Sometimes is needed to parse the content of the issue for some data extraction or statistics purposes.

Feb 6, 2022
News-parser-cli - Simple CLI which allows you to receive news depending on the parameters passed to it
News-parser-cli - Simple CLI which allows you to receive news depending on the parameters passed to it

news-parser-cli Simple CLI which allows you to receive news depending on the par

Jan 4, 2022
Golang parser for Intuit Interchange Format (.IIF) files

Intuit Interchange Format (.IIF) Parser Install go get github.com/joshuaslate/iif Usage iiifile, err := os.Open("./transactions.iif") if err != nil {

Jan 15, 2022
minigli is a tiny command argument parser for Go.

minigli is a tiny command argument parser for Go.

Jan 29, 2022
Create a Protocol Buffers (Protobuf) plugin, which is executed with the protoc compileCreate a Protocol Buffers (Protobuf) plugin, which is executed with the protoc compile

Interview Assignment Overview You assignment is to create a Protocol Buffers (Protobuf) plugin, which is executed with the protoc compiler. In this ex

Nov 19, 2021
protoCURL is cURL for Protobuf: The command-line tool for interacting with Protobuf over HTTP REST endpoints using human-readable text formats

protoCURL protoCURL is cURL for Protobuf: The command-line tool for interacting with Protobuf over HTTP REST endpoints using human-readable text forma

Jan 6, 2023
A Protobuf parser

A Protobuf parser for Go This package contains a cleanroom Protobuf parser for Go using Participle. This was originally an example within Participle.

Nov 9, 2022
Protobuf files manager

Prot - protobuf files manager. It application can help your manage protobuf files and generate code based on him. !!! Before use Prot you must install

Jun 22, 2022