~bduggan/raku-protobuf

fc625f9697d6b525126d5d08ac683cb48e704f9c — Brian Duggan 7 months ago 5e4889a
Nested types
4 files changed, 41 insertions(+), 5 deletions(-)

A eg/nested.proto
M lib/Protobuf/Actions.rakumod
M lib/Protobuf/Grammar.rakumod
A t/04-nested.rakutest
A eg/nested.proto => eg/nested.proto +22 -0
@@ 0,0 1,22 @@
syntax = "proto3";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  rpc Echo (EchoRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

message EchoRequest {
  HelloRequest hello = 1;
  string world = 2;
}


M lib/Protobuf/Actions.rakumod => lib/Protobuf/Actions.rakumod +9 -5
@@ 26,11 26,10 @@ class Protobuf::Actions {
    my @things := $<proto>.made.List;
    my @services = @things.grep( * ~~ Protobuf::Service );
    my @messages = @things.grep( * ~~ Protobuf::Message );
    my %messages = @messages.map: { .name => $_ }
    for @services -> $s {
      for $s.endpoints -> $e {
        $e.request = %messages{ $e.request.name };
        $e.response = %messages{ $e.response.name };
        $e.request = %*messages{ $e.request.name };
        $e.response = %*messages{ $e.response.name };
      }
    }
    $/.make: Protobuf::Definition.new: :@services, :@messages;


@@ 45,7 44,11 @@ class Protobuf::Actions {
  }

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

  method messageBody($/) {


@@ 53,7 56,8 @@ class Protobuf::Actions {
  }

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

  method service($/) {

M lib/Protobuf/Grammar.rakumod => lib/Protobuf/Grammar.rakumod +1 -0
@@ 290,6 290,7 @@ rule topLevelDef {
}

rule TOP {
  :my %*messages;
  [ \s
    | [ '//' \V* [$|\n] ]
  ]*

A t/04-nested.rakutest => t/04-nested.rakutest +9 -0
@@ 0,0 1,9 @@
use Protobuf;
use Test;

my $m = parse-proto($?FILE.IO.parent.parent.child('eg/nested.proto').slurp);
my @services = $m.services;
is @services[0].endpoints[1].request.fields[0].type.name, 'HelloRequest', 'type name';
is @services[0].endpoints[1].request.fields[0].type.fields[0].name, 'name', 'type has nested attributes';

done-testing;