Generic parsing class

482 views
Skip to first unread message

Miguel Muñoz

unread,
Jun 15, 2010, 4:30:15 PM6/15/10
to Protocol Buffers
Comrades,

I have a class I'd like to submit to the protocol buffer code base.
It's a class called GeneratedMessageParser, and it parses messages
from generic parameters. Here's why:

I have a glass called MessageTranceiver<M extends Message>. This class
needs to call the parseFrom() method of whatever message we specify
when we instantiate the class. But if you have this instance:

M message;

you can't say this:

message.parseFrom(buf);

because you don't have an instance of message, and you can't say

M.parseFrom(buf) either, because it's a static message. So I wrote
my parser class, which lets me say this:

GeneratedMessageParser<Requests.LoginRequest> parser
= new GeneratedMessageParser(Requests.LoginRequest.class);
...
message = parser.parseFrom(buf);

I've used protocol buffers on two projects, and this parser class has
been useful to both, so others may find it useful as well. It has
static methods that parallel all the standard parse methods, with
exactly the same signatures, including the declared exceptions. If
you'd like to see it, where do I send it?

Kenton Varda

unread,
Jun 15, 2010, 7:50:48 PM6/15/10
to Miguel Muñoz, Protocol Buffers
Try this:

M prototype = M.getDefaultInstance();

// later on
M instance = prototype.newBuilderForType().mergeFrom(data).build();


--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To post to this group, send email to prot...@googlegroups.com.
To unsubscribe from this group, send email to protobuf+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/protobuf?hl=en.


Miguel Muñoz

unread,
Jun 15, 2010, 8:48:19 PM6/15/10
to Kenton Varda, Protocol Buffers
Kenton,

  You try it!

  You can't say M.getDefaultInstanceForType() for the same reason you can't say M.parseFrom(buffer). You can't call any of the methods from M, because it's type information has been erased at runtime. That's why I wrote my parser class.

-- Miguel

-------------------------------------------

Miguel Muñoz

-------------------------------------------

The Sun, with all those planets revolving around it and dependent on it, can still ripen a vine of grapes like it had nothing else to do in the world.

  -- Galileo

-------------------------------------------

There are seven sins in the world.
    Wealth without work.
    Pleasure without conscience.
    Knowledge without character.
    Commerce without morality.
    Science without humanity.
    Worship without sacrifice.
    Politics without principle. 

  -- Mohandas Gandhi

-------------------------------------------

If tyranny and oppression come to this land, it will come in the guise of fighting a foreign enemy.

  -- James Madison



Kenton Varda

unread,
Jun 15, 2010, 9:27:48 PM6/15/10
to Miguel Muñoz, Protocol Buffers
Sorry, I should have been a bit clearer.

You've defined a new interface called GeneratedMessageParser, and when someone instantiates a generic class which needs to parse things, they need to pass in an instance of your interface to do the parsing.

I'm saying that they can just pass in the message type's default instance instead.  The default instance is explicitly intended to serve the purpose that your GeneratedMessageParser serves (among other things).

class Frobber<M extends Message> {
  M prototype;

  public Frobber(M prototype) {
    this.prototype = prototype;
  }

  public M parse(ByteString data) {
    return prototype.newBuilderForType().mergeFrom(data).build();
  }
}

// some code that uses this
Frobber<MyType> frobber = new Frobber<MyType>(MyType.getDefaultInstance());
MyType result = frobber.parse(someData);
Reply all
Reply to author
Forward
0 new messages