File Coverage

blib/lib/Data/Sah/Compiler.pm
Criterion Covered Total %
statement 359 425 84.4
branch 133 194 68.5
condition 68 120 56.6
subroutine 23 30 76.6
pod 3 11 27.2
total 586 780 75.1


line stmt bran cond sub pod time code
1              
2             use 5.010;
3 24     24   12614 use strict;
  24         80  
4 24     24   120 use warnings;
  24         41  
  24         425  
5 24     24   95  
  24         40  
  24         634  
6             #use Carp;
7             use Mo qw(default);
8 24     24   109 use Role::Tiny::With;
  24         42  
  24         101  
9 24     24   10987 use Log::ger;
  24         86001  
  24         1193  
10 24     24   3185 use Scalar::Util qw(blessed);
  24         137  
  24         199  
11 24     24   4620  
  24         50  
  24         23973  
12             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
13             our $DATE = '2022-10-19'; # DATE
14             our $DIST = 'Data-Sah'; # DIST
15             our $VERSION = '0.914'; # VERSION
16              
17             our %coercer_cache; # key=type, value=coercer coderef
18              
19             with 'Data::Sah::Compiler::TextResultRole';
20              
21             has main => (is => 'rw');
22              
23             # BEGIN COPIED FROM String::LineNumber
24             my ($str, $opts) = @_;
25             $opts //= {};
26 0     0   0 $opts->{width} //= 4;
27 0   0     0 $opts->{zeropad} //= 0;
28 0   0     0 $opts->{skip_empty} //= 1;
29 0   0     0  
30 0   0     0 my $i = 0;
31             $str =~ s/^(([\t ]*\S)?.*)/
32 0         0 sprintf(join("",
33 0         0 "%",
34             ($opts->{zeropad} && !($opts->{skip_empty}
35             && !defined($2)) ? "0" : ""),
36             $opts->{width}, "s",
37             "|%s"),
38             ++$i && $opts->{skip_empty} && !defined($2) ? "" : $i,
39             $1)/meg;
40 0 0 0     0  
    0 0        
