<commit_before>
package PRANG::Graph::Context;

use 5.010;
use Moose;
use MooseX::Method::Signatures;
use Moose::Util::TypeConstraints;

BEGIN {
	class_type "XML::LibXML::Element";
}

# this is a data class, it basically is like a loop counter for
# parsing (or emitting).  Except instead of walking over a list, it
# 'walks' over a tree of a certain, bound shape.

# The shape of the XML Graph at each node is limited to:
#
#  Seq -> Quant -> Choice -> Element -> ( Text | Null )
#
#  (any of the above may be absent)
#
# There are a few assumptions that nodes only connect as above, and
# not just in this class.

# These variables allow us to remember where we were.
has 'seq_pos' =>
	is => "rw",
	isa => "Int",
	lazy => 1,
	default => 1,
	trigger => sub {
		my $self = shift;
		$self->clear_quant;
		$self->clear_chosen;
		$self->clear_element_ok;
	},
	clearer => "clear_seq_pos",
	;

method reset() {
	$self->clear_seq_pos;
}

has 'quant_found' =>
	is => "rw",
	isa => "Int",
	lazy => 1,
	default => 0,
	clearer => 'clear_quant',
	trigger => sub {
		my $self = shift;
		$self->clear_chosen;
		$self->clear_element_ok;
	},
	;

has 'chosen' =>
	is => "rw",
	isa => "Int",
	clearer => "clear_chosen",
	trigger => sub {
		$_[0]->clear_element_ok;
	}
	;

has 'element_ok' =>
	is => "rw",
	isa => "Bool",
	clearer => "clear_element_ok",
	;

# For recursion, we need to know a couple of extra things.
has 'base' =>
	is => "ro",
	isa => 'PRANG::Marshaller',
	;

has 'xpath' =>
	is => "ro",
	isa => "Str",
	;

has 'xsi' =>
	is => "rw",
	isa => "HashRef",
	default => sub { {} },
	;

has 'old_xsi' =>
	is => "rw",
	isa => "HashRef",
	default => sub { {} },
	;

has 'rxsi' =>
	is => "rw",
	isa => "HashRef",
	lazy => 1,
	default => sub {
		my $self = shift;
		+{ reverse %{ $self->xsi } };
	},
	;

has 'xsi_virgin' =>
	is => "rw",
	isa => "Bool",
	default => 1,
	;

sub thing_xmlns {
	my $thing = shift;
	return unless blessed $thing;
	my $xmlns = shift;
	if ( $thing->can("preferred_prefix") ) {
		$thing->preferred_prefix($xmlns);
	}
	elsif ( $thing->can("xmlns_prefix") ) {
		$thing->xmlns_prefix($xmlns);
	}
}

method next_ctx( Maybe[Str] $xmlns, Str $newnode_name, $thing? )  {
	my $prefix = $self->prefix;
	my $new_prefix;
	if ( $xmlns ) {
		if ( !exists $self->rxsi->{$xmlns} ) {
			$new_prefix = 1;
			$prefix = thing_xmlns($thing, $xmlns) //
				$self->base->generate_prefix($xmlns);
		}
		else {
			$prefix = $self->get_prefix($xmlns);
		}
	}
	my $nodename = ($prefix ? "$prefix:" : "") . $newnode_name;

	my $clone = (ref $self)->new(
		prefix => $prefix,
		base => $self->base,
		xpath => $self->xpath."/".$nodename,
		xsi => $self->xsi,
		rxsi => $self->rxsi,
		@_
	       );
	if ( $new_prefix ) {
		$clone->add_xmlns($prefix, $xmlns);
	}
	$clone;
}

method prefix_new(Str $prefix) {
	!$self->xsi_virgin and not exists $self->old_xsi->{$prefix};
}

# this one is to know if the prefix was different to the parent type.
has 'prefix' =>
	is => "ro",
	isa => "Str",
	;

BEGIN { class_type "XML::LibXML::Node" };

