Add another option to support java_implement_interface

30 views
Skip to first unread message

aantono

unread,
Dec 1, 2008, 9:46:20 PM12/1/08
to Protocol Buffers, jcat...@orbitz.com, ken...@google.com
I would like to propose an enhancement to the java options for protoc.
This enhancement would allow one to specify the java interface which
the generated proto object will implement.

It would be very beneficial to be able to have the protoc generate
code that would be implementing some signature interfaces in the Java
world.

Unlike Python or Ruby, where if the method exists on an object, you
can call it, in Java the methods must be declared on the classes, so
it makes it difficult to write methods that could take multiple types
of objects which are of Protocol Buffers type without being able to
mark them with an Interface. Just knowing that the object is of type
"Message" is not sufficient.

Imagine you have an interface Name defining a method getName().
Then I can have a bunch of protos defining various kinds of "names",
like Person,
City, Country, etc. All of those objects have a "name" field, and
thus the getName()
method. By marking them all with a 'Name' interface, I can then have
my business
logic code accept objects of 'Name' type as method arguments and be
guaranteed that
there is a "getName()" method on them.

The problem with doing it the "reflection" route is that it does not
guarantee me a
compile-time checking and is not as clean and java-esque.

The proposed syntax would be:
message Person
java_implement_interface = com.domain.Name;
required string name;
required int32 age;
}

Please post your thoughts, comments & objections... :)

Kenton Varda

unread,
Dec 1, 2008, 10:12:41 PM12/1/08
to aantono, Protocol Buffers, jcat...@orbitz.com
On Mon, Dec 1, 2008 at 6:46 PM, aantono <aan...@gmail.com> wrote:
message Person
 java_implement_interface = com.domain.Name;
 required string name;
 required int32 age;
}

More precisely:

message Person {
  option java_implement_interface = "com.domain.Name";
  required string name = 1;
  required int32 age = 2;
}

And the effect of this is simply that when protoc generates the Person class, it declares it as implementing com.domain.Name.

This is a very simple change, so I may be convinced to accept it.  My main concerns are:

* Adding another option imposes non-zero overhead even on people who don't use the option, since it increases the code generated for descriptor.proto.  The size of descriptor.proto's generated code is already somewhat of a problem.

* I'm somewhat uneasy with the idea of generated protobuf code depending on non-generated code (other than standard libraries and libprotobuf).  This goes against the model.  It would not work in our internal build system, which assumes that protobuf code never has such dependencies.  I am worried that making the model more complicated in this way will lead to other problems down the road; e.g. if protocol buffers are integrated better into other build systems, they may also dislike this.

I can see where this feature would be useful but I'm not sure if it outweighs these issues.

What do other people think?

Chris

unread,
Dec 2, 2008, 11:23:06 AM12/2/08
to Kenton Varda, Protocol Buffers
Kenton Varda wrote:
> On Mon, Dec 1, 2008 at 6:46 PM, aantono <aan...@gmail.com
> <mailto:aan...@gmail.com>> wrote:
>
> message Person
> java_implement_interface = com.domain.Name <http://com.domain.Name>;

> required string name;
> required int32 age;
> }
>
>
> More precisely:
>
> message Person {
> option java_implement_interface = "com.domain.Name
> <http://com.domain.Name>";

> required string name = 1;
> required int32 age = 2;
> }
Why not use the new mechanism, putting the java extensions into
"java_ext.proto":

import "java_ext";

message Person {
option (java_ext.implement_interface) = "com.domain.Name
<http://com.domain.Name>";


required string name = 1;
required int32 age = 2;
}

>
> And the effect of this is simply that when protoc generates the Person
> class, it declares it as implementing com.domain.Name

> <http://com.domain.Name>.


>
> This is a very simple change, so I may be convinced to accept it. My
> main concerns are:
>
> * Adding another option imposes non-zero overhead even on people who
> don't use the option, since it increases the code generated for
> descriptor.proto. The size of descriptor.proto's generated code is
> already somewhat of a problem.

The java_ext.proto code would not be part of descriptor.proto code.
Non-java targets could eliminate it.


> * I'm somewhat uneasy with the idea of generated protobuf code
> depending on non-generated code (other than standard libraries and
> libprotobuf). This goes against the model. It would not work in our
> internal build system, which assumes that protobuf code never has such
> dependencies. I am worried that making the model more complicated in
> this way will lead to other problems down the road; e.g. if protocol
> buffers are integrated better into other build systems, they may also
> dislike this.
>
> I can see where this feature would be useful but I'm not sure if it
> outweighs these issues.
>
> What do other people think?

I think that having target specific "java_ext.proto",
"python_ext.proto", and "cpp_ext.proto" that define hints to protoc's
code generation would be a good idea. The existing java* options and
the "ctype=CORD" options are legacy examples that would be in
"java_ext.proto" and "cpp_ext.proto" if redesigned today. This way
"descriptor.proto" is stable against adding target specific extensions.
The code bloat only occurs on the target platform, though there is data
bloat in the reflection storage on all platforms.

Is there any technical reason it could not go into a separate
"java_ext.proto" file?

Kenton Varda

unread,
Dec 2, 2008, 3:13:51 PM12/2/08
to Chris, Protocol Buffers
Hmm, that's a good idea.  They'd still have to be compiled into protoc, but at least they wouldn't have to be compiled into client code.  The only problem is that it adds complication, I suppose.

My second point is still an issue.
Reply all
Reply to author
Forward
0 new messages