41             $str;
42             }
43 0         0 # END COPIED FROM String::LineNumber
44              
45             die "BUG: Please override name()";
46             }
47              
48 0     0 0 0 # literal representation in target language
49             die "BUG: Please override literal()";
50             }
51              
52             # compile expression to target language
53 0     0 0 0 die "BUG: Please override expr()";
54             }
55              
56             my ($self, $cd, $msg) = @_;
57             die join(
58 0     0 0 0 "",
59             "Sah ". $self->name . " compiler: ",
60             "at schema:/", join("/", @{$cd->{spath} // []}), ": ",
61             # XXX show (snippet of) current schema
62 35     35   117 $msg,
63             );
64             }
65              
66 35   50     121 # form dependency list from which clauses are mentioned in expressions NEED TO
  35         1870  
67             # BE UPDATED: NEED TO CHECK EXPR IN ALL ATTRS FOR THE WHOLE SCHEMA/SUBSCHEMAS
68             # (NOT IN THE CURRENT CLSET ONLY), THERE IS NO LONGER A ctbl, THE WAY EXPR IS
69             # STORED IS NOW DIFFERENT. PLAN: NORMALIZE ALL SUBSCHEMAS, GATHER ALL EXPR VARS
70             # AND STORE IN $cd->{all_expr_vars} (SKIP DOING THIS IS
71             # $cd->{outer_cd}{all_expr_vars} is already defined).
72             #require Data::Graph::Util;
73             require Language::Expr::Interpreter::var_enumer;
74              
75             my ($self, $cd, $ctbl) = @_;
76             my $main = $self->main;
77              
78             my %depends;
79             for my $crec (values %$ctbl) {
80 0     0   0 my $cn = $crec->{name};
81             my $expr = defined($crec->{expr}) ? $crec->{value} :
82 0         0 $crec->{attrs}{expr};
83 0         0 if (defined $expr) {
84             my $vars = $main->_var_enumer->eval($expr);
85 0         0 for (@$vars) {
86 0         0 /^\w+$/ or $self->_die($cd,
87 0         0 "Invalid variable syntax '$_', ".
88             "currently only the form \$abc is supported");
89 0 0       0 $ctbl->{$_} or $self->_die($cd,
90 0 0       0 "Unhandled clause specified in variable '$_'");
91 0         0 }
92 0         0 $depends{$cn} = $vars;
93 0 0       0 for (@$vars) {
94             push @{ $ctbl->{$_}{depended_by} }, $cn;
95             }
96 0 0       0 } else {
97             $depends{$cn} = [];
98             }
99 0         0 }
100 0         0 #$log->tracef("deps: %s", \%depends);
101 0         0 #my @sorted = Data::Graph::Util::toposort(\%depends); # dies when cyclic
  0         0  
102             #$log->tracef("sorted: %s", \@sorted);
103             my %rsched = #map
104 0         0 #{@{ $depends{$sched->[$_]} } ? ($sched->[$_] => $_) : ()}
105             # 0..@$sched-1;
106             (); # TMP
107             #$log->tracef("deps: %s", \%rsched);
108             \%rsched;
109             }
110 0         0  
111             # generate a list of clauses in clsets, in order of evaluation. clauses are
112             # sorted based on expression dependencies and priority. result is array of
113             # [CLSET_NUM, CLAUSE, CLAUSEMETA] triplets, e.g. ([0, 'default', {...}], [1,
114             # 'default', {...}], [0, 'min', {...}], [0, 'max', {...}]).
115 0         0 my ($self, $cd, $clsets) = @_;
116             my $tn = $cd->{type};
117             my $th = $cd->{th};
118              
119             my $deps;
120             ## temporarily disabled, expr needs to be sorted globally
121             #if ($self->_clset_has_expr($clset)) {
122             # $deps = $self->_form_deps($ctbl);
123 10514     10514   22654 #} else {
124 10514         15749 # $deps = {};
125 10514         16188 #}
126             #$deps = {};
127 10514         11983  
128             my $sorter = sub {
129             my ($ia, $ca, $metaa) = @$a;
130             my ($ib, $cb, $metab) = @$b;
131             my $res;
132              
133             # dependency
134             #$res = ($deps->{"$ca.$ia"} // -1) <=> ($deps->{"$cb.$ib"} // -1);
135             #return $res if $res;
136              
137 1134     1134   2336 {
138 1134         1704 $res = $metaa->{prio} <=> $metab->{prio};
139 1134         1436 #$log->errorf("TMP: sort1");
140             last if $res;
141              
142             # prio from schema
143             my $sprioa = $clsets->[$ia]{"$ca.prio"} // 50;
144             my $spriob = $clsets->[$ib]{"$cb.prio"} // 50;
145             $res = $sprioa <=> $spriob;
146 1134         1671 #$log->errorf("TMP: sort2");
  1134         2003  
147             last if $res;
148 1134 100       2244  
149             # alphabetical order of clause name
150             $res = $ca cmp $cb;
151 108   50     486 #$log->errorf("TMP: sort3");
152 108   50     389 last if $res;
153 108         203  
154             # clause set order
155 108 50       218 $res = $ia <=> $ib;
156             #$log->errorf("TMP: sort4");
157             last if $res;
158 108         193  
159             $res = 0;
160 108 50       269 }
161              
162             #$log->errorf("TMP: sort [%s,%s] vs [%s,%s] = %s", $ia, $ca, $ib, $cb, $res);
163 0         0 $res;
164             };
165 0 0       0  
166             my @clauses;
167 0         0 for my $i (0..@$clsets-1) {
168             for my $k (grep {!/\A_/ && !/\./} keys %{$clsets->[$i]}) {
169             my $meta;
170             eval {
171 1134         3079 $meta = "Data::Sah::Type::$tn"->${\("clausemeta_$k")};
172 10514         46365 };
173             if ($@) {
174 10514         16329 for ($cd->{args}{on_unhandled_clause}) {
175 10514         25086 my $msg = "Unhandled clause for type $tn: $k ($@)";
176 9616   100     14306 next if $_ eq 'ignore';
  15183         63971  
  9616         20151  
177 10496         13399 next if $_ eq 'warn'; # don't produce multiple warnings
178 10496         14709 $self->_die($cd, $msg);
179 10496         18022 }
  10496         56798  
180             }
181 10496 100       23226 $meta //= {prio=>50};
182 31         79 push @clauses, [$i, $k, $meta];
183 31         4442 }
184 31 100       79 }
185 15 100       42  
186 14         57 my $res = [sort $sorter @clauses];
187             #$log->errorf("TMP: sorted clauses: %s", $res);
188             $res;
189 10482   100     19793 }
190 10482         31789  
191             my ($self, %args) = @_;
192             my $cd = $args{cd};
193             my $name = $args{name};
194 10500         27649  
195             my $th_map = $cd->{th_map};
196 10500         63848 return $th_map->{$name} if $th_map->{$name};
197              
198             if ($args{load} // 1) {
199             no warnings;
200 15186     15186 1 43110 $self->_die($cd, "Invalid syntax for type name '$name', please use ".
201 15186         24056 "letters/numbers/underscores only")
202 15186         20169 unless $name =~ $Data::Sah::type_re;
203             my $main = $self->main;
204 15186         20386 my $module = ref($self) . "::TH::$name";
205 15186 100       33144 if (!eval "require $module; 1") { ## no critic: BuiltinFunctions::ProhibitStringyEval
206             $self->_die($cd, "Can't load type handler $module".
207 15160 50 50     55188 ($@ ? ": $@" : ""));
208 24     24   182 }
  24         56  
  24         5224  
209 15160 50       103727 $self->add_compile_module($cd, $module, {category=>'type_handler'});
210              
211             my $obj = $module->new(compiler=>$self);
212 15160         47068 $th_map->{$name} = $obj;
213 15160         79591 }
214 15160 50       804492 return $th_map->{$name};
215 0 0       0 }
216              
217             my ($self, %args) = @_;
218 15160         77116 my $cd = $args{cd};
219             my $name = $args{name};
220 15160         76273  
221 15160         752317 my $fsh_table = $cd->{fsh_table};
222             return $fsh_table->{$name} if $fsh_table->{$name};
223 15160         51517  
224             if ($args{load} // 1) {
225             no warnings;
226             $self->_die($cd, "Invalid syntax for func set name '$name', ".
227 0     0 1 0 "please use letters/numbers/underscores")
228 0         0 unless $name =~ $Data::Sah::funcset_re;
229 0         0 my $module = ref($self) . "::FSH::$name";
230             if (!eval "require $module; 1") { ## no critic: BuiltinFunctions::ProhibitStringyEval
231 0         0 $self->_die($cd, "Can't load func set handler $module".
232 0 0       0 ($@ ? ": $@" : ""));
233             }
234 0 0 0     0  
235 24     24   160 my $obj = $module->new();
  24         36  
  24         71899  
236 0 0       0 $fsh_table->{$name} = $obj;
237             }
238             return $fsh_table->{$name};
239 0         0 }
240 0 0       0  
241 0 0       0 require Time::HiRes;
242              
243             my ($self, %args) = @_;
244              
245 0         0 my $cd = {};
246 0         0 $cd->{v} = 2;
247             $cd->{args} = \%args;
248 0         0 $cd->{compiler} = $self;
249             $cd->{compiler_name} = $self->name;
250              
251             if (my $ocd = $args{outer_cd}) {
252 10130     10130 0 45954 # for checking later, because outer_cd might be autovivified to hash
253             # later
254 10130         94432 $cd->{is_inner} = 1;
255              
256 10130         20142 $cd->{outer_cd} = $ocd;
257 10130         17724 $cd->{indent_level} = $ocd->{indent_level};
258 10130         18767 $cd->{th_map} = { %{ $ocd->{th_map} } };
259 10130         15978 $cd->{fsh_map} = { %{ $ocd->{fsh_map} } };
260 10130         25335 $cd->{default_lang} = $ocd->{default_lang};
261             $cd->{spath} = [@{ $ocd->{spath} }];
262 10130 100       22673 } else {
263             $cd->{indent_level} = $cd->{args}{indent_level} // 0;
264             $cd->{th_map} = {};
265 655         1395 $cd->{fsh_map} = {};
266             # we use || here because in some env, LANG/LANGUAGE is set to ''
267 655         1076 $cd->{default_lang} = $ENV{LANG} || "en_US";
268 655         1227 $cd->{default_lang} =~ s/\..+//; # en_US.UTF-8 -> en_US
269 655         866 $cd->{spath} = [];
  655         2234  
270 655         1039 }
  655         1300  
271 655         1408 $cd->{_id} = Time::HiRes::gettimeofday(); # compilation id
272 655         941 $cd->{ccls} = [];
  655         1525  
273              
274 9475   100     21912 $cd;
275 9475         15986 }
276 9475         17096  
277             my ($self, $args) = @_;
278 9475   50     35876  
279 9475         19532 return if $args->{_args_checked}++;
280 9475         17342  
281             $args->{data_name} //= 'data';
282 10130         32982 $args->{data_name} =~ /\A[A-Za-z_]\w*\z/ or $self->_die(
283 10130         20244 {}, "Invalid syntax in data_name '$args->{data_name}', ".
284             "please use letters/nums only");
285 10130         21967 $args->{allow_expr} //= 1;
286             $args->{on_unhandled_attr} //= 'die';
287             $args->{on_unhandled_clause} //= 'die';
288             $args->{skip_clause} //= [];
289 9800     9800 0 16539 $args->{mark_missing_translation} //= 1;
290             for ($args->{lang}) {
291 9800 100       26025 $_ //= $ENV{LANG} || $ENV{LANGUAGE} || "en_US";
292             s/\W.*//; # LANG=en_US.UTF-8, LANGUAGE=en_US:en
293 4746   50     23988 }
294 4746 50       19869 # locale, no default
295             }
296              
297 4746   50     18204 my ($self, $cd, $clset_num, $clause) = @_;
298 4746   100     22254  
299 4746   100     18239 my $th = $cd->{th};
300 4746   100     18793 my $tn = $cd->{type};
301 4746   50     18002 my $clsets = $cd->{clsets};
302 4746         10114  
303 4746   50     35726 my $clset = $clsets->[$clset_num];
      66        
304 4746         15093 local $cd->{spath} = [@{$cd->{spath}}, $clause];
305             local $cd->{clset} = $clset;
306             local $cd->{clset_num} = $clset_num;
307             local $cd->{uclset} = $cd->{uclsets}[$clset_num];
308             local $cd->{clset_dlang} = $cd->{_clset_dlangs}[$clset_num];
309             #$log->tracef("Processing clause %s", $clause);
310 10641     10641   18398  
311             delete $cd->{uclset}{$clause};
312 10641         16235 delete $cd->{uclset}{"$clause.prio"};
313 10641         16882  
314 10641         14127 if (grep { $_ eq $clause } @{ $cd->{args}{skip_clause} }) {
315             delete $cd->{uclset}{$_}
316 10641         15807 for grep {/^\Q$clause\E(\.|\z)/} keys(%{$cd->{uclset}});
317 10641         15121 return;
  10641         28923  
318 10641         19260 }
319 10641         23116  
320 10641         19457 my $meth = "clause_$clause";
321 10641         20713 my $mmeth = "clausemeta_$clause";
322             unless ($th->can($meth)) {
323             for ($cd->{args}{on_unhandled_clause}) {
324 10641         16818 next if $_ eq 'ignore';
325 10641         18865 do { warn "Can't handle clause $clause"; next }
326             if $_ eq 'warn';
327 10641 100       12970 $self->_die($cd, "Can't handle clause $clause");
  4         12  
  10641         32445  
328             }
329 2         3 }
  2         28  
  2         5  
330 2         9  
331             # put information about the clause to $cd
332              
333 10639         18020 my $meta;
334 10639         17092 if ($th->can($mmeth)) {
335 10639 100       35790 $meta = $th->$mmeth;
336 35         113 } else {
337 35 100       107 $meta = {};
338 10 100       37 }
  1         25  
  1         64  
339             local $cd->{cl_meta} = $meta;
340 9         55 $self->_die($cd, "Clause $clause doesn't allow expression")
341             if $clset->{"$clause.is_expr"} && !$meta->{allow_expr};
342             for my $a (keys %{ $meta->{attrs} }) {
343             my $av = $meta->{attrs}{$a};
344             $self->_die($cd, "Attribute $clause.$a doesn't allow ".
345             "expression")
346 10630         14987 if $clset->{"$clause.$a.is_expr"} && !$av->{allow_expr};
347 10630 100       31279 }
348 10604         32500 local $cd->{clause} = $clause;
349             my $cv = $clset->{$clause};
350 26         52 my $ie = $clset->{"$clause.is_expr"};
351             my $op = $clset->{"$clause.op"};
352 10630         20074  
353             # store original value before being coerced/normalized
354 10630 50 66     28478 local $cd->{cl_raw_value} = $cv;
355 10630         15090  
  10630         26432  
356 458         1003 # coerce clause value (with default coerce rules & x.perl.coerce_to). XXX it
357             # should be validate + coerce but for now we do coerce to reduce compilation
358             # overhead.
359 458 50 33     1444 {
360             last if $ie;
361 10630         20103 my $coerce_type = $meta->{schema}[0] or last;
362 10630         16842 my $value_is_array;
363 10630         16635 if ($coerce_type eq '_same') {
364 10630         16950 $coerce_type = $cd->{type};
365             } elsif ($coerce_type eq '_same_elem') {
366             $coerce_type = $cd->{nschema}[1]{of} //
367 10630         17533 $cd->{nschema}[1]{each_elem} // 'any';
368             } elsif ($clause eq 'between' || $clause eq 'xbetween') { # XXX special cased for now
369             $coerce_type = $cd->{type};
370             $value_is_array = 1;
371             }
372             my $coercer = $coercer_cache{$coerce_type};
373 10630 100       13704 if (!$coercer) {
  10630         17078  
374 10622 100       24776 require Data::Sah::Coerce;
375 10596         13821 $coercer = Data::Sah::Coerce::gen_coercer(
376 10596 100 100     38906 type => $coerce_type,
    100          
    100          
377 2719         5182 return_type=>'status+err+val',
378             (coerce_to => $cd->{coerce_to}) x !!$cd->{coerce_to},
379             );
380 122   66     621 $coercer_cache{$coerce_type} = $coercer;
      50        
381             }
382 1386         2288 my ($cstatus, $cerr);
383 1386         1933 if ($op && ($op eq 'or' || $op eq 'and')) {
384             for my $cv2 (@$cv) {
385 10596         23802 if ($value_is_array) {
386 10596 100       18690 $cv2 = [@$cv2]; # shallow copy
387 52         9102 for (@$cv2) {
388             ($cstatus, $cerr, $_) = @{ $coercer->($_) };
389             if ($cerr) {
390             $self->_die($cd, "Can't coerce clause value $_: $cerr");
391             }
392 52         43071 }
393 52         10962 } else {
394             ($cstatus, $cerr, $cv) = @{ $coercer->($cv) };
395 10596         16202 if ($cerr) {
396 10596 100 100     34450 $self->_die($cd, "Can't coerce clause value $cv: $cerr");
      100        
397 2966         5915 }
398 4770 100       7987 }
399 1152         2422 }
400 1152         1875 } else {
401 2304         2516 if ($value_is_array) {
  2304         34797  
402 2304 50       15251 $cv = [@$cv]; # shallow copy
403 0         0 for (@$cv) {
404             my $cf;
405             ($cstatus, $cerr, $_) = @{ $coercer->($_) };
406             if ($cerr) {
407 3618         4133 $self->_die($cd, "Can't coerce clause value $_: $cerr");
  3618         63788  
408 3618 50       24051 }
409 0         0 }
410             } else {
411             ($cstatus, $cerr, $cv) = @{ $coercer->($cv) };
412             if ($cerr) {
413             $self->_die($cd, "Can't coerce clause value $cv: $cerr");
414 7630 100       12822 }
415 660         1481 }
416 660         1352 }
417 1248         1527 #$log->tracef("Coerced clause value %s to %s (type=%s)",
418 1248         1684 # $cd->{cl_raw_value}, $cv, $coerce_type);
  1248         21556  
419 1248 50       9414 }
420 0         0  
421             local $cd->{cl_value} = $cv;
422             local $cd->{cl_term} = $ie ? $self->expr($cd, $cv) : $self->literal($cv);
423             local $cd->{cl_is_expr} = $ie;
424 6970         8720 local $cd->{cl_op} = $op;
  6970         144645  
