Skip to content

Unable to use GRPC service RPC call "New" #485

@daniel-sullivan

Description

@daniel-sullivan

When attempting to compile Dart libraries for our existing platform, we came across a strange issue with one of the repositories where we have a definition similar to:

service Account {
  rpc Get(api.base.GetRequest) returns (api.account.Model);
  rpc Search(api.base.SearchRequest) returns (stream api.account.SearchResponse);
  rpc New(api.account.Model) returns (api.account.Model);
  rpc Update(api.account.Model) returns (api.account.Model);
  rpc Destroy(api.base.DestroyRequest) returns (google.protobuf.Empty);
}

We received an output similar to the below examples with the main error seeming to be "Constructors can't have type parameters.". Unfortunately Google didn't provide any suggestions.

Doing a bit of digging through commenting out lines, we discovered that the issue was being caused by this line:

  rpc New(api.account.Model) returns (api.account.Model);

Further reading into Dart suggests that with "new" being a reserved term in Dart, us using it as the rpc function name is causing a conflict.

This was verified by creating two files:

test_create.proto

syntax = "proto3";

message SimpleReq {
  string test = 1;
}

message SimpleResponse {
  string test = 1;
}

service TestService {
  rpc Create(SimpleReq) returns (SimpleResponse);
}
❯ protoc --dart_out=grpc:. test_create.proto
< successful return > 

test_new.proto

syntax = "proto3";

message SimpleReq {
  string test = 1;
}

message SimpleResponse {
  string test = 1;
}

service TestService {
  rpc New(SimpleReq) returns (SimpleResponse);
}
❯ protoc --dart_out=grpc:. test_new.proto
Unhandled exception:
Could not format because the source could not be parsed:

line 50, column 36: A function body must be provided.
   ╷
50 │   $async.Future<$0.SimpleResponse> new($grpc.ServiceCall call, $0.SimpleReq request);
   │                                    ^^^
   ╵
line 28, column 24: Expected to find '>'.
   ╷
28 │   $grpc.ResponseFuture<$0.SimpleResponse> new($0.SimpleReq request, {$grpc.CallOptions options}) {
   │                        ^^
   ╵
line 28, column 23: Constructors can't have type parameters.
   ╷
28 │   $grpc.ResponseFuture<$0.SimpleResponse> new($0.SimpleReq request, {$grpc.CallOptions options}) {
   │                       ^^^^^^^^^^^^^^^^^^^
   ╵
line 50, column 17: Expected to find '>'.
   ╷
50 │   $async.Future<$0.SimpleResponse> new($grpc.ServiceCall call, $0.SimpleReq request);
   │                 ^^
   ╵
line 28, column 3: Methods must have an explicit list of parameters.
   ╷
28 │   $grpc.ResponseFuture<$0.SimpleResponse> new($0.SimpleReq request, {$grpc.CallOptions options}) {
   │   ^^^^^
   ╵
line 50, column 16: Constructors can't have type parameters.
   ╷
50 │   $async.Future<$0.SimpleResponse> new($grpc.ServiceCall call, $0.SimpleReq request);
   │                ^^^^^^^^^^^^^^^^^^^
   ╵
line 28, column 3: The name of a constructor must match the name of the enclosing class.
   ╷
28 │   $grpc.ResponseFuture<$0.SimpleResponse> new($0.SimpleReq request, {$grpc.CallOptions options}) {
   │   ^^^^^
   ╵
line 28, column 43: A function body must be provided.
   ╷
28 │   $grpc.ResponseFuture<$0.SimpleResponse> new($0.SimpleReq request, {$grpc.CallOptions options}) {
   │                                           ^^^
   ╵
line 50, column 36: Expected a class member.
   ╷
50 │   $async.Future<$0.SimpleResponse> new($grpc.ServiceCall call, $0.SimpleReq request);
   │                                    ^^^
   ╵
line 50, column 3: The name of a constructor must match the name of the enclosing class.
   ╷
50 │   $async.Future<$0.SimpleResponse> new($grpc.ServiceCall call, $0.SimpleReq request);
   │   ^^^^^^
   ╵
(5 more errors...)
#0      DartFormatter.formatSource (package:dart_style/src/dart_formatter.dart:141:7)
#1      DartFormatter.format (package:dart_style/src/dart_formatter.dart:75:12)
#2      FileGenerator.generateGrpcFile (package:protoc_plugin/file_generator.dart:518:23)
#3      FileGenerator.generateFiles (package:protoc_plugin/file_generator.dart:252:44)
#4      CodeGenerator.generate.<anonymous closure> (package:protoc_plugin/code_generator.dart:114:36)
#5      _RootZone.runUnary (dart:async/zone.dart:1450:54)
#6      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
#7      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
#8      Future._propagateToListeners (dart:async/future_impl.dart:725:32)
#9      Future._complete (dart:async/future_impl.dart:519:7)
#10     Stream.fold.<anonymous closure> (dart:async/stream.dart:847:14)
#11     _RootZone.runGuarded (dart:async/zone.dart:1372:10)
#12     _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:410:13)
#13     _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:420:15)
#14     _BufferingStreamSubscription._close (dart:async/stream_impl.dart:305:7)
#15     _SyncStreamControllerDispatch._sendDone (dart:async/stream_controller.dart:816:19)
#16     _StreamController._closeUnchecked (dart:async/stream_controller.dart:671:7)
#17     _StreamController.close (dart:async/stream_controller.dart:664:5)
#18     _Socket._onData (dart:io-patch/socket_patch.dart:2051:21)
#19     _RootZone.runUnaryGuarded (dart:async/zone.dart:1384:10)
#20     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11)
#21     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:285:7)
#22     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:808:19)
#23     _StreamController._add (dart:async/stream_controller.dart:682:7)
#24     _StreamController.add (dart:async/stream_controller.dart:624:5)
#25     new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1587:35)
#26     _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1069:18)
#27     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
#28     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
#29     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:118:13)
#30     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:169:5)
--dart_out: protoc-gen-dart: Plugin failed with status code 255.

Would anyone have any suggestions which don't involve renaming the functions in this module? (which are currently being used by several other systems). Unfortunately, we're just starting to get into Dart coding so don't have the skills required to investigate solutions in a time efficient manner.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions