Stack Level Too Deep Exception when creating self referenced field type
kb opened this issue · 4 comments
I'm running into a Stack Level Too Deep issue when defining a field within itself. Essentially I'm looking into nesting more Baz objects within a Baz object (exert from my generated file below)
class Baz < ::ProtocolBuffers::Message
optional ::Foo::Bar::Baz, :caused_by, 1
gen_methods! # new fields ignored after this point
end
However the gem blows up on the self.fields method on the Message class. The calling class is the Decoder from self.decode. Everything goes smoothly until it hits the field definition for Baz within the Baz class and the gem gets stuck referencing self.fields over and over again until it hits a stack level too deep exception.
I currently have this functionality working properly for both Java and C protobufs, so I'm not exactly sure why the ruby version isn't behaving in the same manner.
Any ideas?
Sounds like a pretty clear bug, I don't think anybody has tried to use a recursive message with ruby-protocol-buffers before.
I'll dig into this a bit more and see if I can work a fix out for it. Do you have any recommendations as to where I should start looking into a fix for this? I'm just getting into the inner workings of the gem now.
I'm not sure, but I'd guess that maybe the decoder is not being lazy enough -- maybe it's instantiating a sub-object to parse even if the field is blank, throwing things into a loop. If you don't have any luck tracking it down, I might get a chance this weekend to test it out.
I believe I've tracked down the issue that causes the looping, which eventually throws the Stack Level Too Deep exception.
Within the else
block in the def initialize(attributes = { })
method on the Message
class there is a call to field.default_value
. This calls the def default_value
method on the MessageField
class. The MessageField
class is initialized with the proxy_class of recursive field, so when default_value
is called and executes @proxy_class.new
within the def default_value
method on the MessageField
it calls def initialize(attributes = { })
method on the Message
class again. This fun process happens until the exception is thrown.
Any good ideas on resolving this issue?