425 6970 50       53329 delete $cd->{uclset}{"$clause.is_expr"};
426 0         0 delete $cd->{uclset}{"$clause.op"};
427              
428             if ($self->can("before_clause")) {
429             $self->before_clause($cd);
430             }
431             if ($th->can("before_clause")) {
432             $th->before_clause($cd);
433             }
434 10630         30681 my $tmpnam = "before_clause_$clause";
435 10630 100       32066 if ($th->can($tmpnam)) {
436 10630         745778 $th->$tmpnam($cd);
437 10630         19540 }
438 10630         20381  
439 10630         20623 my $is_multi;
440             if (defined($op) && !$ie) {
441 10630 50       37267 if ($op =~ /\A(and|or|none)\z/) {
442 10630         26311 $is_multi = 1;
443             } elsif ($op eq 'not') {
444 10630 100       35483 $is_multi = 0;
445 3051         10893 } else {
446             $self->_die($cd, "Invalid value for $clause.op, ".
447 10630         19457 "must be one of and/or/not/none");
448 10630 100       32776 }
449 1025         3480 }
450             $self->_die($cd, "'$clause.op' attribute set to $op, ".
451             "but value of '$clause' clause not an array")
452 10630         15481 if $is_multi && ref($cv) ne 'ARRAY';
453 10630 100 66     28138 if (!$th->can($meth)) {
454 4349 100       18412 # skip
    50          
455 3686         5566 } elsif ($cd->{CLAUSE_DO_MULTI} || !$is_multi) {
456             local $cd->{cl_is_multi} = 1 if $is_multi;
457 663         960 $th->$meth($cd);
458             } else {
459 0         0 my $i = 0;
460             for my $cv2 (@$cv) {
461             local $cd->{spath} = [@{ $cd->{spath} }, $i];
462             local $cd->{cl_value} = $cv2;
463 10630 50 66     29418 local $cd->{cl_term} = $self->literal($cv2);
464             local $cd->{_debug_ccl_note} = "" if $i;
465             $i++;
466 10630 100 100     49724 $th->$meth($cd);
    100          
467             }
468             }
469 8305 100       16510  
470 8305         27964 $tmpnam = "after_clause_$clause";
471             if ($th->can($tmpnam)) {
472 2299         3780 $th->$tmpnam($cd);
473 2299         4279 }
474 3686         5559 if ($th->can("after_clause")) {
  3686         10274  
475 3686         7359 $th->after_clause($cd);
476 3686         8183 }
477 3686 100       184599 if ($self->can("after_clause")) {
478 3686         4935 $self->after_clause($cd);
479 3686         11872 }
480              
481             delete $cd->{uclset}{"$clause.err_msg"};
482             delete $cd->{uclset}{"$clause.err_level"};
483 10597         20015 delete $cd->{uclset}{$_} for
484 10597 100       42101 grep {/\A\Q$clause\E\.human(\..+)?\z/} keys(%{$cd->{uclset}});
485 56         254 }
486              
487 10597 50       33067 my ($self, $cd, $which) = @_;
488 0         0  
489             # $which can be left undef/false if called from compile(), or set to 'from
490 10597 50       28450 # clause_clset' if called from within clause_clset(), in which case
491 10597         24540 # before_handle_type, handle_type, before_all_clauses, and after_all_clauses
492             # won't be called.
493              
494 10597         23454 my $th = $cd->{th};
495 10597         16946 my $tn = $cd->{type};
496 10597         13467 my $clsets = $cd->{clsets};
497 1222         21082  
  10597         77614  
