tomas-abrahamsson / gpb

A Google Protobuf implementation for Erlang

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unhelpful error (no case clause matching undefined)

nisbus opened this issue · comments

I'm trying to generate code from a file with a lot of references and it doesn't look like it's not finding files anymore.

The settings I've added to rebar.config are the following:

{gpb_opts, [
 	    {recursive, true}
]}.
{pre_hooks,
 [{compile, "mkdir -p include"},
  {compile, "mkdir -p src"},
  {compile,
   "modules/gpb/bin/protoc-erl"
   " -I `pwd`/apps/convert/src"
   " -o-erl src -o-hrl include -json -pkgs `pwd`/apps/convert/src/resources.proto"
  }]}.

escript: exception error: no case clause matching undefined
  in function  gpb_gen_encoders:field_encode_expr/10 (src/gpb_gen_encoders.erl, line 343)
  in call from gpb_gen_encoders:'-format_msg_encoder/6-fun-2-'/6 (src/gpb_gen_encoders.erl, line 277)
  in call from lists:mapfoldl/3 (lists.erl, line 1354)
  in call from lists:mapfoldl/3 (lists.erl, line 1355)
  in call from gpb_gen_encoders:format_msg_encoder/6 (src/gpb_gen_encoders.erl, line 265)
  in call from gpb_gen_encoders:'-format_msg_encoders/4-lc$^0/1-0-'/5 (src/gpb_gen_encoders.erl, line 227)
  in call from gpb_gen_encoders:'-format_msg_encoders/4-lc$^0/1-0-'/5 (src/gpb_gen_encoders.erl, line 232)
  in call from gpb_gen_encoders:format_msg_encoders/4 (src/gpb_gen_encoders.erl, line 232)

Any clues you could give me as to what the issue actually is?

Thanks,
nisbus

What version of gpb are you running, and is it possible to share the protos so I could try to reproduce the issue?

Any clues you could give me as to what the issue actually is?

Sorry, forgot to say, the error looks like some internal bug in gpb: For some reason it for some message, it has lost whether a field is repeated etc, and just thinks it is undefined. I'm not sure how that could have happened, that's why it'd be useful to be able to reproduce the issue.

A long-shot one could also try is to see if it has something to do with the introduction of the new parser a while back (4.14.0), it is possible to force the old parser, either like below, or by setting the enviroment variable in the shell before you run rebar:

 {pre_hooks,
  [{compile, "mkdir -p include"},
   {compile, "mkdir -p src"},
   {compile,
-   "modules/gpb/bin/protoc-erl"
+   "env GPB_PARSER=old modules/gpb/bin/protoc-erl"
    " -I `pwd`/apps/convert/src"
    " -o-erl src -o-hrl include -json -pkgs `pwd`/apps/convert/src/resources.proto"
   }]}.

Thanks for getting back so soon!

I tested with the older parser (the version I'm using is just a clone of master from yesterday).
Now I get a different error:

resources.proto:60: syntax error before: deprecated

The part of the file that is complaining is this one:

message MYMESSAGE {
	uint64 my_id = 1;  // Unique identifier
        uint32 port = 2 [ (my.pb.options).deprecated = true];

This option is then declared like this:

syntax = "proto3";

import "google/protobuf/descriptor.proto";

package my.pb;

message MyDefaultValue {
  oneof value {
    string string = 1; // the string value is also used to set defaults on enum fields
    bool bool = 2;
    double double = 3;
    float float = 4;
    int32 int32 = 5;
    int64 int64 = 6;
    uint32 uint32 = 7;
    uint64 uint64 = 8;
  }
}

// FileOptions extensions with custom message
extend google.protobuf.FileOptions {
  FileMyOptions file_options = 10200;
}

// Custom protobuf field annotations
// Allows indicating required fields and default values for APIs
message FieldMyOptions {
  bool required = 1; // indicates that the field is required
  MyDefaultValue default = 2; // Default value for the field
  bool deprecated = 3; // indicates that the field is deprecated and should not be used by new clients
}

// FieldOptions extensions with my custom message
extend google.protobuf.FieldOptions {
  FieldMyOptions options = 10200;
}

// Custom protobuf grpc method options
message MethodMyOptions {
  bool deprecated = 1; // indicates that the RPC method is deprecated and should not be used by new clients
  bool unsupported = 2; // indicates that the RPC method is unsupported in current API version
}

// FieldOptions extensions with custom message
extend google.protobuf.MethodOptions {
  MethodMyOptions method_options = 10200;
}

So I'm guessing that the custom values are also the thing that is messing up the new parser.
I hope this helps.

Thanks,
nisbus

It looks like it was actually extend with proto3 syntax that was tripping gpb up, like in this excerpt:

extend google.protobuf.FileOptions {
  FileMyOptions file_options = 10200;
}

where there is neither optional nor required nor repeated since it is syntax = "proto3".

I have pushed a fix to a temporary branch, fix-extend-with-proto3-syntax, if you would want to try it out. I intend to merge it soon, along with a few other changes.

Thanks, this did the trick.
Great job!

The fix is merged and landed in 4.16.0