class ProtobufDescriptor # Mixin module to support classes with different "kinds" of children module HasChildren def self.included(base) base.extend(ClassMethods) end module ClassMethods # To be called by the containing class, registers a set of children def register_children(children_method, child_kind_id) @registered_children ||= Hash.new { |h, k| h[k] = [] } @registered_children[child_kind_id] = children_method end def registered_children return @registered_children end end def named_children return @named_children if @named_children @named_children = NamedCollection.new([]) self.class.registered_children.each do |id, method| collection = self.send(method) collection = collection.is_a?(NamedCollection) ? collection.collection : collection collection.each do |m| @named_children << m if m.is_a?(NamedChild) end end return @named_children end # Computes the "relative path" from this node to one of its direct children # according to the rules specified by # [descriptor.proto line 506](https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto#506). def compute_source_code_info_path_component(child) self.class.registered_children.each do |kind_id, collection| idx = self.send(collection).find_index(child) if !idx.nil? return [kind_id, idx] end end raise "Could not find #{child} in #{self}" end end end