498             my $cname = $self->name;
499             local $cd->{uclsets} = [];
500             $cd->{_clset_dlangs} = []; # default lang for each clset
501 10514     10514   19142 for my $clset (@$clsets) {
502             for (keys %$clset) {
503             if (!$cd->{args}{allow_expr} && /\.is_expr\z/ && $clset->{$_}) {
504             $self->_die($cd, "Expression not allowed: $_");
505             }
506             }
507             $cd->{coerce_to} //= $clset->{'x.perl.coerce_to'} if $clset->{'x.perl.coerce_to'};
508 10514         16137 push @{ $cd->{uclsets} }, {
509 10514         15277 map {$_=>$clset->{$_}}
510 10514         13362 grep {
511             !/\A_|\._|\Ax\./ && (!/\Ac\./ || /\Ac\.\Q$cname\E\./)
512 10514         23524 } keys %$clset
513 10514         24227 };
514 10514         21955 my $dl = $clset->{default_lang} //
515 10514         21613 ($cd->{outer_cd} ? $cd->{outer_cd}{clset_dlang} : undef) //
516 9616         21170 "en_US";
517 15183 0 33     37403 push @{ $cd->{_clset_dlangs} }, $dl;
      33        
518 0         0 }
519              
520             my $clauses = $self->_get_clauses_from_clsets($cd, $clsets);
521 9616 100 33     19843 $cd->{has_constraint_clause} = 0;
522 9616         22576 $cd->{has_subschema} = 0;
523 15015         43825 #$cd->{inspect_elem} = 0; # currently not needed
524             for my $cl (@$clauses) {
525 9616 100 66     12034 # 0=clset_num, 1=cl name, 2=cl meta
  15183         103571  
526             next if $cl->[1] =~ /\A(req|forbidden)\z/;
527             $cd->{has_subschema} = 1 if $cl->[2]{subschema};
528             #$cd->{inspect_elem} = 1 if $cl->[2]{inspect_elem};
529 9616 100 100     51120 if ($cl->[2]{tags} && grep {$_ eq 'constraint'} @{ $cl->[2]{tags} }) {
      100        
530             $cd->{has_constraint_clause} = 1;
531 9616         13994 }
  9616         22975  
532             }
533              
534 10514         27796 if ($which) {
535 10500         18151 # {before,after}_clause_sets is currently internal/undocumented, created
536 10500         15572 # only for clause_clset
537             if ($self->can("before_clause_sets")) {
538 10500         18309 $self->before_clause_sets($cd);
539             }
540 10482 100       30378 if ($th->can("before_clause_sets")) {
541 9390 100       19979 $th->before_clause_sets($cd);
542             }
543 9390 100 100     22015 } else {
  9751         37076  
  9373         23825  
544 8803         16850 if ($self->can("before_handle_type")) {
545             $self->before_handle_type($cd);
546             }
547              
548 10500 100       20724 $th->handle_type($cd);
549              
550             if ($self->can("before_all_clauses")) {
551 371 50       1246 $self->before_all_clauses($cd);
552 0         0 }
553             if ($th->can("before_all_clauses")) {
554 371 50       1148 $th->before_all_clauses($cd);
555 0         0 }
556             }
557              
558 10129 50       36408 for my $clause0 (@$clauses) {
559 10129         25707 my ($clset_num, $clause) = @$clause0;
560             $self->_process_clause($cd, $clset_num, $clause);
561             } # for clause
562 10126         45263  
563             for my $uclset (@{ $cd->{uclsets} }) {
564 10126 100       39937 if (keys %$uclset) {
565 5056         14413 for ($cd->{args}{on_unhandled_attr}) {
566             my $msg = "Unhandled attribute(s) for type $tn: ".
567 10126 100       47912 join(", ", keys %$uclset);
568 521         1830 next if $_ eq 'ignore';
569             do { warn $msg; next } if $_ eq 'warn';
570             $self->_die($cd, $msg);
571             }
572 10497         21572 }
573 10479         20162 }
574 10479         24332  
575             if ($which) {
576             # {before,after}_clause_sets is currently internal/undocumented, created
577 10464         16070 # only for clause_clset
  10464         22074  
578 9566 100       20854 if ($th->can("after_clause_sets")) {
579 26         69 $th->after_clause_sets($cd);
580 26         102 }
581             if ($self->can("after_clause_sets")) {
582 26 100       84 $self->after_clause_sets($cd);
583 7 100       23 }
  1         13  
  1         53  
584 6         25 } else {
585             if ($th->can("after_all_clauses")) {
586             $th->after_all_clauses($cd);
587             }
588             if ($self->can("after_all_clauses")) {
589 10458 100       19769 $self->after_all_clauses($cd);
590             }
591             }
592 366 50       1322 }
593 0         0  
594             my ($self, %args) = @_;
595 366 100       1526  
596 174         489 # XXX schema
597             $self->check_compile_args(\%args);
598              
599 10092 100       35536 my $main = $self->main;
600 517         1916 my $cd = $self->init_cd(%args);
601              
602 10092 50       27577 if ($self->can("before_compile")) {
603 10092         24424 $self->before_compile($cd);
604             }
605              
606             # normalize schema
607             my $schema0 = $args{schema} or $self->_die($cd, "No schema");
608             my $nschema;
609 10130     10130 1 71330 if ($args{schema_is_normalized}) {
610             $nschema = $schema0;
611             #$log->tracef("schema already normalized, skipped normalization");
612 10130         35290 } else {
613             $nschema = $main->normalize_schema($schema0);
614 10130         27733 #$log->tracef("normalized schema=%s", $nschema);
615 10130         74092 }
616             $cd->{nschema} = $nschema;
617 10130 50       47559 local $cd->{schema} = $nschema;
618 10130         24491  
619             if ($self->can("before_resolve")) {
620             my $res = $self->before_resolve($cd);
621             return $cd if ($res//0) == 99;
622 10130 50       23187 }
623 10130         14895  
624 10130 100       20304 require Data::Sah::Resolve;
625 4889         8084 my $res = Data::Sah::Resolve::resolve_schema(
626             {
627             schema_is_normalized => 1,
628 5241         15746 allow_base_with_no_additional_clauses => 1,
629             %{$args{resolve_opts} // {}},
630             },
631 10130         408399 $nschema);
632 10130         25431 my $tn = $res->{type};
633             $cd->{th} = $self->get_th(name=>$tn, cd=>$cd);
634 10130 100       36026 $cd->{type} = $tn;
635 5060         15628 if ($nschema->[0] ne $tn) {
636 5060 50 100     20122 $self->add_compile_module($cd, "Sah::Schema::$nschema->[0]");
637             }
638             if ($args{cache} && $res->{base} && $res->{base} ne $res->{type}) {
639 10130         47318 $cd->{base_schema} = $res->{base};
640             $cd->{clsets} = $res->{"clsets_after_base"};
641             } else {
642             delete $cd->{base_schema};
643             $cd->{clsets} = $res->{"clsets_after_type.alt.merge.merged"};
644 10130   50     45721 }
  10130         60997  
645              
646             $self->_process_clsets($cd);
647 10130         716396  
648 10130         25630 if ($self->can("after_compile")) {
649 10130         18026 $self->after_compile($cd);
650 10130 50       24795 }
651 0         0  
652             if ($args{log_result}) {# && $log->is_trace) {
653 10130 50 33     29184 log_trace(
      0        
654 0         0 "Schema compilation result (compiler=%s):\n%s",
655 0         0 ref($self),
656             !ref($cd->{result}) && ($ENV{LINENUM} // 1) ?
657 10130         15464 __linenum($cd->{result}) :
658 10130         17205 $cd->{result}
659             );
660             }
661 10130         29232 return $cd;
662             }
663 10092 100       39970  
664 5067         14277 my ($self, $cd) = @_;
665             my $cl = $cd->{clause};
666             delete $cd->{uclset}{$cl};
667 10092 50       24743 }
668              
669             my ($self, $cd) = @_;
670             my $cl = $cd->{clause};
671             delete $cd->{uclset}{$cl};
672             delete $cd->{uclset}{$_} for grep {/\A\Q$cl\E\./} keys %{$cd->{uclset}};
673             }
674 0 0 0     0  
675             my ($self, $cd, $note) = @_;
676 10092         110872  
677             $self->_die($cd, "Clause '$cd->{clause}' for type '$cd->{type}' ".
678             ($note ? "($note) " : "") .
679             "is currently unimplemented");
680 189     189   908 }
681 189         280  
682 189         374 my ($self, $cd, $name, $extra_keys, $allow_duplicate) = @_;
683              
684             my $found;
685             for (@{ $cd->{modules} }) {
686 81     81   394 if ($_->{name} eq $name && $_->{phase} eq $extra_keys->{phase}) {
687 81         130 $found++;
688 81         141 last;
689 81         116 }
  0         0  
  81         309  
690             }
691             return if $found && !$allow_duplicate;
692             push @{ $cd->{modules} }, {
693 0     0   0 name => $name,
694             %{ $extra_keys // {} },
695 0 0       0 };
696             }
697              
698             my ($self, $cd, $name, $extra_keys, $allow_duplicate) = @_;
699              
700             if ($extra_keys) {
701 24213     24213 0 41806 $extra_keys = { %$extra_keys, phase => 'runtime' };
702             } else {
703 24213         33175 $extra_keys = { phase => 'runtime' };
704 24213         28415 }
  24213         60452  
