Skip to content

Latest commit

 

History

History
 
 

adtproto

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

ADT-extended protobuf preprocessor

Input is approximately protobuf syntax, with a few extensions and a few missing parts. Output is (a) protobuf syntax (b) C++ code that checks structures for well-formedness.

In particular:

  1. Fields are "required" by default and are automatically given tags based on their order in the file. So instead of:

     required int foo = 1;
     optional string bar = 2;
    

    You write:

     int foo;
     optional string bar;
    

    These are arguably misfeatures.

  2. Adds a "data" construct to define an algebraic data type / variant / tagged union. Inside of "data" you define "branches". Branches can have associated data, which can either be a message, another type, or nothing.

    Example:

     data Example {
         branch Branch1 {
             // A message body goes here.
             int foo;
             string blah;
             repeated Example children;
         };
    
         // this branch is just an int, no message type
         branch Branch2 = int;
    
         // this branch has no associated data
         branch Branch3;
     };
    

    This turns into the following protobuf code:

     message Example {
         enum ExampleType {
             BRANCH1 = 0;
             BRANCH2 = 1;
             BRANCH3 = 2;
         };
         required ExampleType type = 1;
         message Branch1 {
             required int foo = 1;
             required string blah = 2;
             repeated Example children = 3;
         };
         optional Branch1 branch1 = 2;
         optional int branch2 = 3;
     };
    

    And the following C++ checker code:

     bool well_formed(const Example& self) {
         if (self.type == Example::BRANCH1 && !self.has_branch1())
             return false;
    
         if (self.has_branch1() && self.type != Example::BRANCH1)
             return false;
    
         if (self.type == Example::BRANCH2 && !self.has_branch2())
             return false;
    
         if (self.has_branch2() && self.type != Example::BRANCH2)
             return false;
    
         return true;
     }
    

Bugs

Doesn't recursively check for well-formedness yet.