~bduggan/raku-protobuf

ref: 204a01ffb6bd0849698e8adf47a3b1bc4030f020 raku-protobuf/lib/Protobuf/Actions.rakumod -rw-r--r-- 1.7 KiB
204a01ffBrian Duggan doc 7 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class Protobuf::Service {
  has $.name;
  has @.endpoints;
}
class Protobuf::Definition {
  has @.services;
  has @.messages;
}
class Protobuf::Endpoint {
  has $.name;
  has $.request is rw;
  has $.response is rw;
}
class Protobuf::Message {
  has $.name;
  has @.fields;
}
class Protobuf::Field {
  has $.name;
  has $.type;
}

class Protobuf::Actions {

  method TOP($/) {
    my @things := $<proto>.made.List;
    my @services = @things.grep( * ~~ Protobuf::Service );
    my @messages = @things.grep( * ~~ Protobuf::Message );
    for @services -> $s {
      for $s.endpoints -> $e {
        $e.request = %*messages{ $e.request.name };
        $e.response = %*messages{ $e.response.name };
      }
    }
    $/.make: Protobuf::Definition.new: :@services, :@messages;
  }

  method proto($/) {
    $/.make: $<topLevelDef>.map( *.made ).grep( *.defined )
  }

  method topLevelDef($/) {
    $/.make: $<service>.made // $<message>.made
  }

  method message($/) {
    my $name = ~$<messageName>;
    my @fields = $<messageBody>.made;
    my $msg =  Protobuf::Message.new( :$name, :@fields );
    %*messages{ $name } = $msg;
    $/.make: $msg;
  }

  method messageBody($/) {
    $/.make: $<field>.map: *.made;
  }

  method field($/) {
    my $type = ~$<type>;
    $/.make: Protobuf::Field.new( name => ~$<fieldName>, type => %*messages{ $type } // $type );
  }

  method service($/) {
    $/.make: Protobuf::Service.new: name => ~$<serviceName>, endpoints => ($<rpc>.map(*.made).grep(*.defined))
  }

  method rpc($/) {
    $/.make: Protobuf::Endpoint.new(name => ~$<rpcName>, request => $<request>.?made, response => $<response>.?made )
  }

  method messageType($/) {
    $/.make: Protobuf::Message.new: name => ~$<messageName>
  }
}