705 17362 100 66     42576 $self->add_module($cd, $name, $extra_keys, $allow_duplicate);
706 468         792 }
707 468         715  
708             my ($self, $cd, $name, $extra_keys, $allow_duplicate) = @_;
709              
710 24213 100 66     59297 if ($extra_keys) {
711 23745         36704 $extra_keys = { %$extra_keys, phase => 'compile' };
712             } else {
713 23745   50     26504 $extra_keys = { phase => 'compile' };
  23745         109207  
714             }
715             $self->add_module($cd, $name, $extra_keys, $allow_duplicate);
716             }
717              
718 7653     7653 0 15448 1;
719             # ABSTRACT: Base class for Sah compilers (Data::Sah::Compiler::*)
720 7653 100       14556  
721 4858         16417  
722             =pod
723 2795         6549  
724             =encoding UTF-8
725 7653         22925  
726             =head1 NAME
727              
728             Data::Sah::Compiler - Base class for Sah compilers (Data::Sah::Compiler::*)
729 16560     16560 0 34607  
730             =head1 VERSION
731 16560 50       30827  
732 16560         55839 This document describes version 0.914 of Data::Sah::Compiler (from Perl distribution Data-Sah), released on 2022-10-19.
733              
734 0         0 =for Pod::Coverage ^(check_compile_args|def|expr|init_cd|literal|name|add_module|add_compile_module|add_runtime_module)$
735              
736 16560         44227 =head1 COMPILATION DATA KEYS
737              
738             =over
739              
740             =item * v => int
741              
742             Version of compilation data structure. Currently at 2. Whenever there's a
743             backward-incompatible change introduced in the structure, this version number
744             will be bumped. Client code can check this key to deliberately fail when it
745             encounters version number that it can't handle.
746              
747             =item * args => HASH
748              
749             Arguments given to C<compile()>.
750              
751             =item * compiler => OBJ
752              
753             The compiler object.
754              
755             =item * compiler_name => str
756              
757             Compiler name, e.g. C<perl>, C<js>.
758              
759             =item * is_inner => bool
760              
761             Convenience. Will be set to 1 when this compilation is a subcompilation (i.e.
762             compilation of a subschema). You can also check for C<outer_cd> to find out if
763             this compilation is an inner compilation.
764              
765             =item * outer_cd => HASH
766              
767             If compilation is called from within another C<compile()>, this will be set to
768             the outer compilation's C<$cd>. The inner compilation will inherit some values
769             from the outer, like list of types (C<th_map>) and function sets (C<fsh_map>).
770              
771             =item * th_map => HASH
772              
773             Mapping of fully-qualified type names like C<int> and its
774             C<Data::Sah::Compiler::*::TH::*> type handler object (or array, a normalized
775             schema).
776              
777             =item * fsh_map => HASH
778              
779             Mapping of function set name like C<core> and its
780             C<Data::Sah::Compiler::*::FSH::*> handler object.
781              
782             =item * schema => ARRAY
783              
784             The current schema (normalized) being processed. Since schema can contain other
785             schemas, there will be subcompilation and this value will not necessarily equal
786             to C<< $cd->{args}{schema} >>.
787              
788             =item * spath = ARRAY
789              
790             An array of strings, with empty array (C<[]>) as the root. Point to current
791             location in schema during compilation. Inner compilation will continue/append
792             the path.
793              
794             Example:
795              
796             # spath, with pointer to location in the schema
797              
798             spath: ["elems"] ----
799             \
800             schema: ["array", {elems => ["float", [int => {min=>3}], [int => "div_by&" => [2, 3]]]}
801              
802             spath: ["elems", 0] ------------
803             \
804             schema: ["array", {elems => ["float", [int => {min=>3}], [int => "div_by&" => [2, 3]]]}
805              
806             spath: ["elems", 1, "min"] ---------------------
807             \
808             schema: ["array", {elems => ["float", [int => {min=>3}], [int => "div_by&" => [2, 3]]]}
809              
810             spath: ["elems", 2, "div_by", 1] -------------------------------------------------
811             \
812             schema: ["array", {elems => ["float", [int => {min=>3}], [int => "div_by&" => [2, 3]]]}
813              
814             Note: aside from C<spath>, there is also the analogous C<dpath> which points to
815             the location of I<data> (e.g. array element, hash key). But this is declared and
816             maintained by the generated code, not by the compiler.
817              
818             =item * th => OBJ
819              
820             Current type handler.
821              
822             =item * type => STR
823              
824             Current type name.
825              
826             =item * clsets => ARRAY
827              
828             All the clause sets. Each schema might have more than one clause set, due to
829             processing base type's clause set.
830              
831             =item * clset => HASH
832              
833             Current clause set being processed. Note that clauses are evaluated not strictly
834             in clset order, but instead based on expression dependencies and priority.
835              
836             =item * clset_dlang => HASH
837              
838             Default language of the current clause set. This value is taken from C<<
839             $cd->{clset}{default_lang} >> or C<< $cd->{outer_cd}{default_lang} >> or the
840             default C<en_US>.
841              
842             =item * clset_num => INT
843              
844             Set to 0 for the first clause set, 1 for the second, and so on. Due to merging,
845             we might process more than one clause set during compilation.
846              
847             =item * uclset => HASH
848              
849             Short for "unprocessed clause set", a shallow copy of C<clset>, keys will be
850             removed from here as they are processed by clause handlers, remaining keys after
851             processing the clause set means they are not recognized by hooks and thus
852             constitutes an error.
853              
854             =item * uclsets => ARRAY
855              
856             All the C<uclset> for each clause set.
857              
858             =item * clause => STR
859              
860             Current clause name.
861              
862             =item * cl_meta => HASH
863              
864             Metadata information about the clause, from the clause definition. This include
865             C<prio> (priority), C<attrs> (list of attributes specific for this clause),
866             C<allow_expr> (whether clause allows expression in its value), etc. See
867             C<Data::Sah::Type::$TYPENAME> for more information.
868              
869             =item * cl_value => ANY
870              
871             Clause value. Note: for putting in generated code, use C<cl_term>.
872              
873             The clause value will be coerced if there are applicable coercion rules. To get
874             the raw/original value as the schema specifies it, see C<cl_raw_value>.
875              
876             =item * cl_raw_value => any
877              
878             Like C<cl_value>, but without any coercion/filtering done to the value.
879              
880             =item * cl_term => STR
881              
882             Clause value term. If clause value is a literal (C<.is_expr> is false) then it
883             is produced by passing clause value to C<literal()>. Otherwise, it is produced
884             by passing clause value to C<expr()>.
885              
886             =item * cl_is_expr => BOOL
887              
888             A copy of C<< $cd->{clset}{"${clause}.is_expr"} >>, for convenience.
889              
890             =item * cl_op => STR
891              
892             A copy of C<< $cd->{clset}{"${clause}.op"} >>, for convenience.
893              
894             =item * cl_is_multi => BOOL
895              
896             Set to true if cl_value contains multiple clause values. This will happen if
897             C<.op> is either C<and>, C<or>, or C<none> and C<< $cd->{CLAUSE_DO_MULTI} >> is
898             set to true.
899              
900             =item * indent_level => INT
901              
902             Current level of indent when printing result using C<< $c->line() >>. 0 means
903             unindented.
904              
905             =item * all_expr_vars => ARRAY
906              
907             All variables in all expressions in the current schema (and all of its
908             subschemas). Used internally by compiler. For example (XXX syntax not not
909             finalized):
910              
911             # schema
912             [array => {of=>'str1', min_len=>1, 'max_len=' => '$min_len*3'},
913             {def => {
914             str1 => [str => {min_len=>6, 'max_len=' => '$min_len*2',
915             check=>'substr($_,0,1) eq "a"'}],
916             }}]
917              
918             all_expr_vars => ['schema:///clsets/0/min_len', # or perhaps .../min_len/value
919             'schema://str1/clsets/0/min_len']
920              
921             This data can be used to order the compilation of clauses based on dependencies.
922             In the above example, C<min_len> needs to be evaluated before C<max_len>
923             (especially if C<min_len> is an expression).
924              
925             =item * modules => array of hash
926              
927             List of modules that are required, one way or another. Each element is a hash
928             which must contain at least the C<name> key (module name). There are other keys
929             like C<version> (minimum version), C<phase> (explained below). Some languages
930             might add other keys, like C<perl> with C<use_statement> (statement to load/use
931             the module, used by e.g. pragmas like C<no warnings 'void'> which are not the
932             regular C<require MODULE> statement). Generally, duplicate entries (entries with
933             the same C<name> and C<phase>) are avoided, except in special cases like Perl
934             pragmas.
935              
936             There are I<runtime> modules (C<phase> key set to C<runtime>), which are
937             required by the generated code when running. For each entry, the only required
938             key is C<name>. Other keys include: C<version> (minimum version). Some languages
939             have some additional rule for this, e.g. perl has C<use_statement> (how to use
940             the module, e.g. for pragma, like C<no warnings 'void'>).
941              
942             There are also I<compile-time> modules (C<phase> key set to C<compile>), which
943             are required during compilation of schema. This include coercion rule modules
944             like L<Data::Sah::Coerce::perl::To_date::From_float::Epoch>, and so on. This
945             information might be useful for distributions that use Data::Sah. Because
946             Data::Sah is a modular library, where there are third party extensions for
947             types, coercion rules, and so on, listing these modules as dependencies instead
948             of a single C<Data::Sah> will ensure that dependants will pull the right
949             distribution during installation.
950              
951             =item * ccls => [HASH, ...]
952              
953             (Result) Compiled clauses, collected during processing of schema's clauses. Each
954             element will contain the compiled code in the target language, error message,
955             and other information. At the end of processing, these will be joined together.
956              
957             =item * result => ...
958              
959             (Result) The final result. For most compilers, it will be string/text.
960              
961             =item * has_constraint_clause => bool
962              
963             Convenience. True if there is at least one constraint clause in the schema. This
964             I<excludes> special clause C<req> and C<forbidden>.
965              
966             =item * has_subschema => bool
967              
968             Convenience. True if there is at least one clause which contains a subschema.
969              
970             =back
971              
972             =head1 ATTRIBUTES
973              
974             =head2 main => OBJ
975              
976             Reference to the main Data::Sah object.
977              
978             =head2 expr_compiler => OBJ
979              
980             Reference to expression compiler object. In the perl compiler, for example, this
981             will be an instance of L<Language::Expr::Compiler::Perl> object.
982              
983             =head1 METHODS
984              
985             =head2 new() => OBJ
986              
987             =head2 $c->compile(%args) => HASH
988              
989             Compile schema into target language.
990              
991             Arguments (C<*> denotes required arguments, subclass may introduce others):
992              
993             =over 4
994              
995             =item * data_name => STR (default: 'data')
996              
997             A unique name. Will be used as default for variable names, etc. Should only be
998             comprised of letters/numbers/underscores.
999              
1000             =item * schema* => STR|ARRAY
1001              
1002             The schema to use. Will be normalized by compiler, unless
1003             C<schema_is_normalized> is set to true.
1004              
1005             =item * lang => STR (default: from LANG/LANGUAGE or C<en_US>)
1006              
1007             Desired output human language. Defaults (and falls back to) C<en_US>.
1008              
1009             =item * mark_missing_translation => BOOL (default: 1)
1010              
1011             If a piece of text is not found in desired human language, C<en_US> version of
1012             the text will be used but using this format:
1013              
1014             (en_US:the text to be translated)
1015              
1016             If you do not want this marker, set the C<mark_missing_translation> option to 0.
1017              
1018             =item * locale => STR
1019              
1020             Locale name, to be set during generating human text description. This sometimes
1021             needs to be if setlocale() fails to set locale using only C<lang>.
1022              
1023             =item * schema_is_normalized => BOOL (default: 0)
1024              
1025             If set to true, instruct the compiler not to normalize the input schema and
1026             assume it is already normalized.
1027              
1028             =item * allow_expr => BOOL (default: 1)
1029              
1030             Whether to allow expressions. If false, will die when encountering expression
1031             during compilation. Usually set to false for security reason, to disallow
1032             complex expressions when schemas come from untrusted sources.
1033              
1034             =item * on_unhandled_attr => STR (default: 'die')
1035              
1036             What to do when an attribute can't be handled by compiler (either it is an
1037             invalid attribute, or the compiler has not implemented it yet). Valid values
1038             include: C<die>, C<warn>, C<ignore>.
1039              
1040             =item * on_unhandled_clause => STR (default: 'die')
1041              
1042             What to do when a clause can't be handled by compiler (either it is an invalid
1043             clause, or the compiler has not implemented it yet). Valid values include:
1044             C<die>, C<warn>, C<ignore>.
1045              
1046             =item * indent_level => INT (default: 0)
1047              
1048             Start at a specified indent level. Useful when generated code will be inserted
1049             into another code (e.g. inside C<sub {}> where it is nice to be able to indent
1050             the inside code).
1051              
1052             =item * skip_clause => ARRAY (default: [])
1053              
1054             List of clauses to skip (to assume as if it did not exist). Example when
1055             compiling with the human compiler:
1056              
1057             # schema
1058             [int => {default=>1, between=>[1, 10]}]
1059              
1060             # generated human description in English
1061             integer, between 1 and 10, default 1
1062              
1063             # generated human description, with skip_clause => ['default']
1064             integer, between 1 and 10
1065              
1066             =back
1067              
1068             =head3 Compilation data
1069              
1070             During compilation, compile() will call various hooks (listed below). The hooks
1071             will be passed compilation data (C<$cd>) which is a hashref containing various
1072             compilation state and result. Compilation data is written to this hashref
1073             instead of on the object's attributes to make it easy to do recursive
1074             compilation (compilation of subschemas).
1075              
1076             Keys that are put into this compilation data include input data, compilation
1077             state, and others. Many of these keys might exist only temporarily during
1078             certain phases of compilation and will no longer exist at the end of
1079             compilation, for example C<clause> will only exist during processing of a clause
1080             and will be seen by hooks like C<before_clause> and C<after_clause>, it will not
1081             be seen by C<before_all_clauses> or C<after_compile>.
1082              
1083             For a list of keys, see L</"COMPILATION DATA KEYS">. Subclasses may add more
1084             data; see their respective documentation.
1085              
1086             =head3 Return value
1087              
1088             The compilation data will be returned as return value. Main result will be in
1089             the C<result> key. There is also C<ccls>, and subclasses may put additional
1090             results in other keys. Final usable result might need to be pieced together from
1091             these results, depending on your needs.
1092              
1093             =head3 Hooks
1094              
1095             By default this base compiler does not define any hooks; subclasses can define
1096             hooks to implement their compilation process. Each hook will be passed
1097             compilation data, and should modify or set the compilation data as needed. The
1098             hooks that compile() will call at various points, in calling order, are:
1099              
1100             =over 4
1101              
1102             =item * $c->before_compile($cd)
1103              
1104             Called once at the beginning of compilation.
1105              
1106             =item * $c->before_handle_type($cd)
1107              
1108             =item * $th->handle_type($cd)
1109              
1110             =item * $c->before_all_clauses($cd)
1111              
1112             Called before calling handler for any clauses.
1113              
1114             =item * $th->before_all_clauses($cd)
1115              
1116             Called before calling handler for any clauses, after compiler's
1117             before_all_clauses().
1118              
1119             =item * $c->before_clause($cd)
1120              
1121             Called for each clause, before calling the actual clause handler
1122             ($th->clause_NAME() or $th->clause).
1123              
1124             =item * $th->before_clause($cd)
1125              
1126             After compiler's before_clause() is called, I<type handler>'s before_clause()
1127             will also be called if available.
1128              
1129             Input and output interpretation is the same as compiler's before_clause().
1130              
1131             =item * $th->before_clause_NAME($cd)
1132              
1133             Can be used to customize clause.
1134              
1135             Introduced in v0.10.
1136              
1137             =item * $th->clause_NAME($cd)
1138              
1139             Clause handler. Will be called only once (if C<$cd->{CLAUSE_DO_MULTI}> is set to
1140             by other hooks before this) or once for each value in a multi-value clause (e.g.
1141             when C<.op> attribute is set to C<and> or C<or>). For example, in this schema:
1142              
1143             [int => {"div_by&" => [2, 3, 5]}]
1144              
1145             C<clause_div_by()> can be called only once with C<< $cd->{cl_value} >> set to
1146             [2, 3, 5] or three times, each with C<< $cd->{value} >> set to 2, 3, and 5
1147             respectively.
1148              
1149             =item * $th->after_clause_NAME($cd)
1150              
1151             Can be used to customize clause.
1152              
1153             Introduced in v0.10.
1154              
1155             =item * $th->after_clause($cd)
1156              
1157             Called for each clause, after calling the actual clause handler
1158             ($th->clause_NAME()).
1159              
1160             =item * $c->after_clause($cd)
1161              
1162             Called for each clause, after calling the actual clause handler
1163             ($th->clause_NAME()).
1164              
1165             Output interpretation is the same as $th->after_clause().
1166              
1167             =item * $th->after_all_clauses($cd)
1168              
1169             Called after all clauses have been compiled, before compiler's
1170             after_all_clauses().
1171              
1172             =item * $c->after_all_clauses($cd)
1173              
1174             Called after all clauses have been compiled.
1175              
1176             =item * $c->after_compile($cd)
1177              
1178             Called at the very end before compiling process end.
1179              
1180             =back
1181              
1182             =head2 $c->get_th
1183              
1184             =head2 $c->get_fsh
1185              
1186             =head1 HOMEPAGE
1187              
1188             Please visit the project's homepage at L<https://metacpan.org/release/Data-Sah>.
1189              
1190             =head1 SOURCE
1191              
1192             Source repository is at L<https://github.com/perlancar/perl-Data-Sah>.
1193              
1194             =head1 AUTHOR
1195              
1196             perlancar <perlancar@cpan.org>
1197              
1198             =head1 CONTRIBUTING
1199              
1200              
1201             To contribute, you can send patches by email/via RT, or send pull requests on
1202             GitHub.
1203              
1204             Most of the time, you don't need to build the distribution yourself. You can
1205             simply modify the code, then test via:
1206              
1207             % prove -l
1208              
1209             If you want to build the distribution (e.g. to try to install it locally on your
1210             system), you can install L<Dist::Zilla>,
1211             L<Dist::Zilla::PluginBundle::Author::PERLANCAR>,
1212             L<Pod::Weaver::PluginBundle::Author::PERLANCAR>, and sometimes one or two other
1213             Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond
1214             that are considered a bug and can be reported to me.
1215              
1216             =head1 COPYRIGHT AND LICENSE
1217              
1218             This software is copyright (c) 2022, 2021, 2020, 2019, 2018, 2017, 2016, 2015, 2014, 2013, 2012 by perlancar <perlancar@cpan.org>.
1219              
1220             This is free software; you can redistribute it and/or modify it under
1221             the same terms as the Perl 5 programming language system itself.
1222              
1223             =head1 BUGS
1224              
1225             Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Data-Sah>
1226              
1227             When submitting a bug or request, please include a test-file or a
1228             patch to an existing test-file that illustrates the bug or desired
1229             feature.
1230              
1231             =cut