method get_prefix( Str $xmlns, Object $thing?, XML::LibXML::Element $victim? ) {
	if ( defined(my $prefix = $self->rxsi->{$xmlns}) ) {
		$prefix;
	}
	else {<commit_msg>Context: remove the '@_' part<commit_after>
package PRANG::Graph::Context;

use 5.010;
use Moose;
use MooseX::Method::Signatures;
use Moose::Util::TypeConstraints;

BEGIN {
	class_type "XML::LibXML::Element";
}

# this is a data class, it basically is like a loop counter for
# parsing (or emitting).  Except instead of walking over a list, it
# 'walks' over a tree of a certain, bound shape.

# The shape of the XML Graph at each node is limited to:
#
#  Seq -> Quant -> Choice -> Element -> ( Text | Null )
#
#  (any of the above may be absent)
#
# There are a few assumptions that nodes only connect as above, and
# not just in this class.

# These variables allow us to remember where we were.
has 'seq_pos' =>
	is => "rw",
	isa => "Int",
	lazy => 1,
	default => 1,
	trigger => sub {
		my $self = shift;
		$self->clear_quant;
		$self->clear_chosen;
		$self->clear_element_ok;
	},
	clearer => "clear_seq_pos",
	;

method reset() {
	$self->clear_seq_pos;
}

has 'quant_found' =>
	is => "rw",
	isa => "Int",
	lazy => 1,
	default => 0,
	clearer => 'clear_quant',
	trigger => sub {
		my $self = shift;
		$self->clear_chosen;
		$self->clear_element_ok;
	},
	;

has 'chosen' =>
	is => "rw",
	isa => "Int",
	clearer => "clear_chosen",
	trigger => sub {
		$_[0]->clear_element_ok;
	}
	;

has 'element_ok' =>
	is => "rw",
	isa => "Bool",
	clearer => "clear_element_ok",
	;

# For recursion, we need to know a couple of extra things.
has 'base' =>
	is => "ro",
	isa => 'PRANG::Marshaller',
	;

has 'xpath' =>
	is => "ro",
	isa => "Str",
	;

has 'xsi' =>
	is => "rw",
	isa => "HashRef",
	default => sub { {} },
	;

has 'old_xsi' =>
	is => "rw",
	isa => "HashRef",
	default => sub { {} },
	;

has 'rxsi' =>
	is => "rw",
	isa => "HashRef",
	lazy => 1,
	default => sub {
		my $self = shift;
		+{ reverse %{ $self->xsi } };
	},
	;

has 'xsi_virgin' =>
	is => "rw",
	isa => "Bool",
	default => 1,
	;

sub thing_xmlns {
	my $thing = shift;
	return unless blessed $thing;
	my $xmlns = shift;
	if ( $thing->can("preferred_prefix") ) {
		$thing->preferred_prefix($xmlns);
	}
	elsif ( $thing->can("xmlns_prefix") ) {
		$thing->xmlns_prefix($xmlns);
	}
}

method next_ctx( Maybe[Str] $xmlns, Str $newnode_name, $thing? )  {
	my $prefix = $self->prefix;
	my $new_prefix;
	if ( $xmlns ) {
		if ( !exists $self->rxsi->{$xmlns} ) {
			$new_prefix = 1;
			$prefix = thing_xmlns($thing, $xmlns) //
				$self->base->generate_prefix($xmlns);
		}
		else {
			$prefix = $self->get_prefix($xmlns);
		}
	}
	my $nodename = ($prefix ? "$prefix:" : "") . $newnode_name;

	my $clone = (ref $self)->new(
		prefix => $prefix,
		base => $self->base,
		xpath => $self->xpath."/".$nodename,
		xsi => $self->xsi,
		rxsi => $self->rxsi,
	       );
	if ( $new_prefix ) {
		$clone->add_xmlns($prefix, $xmlns);
	}
	$clone;
}

method prefix_new(Str $prefix) {
	!$self->xsi_virgin and not exists $self->old_xsi->{$prefix};
}

# this one is to know if the prefix was different to the parent type.
has 'prefix' =>
	is => "ro",
	isa => "Str",
	;

BEGIN { class_type "XML::LibXML::Node" };

method get_prefix( Str $xmlns, Object $thing?, XML::LibXML::Element $victim? ) {
	if ( defined(my $prefix = $self->rxsi->{$xmlns}) ) {
		$prefix;
	}
	else {
{'fraction_non_alphanumeric': 0.1938567622629682, 'fraction_numerical': 0.0037611659614480487, 'mean_word_length': 3.462937062937063, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 177, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 34}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3595962', 'n_tokens_mistral': 2657, 'n_tokens_neox': 2549, 'n_words': 671}