001package Torello.Browser.JavaScriptAPI;
002
003import java.util.*;
004import javax.json.*;
005import javax.json.stream.*;
006import java.io.*;
007
008import java.lang.reflect.Method;
009import java.lang.reflect.Parameter;
010import java.util.function.Function;
011
012import Torello.Browser.BrowserEvent;
013import Torello.Browser.BrowserAPI.*;
014import Torello.Browser.helper.*;
015
016import Torello.Java.Additional.*;
017import Torello.Java.JSON.*;
018
019import static Torello.Java.JSON.JFlag.*;
020
021import Torello.Java.StrCmpr;
022import Torello.JavaDoc.StaticFunctional;
023import Torello.JavaDoc.JDHeaderBackgroundImg;
024import Torello.JavaDoc.Excuse;
025
026/**
027 * <SPAN CLASS=COPIEDJDK><B><CODE>[No Description Provided by Google]</CODE></B></SPAN>
028 * 
029 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
030 */
031@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
032@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
033public class Profiler
034{
035    // ********************************************************************************************
036    // ********************************************************************************************
037    // Class Header Stuff
038    // ********************************************************************************************
039    // ********************************************************************************************
040
041
042    // No Pubic Constructors
043    private Profiler () { }
044
045    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
046    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
047    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
048    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
049
050    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
051    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
052    // offically, two empty-vectors.  One for String's, and the other for Classes.
053
054    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
055    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
056
057    static
058    {
059        for (Method m : Profiler.class.getMethods())
060        {
061            // This doesn't work!  The parameter names are all "arg0" ... "argN"
062            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
063            //
064            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
065
066            Vector<Class<?>> parameterTypesList = new Vector<>();
067        
068            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
069
070            parameterTypes.put(
071                m.getName(),
072                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
073            );
074        }
075    }
076
077    static
078    {
079        Vector<String> v = null;
080
081        parameterNames.put("disable", EMPTY_VEC_STR);
082
083        parameterNames.put("enable", EMPTY_VEC_STR);
084
085        parameterNames.put("getBestEffortCoverage", EMPTY_VEC_STR);
086
087        v = new Vector<String>(1);
088        parameterNames.put("setSamplingInterval", v);
089        Collections.addAll(v, new String[]
090        { "interval", });
091
092        parameterNames.put("start", EMPTY_VEC_STR);
093
094        v = new Vector<String>(3);
095        parameterNames.put("startPreciseCoverage", v);
096        Collections.addAll(v, new String[]
097        { "callCount", "detailed", "allowTriggeredUpdates", });
098
099        parameterNames.put("stop", EMPTY_VEC_STR);
100
101        parameterNames.put("stopPreciseCoverage", EMPTY_VEC_STR);
102
103        parameterNames.put("takePreciseCoverage", EMPTY_VEC_STR);
104    }
105
106
107    // ********************************************************************************************
108    // ********************************************************************************************
109    // Types - Static Inner Classes
110    // ********************************************************************************************
111    // ********************************************************************************************
112
113    /** Profile node. Holds callsite information, execution statistics and child nodes. */
114    public static class ProfileNode
115        extends BaseType
116        implements java.io.Serializable
117    {
118        /** For Object Serialization.  java.io.Serializable */
119        protected static final long serialVersionUID = 1;
120        
121        public boolean[] optionals()
122        { return new boolean[] { false, false, true, true, true, true, }; }
123        
124        /** Unique id of the node. */
125        public final int id;
126        
127        /** Function location. */
128        public final RunTime.CallFrame callFrame;
129        
130        /**
131         * Number of samples where this node was on top of the call stack.
132         * <BR /><B CLASS=Opt>OPTIONAL</B>
133         */
134        public final Integer hitCount;
135        
136        /**
137         * Child node ids.
138         * <BR /><B CLASS=Opt>OPTIONAL</B>
139         */
140        public final int[] children;
141        
142        /**
143         * The reason of being not optimized. The function may be deoptimized or marked as don't
144         * optimize.
145         * <BR /><B CLASS=Opt>OPTIONAL</B>
146         */
147        public final String deoptReason;
148        
149        /**
150         * An array of source position ticks.
151         * <BR /><B CLASS=Opt>OPTIONAL</B>
152         */
153        public final Profiler.PositionTickInfo[] positionTicks;
154        
155        /**
156         * Constructor
157         *
158         * @param id Unique id of the node.
159         * 
160         * @param callFrame Function location.
161         * 
162         * @param hitCount Number of samples where this node was on top of the call stack.
163         * <BR /><B CLASS=Opt>OPTIONAL</B>
164         * 
165         * @param children Child node ids.
166         * <BR /><B CLASS=Opt>OPTIONAL</B>
167         * 
168         * @param deoptReason 
169         * The reason of being not optimized. The function may be deoptimized or marked as don't
170         * optimize.
171         * <BR /><B CLASS=Opt>OPTIONAL</B>
172         * 
173         * @param positionTicks An array of source position ticks.
174         * <BR /><B CLASS=Opt>OPTIONAL</B>
175         */
176        public ProfileNode(
177                int id, RunTime.CallFrame callFrame, Integer hitCount, int[] children, 
178                String deoptReason, Profiler.PositionTickInfo[] positionTicks
179            )
180        {
181            // Exception-Check(s) to ensure that if any parameters which are not declared as
182            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
183            
184            if (callFrame == null) THROWS.throwNPE("callFrame");
185            
186            this.id             = id;
187            this.callFrame      = callFrame;
188            this.hitCount       = hitCount;
189            this.children       = children;
190            this.deoptReason    = deoptReason;
191            this.positionTicks  = positionTicks;
192        }
193        
194        /**
195         * JSON Object Constructor
196         * @param jo A Json-Object having data about an instance of {@code 'ProfileNode'}.
197         */
198        public ProfileNode (JsonObject jo)
199        {
200            this.id             = ReadPrimJSON.getInt(jo, "id");
201            this.callFrame      = ReadJSON.getObject(jo, "callFrame", RunTime.CallFrame.class, false, true);
202            this.hitCount       = ReadBoxedJSON.getInteger(jo, "hitCount", true);
203            this.children = (jo.getJsonArray("children") == null)
204                ? null
205                : RJArrIntoPrimArray.intArr(jo.getJsonArray("children"), -1, 0, null);
206        
207            this.deoptReason    = ReadJSON.getString(jo, "deoptReason", true, false);
208            this.positionTicks = (jo.getJsonArray("positionTicks") == null)
209                ? null
210                : RJArrIntoStream.objArr(jo.getJsonArray("positionTicks"), null, 0, Profiler.PositionTickInfo.class).toArray(Profiler.PositionTickInfo[]::new);
211        
212        }
213        
214        
215        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
216        public boolean equals(Object other)
217        {
218            if (this == other)                       return true;
219            if (other == null)                       return false;
220            if (other.getClass() != this.getClass()) return false;
221        
222            ProfileNode o = (ProfileNode) other;
223        
224            return
225                    (this.id == o.id)
226                &&  Objects.equals(this.callFrame, o.callFrame)
227                &&  Objects.equals(this.hitCount, o.hitCount)
228                &&  Arrays.equals(this.children, o.children)
229                &&  Objects.equals(this.deoptReason, o.deoptReason)
230                &&  Arrays.deepEquals(this.positionTicks, o.positionTicks);
231        }
232        
233        /** Generates a Hash-Code for {@code 'this'} instance */
234        public int hashCode()
235        {
236            return
237                    this.id
238                +   this.callFrame.hashCode()
239                +   Objects.hashCode(this.hitCount)
240                +   Arrays.hashCode(this.children)
241                +   Objects.hashCode(this.deoptReason)
242                +   Arrays.deepHashCode(this.positionTicks);
243        }
244    }
245    
246    /** Profile. */
247    public static class Profile
248        extends BaseType
249        implements java.io.Serializable
250    {
251        /** For Object Serialization.  java.io.Serializable */
252        protected static final long serialVersionUID = 1;
253        
254        public boolean[] optionals()
255        { return new boolean[] { false, false, false, true, true, }; }
256        
257        /** The list of profile nodes. First item is the root node. */
258        public final Profiler.ProfileNode[] nodes;
259        
260        /** Profiling start timestamp in microseconds. */
261        public final Number startTime;
262        
263        /** Profiling end timestamp in microseconds. */
264        public final Number endTime;
265        
266        /**
267         * Ids of samples top nodes.
268         * <BR /><B CLASS=Opt>OPTIONAL</B>
269         */
270        public final int[] samples;
271        
272        /**
273         * Time intervals between adjacent samples in microseconds. The first delta is relative to the
274         * profile startTime.
275         * <BR /><B CLASS=Opt>OPTIONAL</B>
276         */
277        public final int[] timeDeltas;
278        
279        /**
280         * Constructor
281         *
282         * @param nodes The list of profile nodes. First item is the root node.
283         * 
284         * @param startTime Profiling start timestamp in microseconds.
285         * 
286         * @param endTime Profiling end timestamp in microseconds.
287         * 
288         * @param samples Ids of samples top nodes.
289         * <BR /><B CLASS=Opt>OPTIONAL</B>
290         * 
291         * @param timeDeltas 
292         * Time intervals between adjacent samples in microseconds. The first delta is relative to the
293         * profile startTime.
294         * <BR /><B CLASS=Opt>OPTIONAL</B>
295         */
296        public Profile(
297                Profiler.ProfileNode[] nodes, Number startTime, Number endTime, int[] samples, 
298                int[] timeDeltas
299            )
300        {
301            // Exception-Check(s) to ensure that if any parameters which are not declared as
302            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
303            
304            if (nodes == null)     THROWS.throwNPE("nodes");
305            if (startTime == null) THROWS.throwNPE("startTime");
306            if (endTime == null)   THROWS.throwNPE("endTime");
307            
308            this.nodes       = nodes;
309            this.startTime   = startTime;
310            this.endTime     = endTime;
311            this.samples     = samples;
312            this.timeDeltas  = timeDeltas;
313        }
314        
315        /**
316         * JSON Object Constructor
317         * @param jo A Json-Object having data about an instance of {@code 'Profile'}.
318         */
319        public Profile (JsonObject jo)
320        {
321            this.nodes = (jo.getJsonArray("nodes") == null)
322                ? null
323                : RJArrIntoStream.objArr(jo.getJsonArray("nodes"), null, 0, Profiler.ProfileNode.class).toArray(Profiler.ProfileNode[]::new);
324        
325            this.startTime   = ReadNumberJSON.get(jo, "startTime", false, true);
326            this.endTime     = ReadNumberJSON.get(jo, "endTime", false, true);
327            this.samples = (jo.getJsonArray("samples") == null)
328                ? null
329                : RJArrIntoPrimArray.intArr(jo.getJsonArray("samples"), -1, 0, null);
330        
331            this.timeDeltas = (jo.getJsonArray("timeDeltas") == null)
332                ? null
333                : RJArrIntoPrimArray.intArr(jo.getJsonArray("timeDeltas"), -1, 0, null);
334        
335        }
336        
337        
338        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
339        public boolean equals(Object other)
340        {
341            if (this == other)                       return true;
342            if (other == null)                       return false;
343            if (other.getClass() != this.getClass()) return false;
344        
345            Profile o = (Profile) other;
346        
347            return
348                    Arrays.deepEquals(this.nodes, o.nodes)
349                &&  Objects.equals(this.startTime, o.startTime)
350                &&  Objects.equals(this.endTime, o.endTime)
351                &&  Arrays.equals(this.samples, o.samples)
352                &&  Arrays.equals(this.timeDeltas, o.timeDeltas);
353        }
354        
355        /** Generates a Hash-Code for {@code 'this'} instance */
356        public int hashCode()
357        {
358            return
359                    Arrays.deepHashCode(this.nodes)
360                +   Objects.hashCode(this.startTime)
361                +   Objects.hashCode(this.endTime)
362                +   Arrays.hashCode(this.samples)
363                +   Arrays.hashCode(this.timeDeltas);
364        }
365    }
366    
367    /** Specifies a number of samples attributed to a certain source position. */
368    public static class PositionTickInfo
369        extends BaseType
370        implements java.io.Serializable
371    {
372        /** For Object Serialization.  java.io.Serializable */
373        protected static final long serialVersionUID = 1;
374        
375        public boolean[] optionals()
376        { return new boolean[] { false, false, }; }
377        
378        /** Source line number (1-based). */
379        public final int line;
380        
381        /** Number of samples attributed to the source line. */
382        public final int ticks;
383        
384        /**
385         * Constructor
386         *
387         * @param line Source line number (1-based).
388         * 
389         * @param ticks Number of samples attributed to the source line.
390         */
391        public PositionTickInfo(int line, int ticks)
392        {
393            this.line   = line;
394            this.ticks  = ticks;
395        }
396        
397        /**
398         * JSON Object Constructor
399         * @param jo A Json-Object having data about an instance of {@code 'PositionTickInfo'}.
400         */
401        public PositionTickInfo (JsonObject jo)
402        {
403            this.line   = ReadPrimJSON.getInt(jo, "line");
404            this.ticks  = ReadPrimJSON.getInt(jo, "ticks");
405        }
406        
407        
408        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
409        public boolean equals(Object other)
410        {
411            if (this == other)                       return true;
412            if (other == null)                       return false;
413            if (other.getClass() != this.getClass()) return false;
414        
415            PositionTickInfo o = (PositionTickInfo) other;
416        
417            return
418                    (this.line == o.line)
419                &&  (this.ticks == o.ticks);
420        }
421        
422        /** Generates a Hash-Code for {@code 'this'} instance */
423        public int hashCode()
424        {
425            return
426                    this.line
427                +   this.ticks;
428        }
429    }
430    
431    /** Coverage data for a source range. */
432    public static class CoverageRange
433        extends BaseType
434        implements java.io.Serializable
435    {
436        /** For Object Serialization.  java.io.Serializable */
437        protected static final long serialVersionUID = 1;
438        
439        public boolean[] optionals()
440        { return new boolean[] { false, false, false, }; }
441        
442        /** JavaScript script source offset for the range start. */
443        public final int startOffset;
444        
445        /** JavaScript script source offset for the range end. */
446        public final int endOffset;
447        
448        /** Collected execution count of the source range. */
449        public final int count;
450        
451        /**
452         * Constructor
453         *
454         * @param startOffset JavaScript script source offset for the range start.
455         * 
456         * @param endOffset JavaScript script source offset for the range end.
457         * 
458         * @param count Collected execution count of the source range.
459         */
460        public CoverageRange(int startOffset, int endOffset, int count)
461        {
462            this.startOffset  = startOffset;
463            this.endOffset    = endOffset;
464            this.count        = count;
465        }
466        
467        /**
468         * JSON Object Constructor
469         * @param jo A Json-Object having data about an instance of {@code 'CoverageRange'}.
470         */
471        public CoverageRange (JsonObject jo)
472        {
473            this.startOffset  = ReadPrimJSON.getInt(jo, "startOffset");
474            this.endOffset    = ReadPrimJSON.getInt(jo, "endOffset");
475            this.count        = ReadPrimJSON.getInt(jo, "count");
476        }
477        
478        
479        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
480        public boolean equals(Object other)
481        {
482            if (this == other)                       return true;
483            if (other == null)                       return false;
484            if (other.getClass() != this.getClass()) return false;
485        
486            CoverageRange o = (CoverageRange) other;
487        
488            return
489                    (this.startOffset == o.startOffset)
490                &&  (this.endOffset == o.endOffset)
491                &&  (this.count == o.count);
492        }
493        
494        /** Generates a Hash-Code for {@code 'this'} instance */
495        public int hashCode()
496        {
497            return
498                    this.startOffset
499                +   this.endOffset
500                +   this.count;
501        }
502    }
503    
504    /** Coverage data for a JavaScript function. */
505    public static class FunctionCoverage
506        extends BaseType
507        implements java.io.Serializable
508    {
509        /** For Object Serialization.  java.io.Serializable */
510        protected static final long serialVersionUID = 1;
511        
512        public boolean[] optionals()
513        { return new boolean[] { false, false, false, }; }
514        
515        /** JavaScript function name. */
516        public final String functionName;
517        
518        /** Source ranges inside the function with coverage data. */
519        public final Profiler.CoverageRange[] ranges;
520        
521        /** Whether coverage data for this function has block granularity. */
522        public final boolean isBlockCoverage;
523        
524        /**
525         * Constructor
526         *
527         * @param functionName JavaScript function name.
528         * 
529         * @param ranges Source ranges inside the function with coverage data.
530         * 
531         * @param isBlockCoverage Whether coverage data for this function has block granularity.
532         */
533        public FunctionCoverage
534            (String functionName, Profiler.CoverageRange[] ranges, boolean isBlockCoverage)
535        {
536            // Exception-Check(s) to ensure that if any parameters which are not declared as
537            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
538            
539            if (functionName == null) THROWS.throwNPE("functionName");
540            if (ranges == null)       THROWS.throwNPE("ranges");
541            
542            this.functionName     = functionName;
543            this.ranges           = ranges;
544            this.isBlockCoverage  = isBlockCoverage;
545        }
546        
547        /**
548         * JSON Object Constructor
549         * @param jo A Json-Object having data about an instance of {@code 'FunctionCoverage'}.
550         */
551        public FunctionCoverage (JsonObject jo)
552        {
553            this.functionName     = ReadJSON.getString(jo, "functionName", false, true);
554            this.ranges = (jo.getJsonArray("ranges") == null)
555                ? null
556                : RJArrIntoStream.objArr(jo.getJsonArray("ranges"), null, 0, Profiler.CoverageRange.class).toArray(Profiler.CoverageRange[]::new);
557        
558            this.isBlockCoverage  = ReadPrimJSON.getBoolean(jo, "isBlockCoverage");
559        }
560        
561        
562        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
563        public boolean equals(Object other)
564        {
565            if (this == other)                       return true;
566            if (other == null)                       return false;
567            if (other.getClass() != this.getClass()) return false;
568        
569            FunctionCoverage o = (FunctionCoverage) other;
570        
571            return
572                    Objects.equals(this.functionName, o.functionName)
573                &&  Arrays.deepEquals(this.ranges, o.ranges)
574                &&  (this.isBlockCoverage == o.isBlockCoverage);
575        }
576        
577        /** Generates a Hash-Code for {@code 'this'} instance */
578        public int hashCode()
579        {
580            return
581                    Objects.hashCode(this.functionName)
582                +   Arrays.deepHashCode(this.ranges)
583                +   (this.isBlockCoverage ? 1 : 0);
584        }
585    }
586    
587    /** Coverage data for a JavaScript script. */
588    public static class ScriptCoverage
589        extends BaseType
590        implements java.io.Serializable
591    {
592        /** For Object Serialization.  java.io.Serializable */
593        protected static final long serialVersionUID = 1;
594        
595        public boolean[] optionals()
596        { return new boolean[] { false, false, false, }; }
597        
598        /** JavaScript script id. */
599        public final String scriptId;
600        
601        /** JavaScript script name or url. */
602        public final String url;
603        
604        /** Functions contained in the script that has coverage data. */
605        public final Profiler.FunctionCoverage[] functions;
606        
607        /**
608         * Constructor
609         *
610         * @param scriptId JavaScript script id.
611         * 
612         * @param url JavaScript script name or url.
613         * 
614         * @param functions Functions contained in the script that has coverage data.
615         */
616        public ScriptCoverage
617            (String scriptId, String url, Profiler.FunctionCoverage[] functions)
618        {
619            // Exception-Check(s) to ensure that if any parameters which are not declared as
620            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
621            
622            if (scriptId == null)  THROWS.throwNPE("scriptId");
623            if (url == null)       THROWS.throwNPE("url");
624            if (functions == null) THROWS.throwNPE("functions");
625            
626            this.scriptId   = scriptId;
627            this.url        = url;
628            this.functions  = functions;
629        }
630        
631        /**
632         * JSON Object Constructor
633         * @param jo A Json-Object having data about an instance of {@code 'ScriptCoverage'}.
634         */
635        public ScriptCoverage (JsonObject jo)
636        {
637            this.scriptId   = ReadJSON.getString(jo, "scriptId", false, true);
638            this.url        = ReadJSON.getString(jo, "url", false, true);
639            this.functions = (jo.getJsonArray("functions") == null)
640                ? null
641                : RJArrIntoStream.objArr(jo.getJsonArray("functions"), null, 0, Profiler.FunctionCoverage.class).toArray(Profiler.FunctionCoverage[]::new);
642        
643        }
644        
645        
646        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
647        public boolean equals(Object other)
648        {
649            if (this == other)                       return true;
650            if (other == null)                       return false;
651            if (other.getClass() != this.getClass()) return false;
652        
653            ScriptCoverage o = (ScriptCoverage) other;
654        
655            return
656                    Objects.equals(this.scriptId, o.scriptId)
657                &&  Objects.equals(this.url, o.url)
658                &&  Arrays.deepEquals(this.functions, o.functions);
659        }
660        
661        /** Generates a Hash-Code for {@code 'this'} instance */
662        public int hashCode()
663        {
664            return
665                    Objects.hashCode(this.scriptId)
666                +   Objects.hashCode(this.url)
667                +   Arrays.deepHashCode(this.functions);
668        }
669    }
670    
671    /** <CODE>[No Description Provided by Google]</CODE> */
672    public static class consoleProfileFinished
673        extends BrowserEvent
674        implements java.io.Serializable
675    {
676        /** For Object Serialization.  java.io.Serializable */
677        protected static final long serialVersionUID = 1;
678        
679        public boolean[] optionals()
680        { return new boolean[] { false, false, false, true, }; }
681        
682        /** <CODE>[No Description Provided by Google]</CODE> */
683        public final String id;
684        
685        /** Location of console.profileEnd(). */
686        public final Debugger.Location location;
687        
688        /** <CODE>[No Description Provided by Google]</CODE> */
689        public final Profiler.Profile profile;
690        
691        /**
692         * Profile title passed as an argument to console.profile().
693         * <BR /><B CLASS=Opt>OPTIONAL</B>
694         */
695        public final String title;
696        
697        /**
698         * Constructor
699         *
700         * @param id -
701         * 
702         * @param location Location of console.profileEnd().
703         * 
704         * @param profile -
705         * 
706         * @param title Profile title passed as an argument to console.profile().
707         * <BR /><B CLASS=Opt>OPTIONAL</B>
708         */
709        public consoleProfileFinished
710            (String id, Debugger.Location location, Profiler.Profile profile, String title)
711        {
712            super("Profiler", "consoleProfileFinished", 4);
713            
714            // Exception-Check(s) to ensure that if any parameters which are not declared as
715            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
716            
717            if (id == null)       THROWS.throwNPE("id");
718            if (location == null) THROWS.throwNPE("location");
719            if (profile == null)  THROWS.throwNPE("profile");
720            
721            this.id        = id;
722            this.location  = location;
723            this.profile   = profile;
724            this.title     = title;
725        }
726        
727        /**
728         * JSON Object Constructor
729         * @param jo A Json-Object having data about an instance of {@code 'consoleProfileFinished'}.
730         */
731        public consoleProfileFinished (JsonObject jo)
732        {
733            super("Profiler", "consoleProfileFinished", 4);
734        
735            this.id        = ReadJSON.getString(jo, "id", false, true);
736            this.location  = ReadJSON.getObject(jo, "location", Debugger.Location.class, false, true);
737            this.profile   = ReadJSON.getObject(jo, "profile", Profiler.Profile.class, false, true);
738            this.title     = ReadJSON.getString(jo, "title", true, false);
739        }
740        
741        
742        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
743        public boolean equals(Object other)
744        {
745            if (this == other)                       return true;
746            if (other == null)                       return false;
747            if (other.getClass() != this.getClass()) return false;
748        
749            consoleProfileFinished o = (consoleProfileFinished) other;
750        
751            return
752                    Objects.equals(this.id, o.id)
753                &&  Objects.equals(this.location, o.location)
754                &&  Objects.equals(this.profile, o.profile)
755                &&  Objects.equals(this.title, o.title);
756        }
757        
758        /** Generates a Hash-Code for {@code 'this'} instance */
759        public int hashCode()
760        {
761            return
762                    Objects.hashCode(this.id)
763                +   this.location.hashCode()
764                +   this.profile.hashCode()
765                +   Objects.hashCode(this.title);
766        }
767    }
768    
769    /** Sent when new profile recording is started using console.profile() call. */
770    public static class consoleProfileStarted
771        extends BrowserEvent
772        implements java.io.Serializable
773    {
774        /** For Object Serialization.  java.io.Serializable */
775        protected static final long serialVersionUID = 1;
776        
777        public boolean[] optionals()
778        { return new boolean[] { false, false, true, }; }
779        
780        /** <CODE>[No Description Provided by Google]</CODE> */
781        public final String id;
782        
783        /** Location of console.profile(). */
784        public final Debugger.Location location;
785        
786        /**
787         * Profile title passed as an argument to console.profile().
788         * <BR /><B CLASS=Opt>OPTIONAL</B>
789         */
790        public final String title;
791        
792        /**
793         * Constructor
794         *
795         * @param id -
796         * 
797         * @param location Location of console.profile().
798         * 
799         * @param title Profile title passed as an argument to console.profile().
800         * <BR /><B CLASS=Opt>OPTIONAL</B>
801         */
802        public consoleProfileStarted(String id, Debugger.Location location, String title)
803        {
804            super("Profiler", "consoleProfileStarted", 3);
805            
806            // Exception-Check(s) to ensure that if any parameters which are not declared as
807            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
808            
809            if (id == null)       THROWS.throwNPE("id");
810            if (location == null) THROWS.throwNPE("location");
811            
812            this.id        = id;
813            this.location  = location;
814            this.title     = title;
815        }
816        
817        /**
818         * JSON Object Constructor
819         * @param jo A Json-Object having data about an instance of {@code 'consoleProfileStarted'}.
820         */
821        public consoleProfileStarted (JsonObject jo)
822        {
823            super("Profiler", "consoleProfileStarted", 3);
824        
825            this.id        = ReadJSON.getString(jo, "id", false, true);
826            this.location  = ReadJSON.getObject(jo, "location", Debugger.Location.class, false, true);
827            this.title     = ReadJSON.getString(jo, "title", true, false);
828        }
829        
830        
831        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
832        public boolean equals(Object other)
833        {
834            if (this == other)                       return true;
835            if (other == null)                       return false;
836            if (other.getClass() != this.getClass()) return false;
837        
838            consoleProfileStarted o = (consoleProfileStarted) other;
839        
840            return
841                    Objects.equals(this.id, o.id)
842                &&  Objects.equals(this.location, o.location)
843                &&  Objects.equals(this.title, o.title);
844        }
845        
846        /** Generates a Hash-Code for {@code 'this'} instance */
847        public int hashCode()
848        {
849            return
850                    Objects.hashCode(this.id)
851                +   this.location.hashCode()
852                +   Objects.hashCode(this.title);
853        }
854    }
855    
856    /**
857     * Reports coverage delta since the last poll (either from an event like this, or from
858     * {@code takePreciseCoverage} for the current isolate. May only be sent if precise code
859     * coverage has been started. This event can be trigged by the embedder to, for example,
860     * trigger collection of coverage data immediately at a certain point in time.
861     * <BR /><B CLASS=Exp>EXPERIMENTAL</B>
862     */
863    public static class preciseCoverageDeltaUpdate
864        extends BrowserEvent
865        implements java.io.Serializable
866    {
867        /** For Object Serialization.  java.io.Serializable */
868        protected static final long serialVersionUID = 1;
869        
870        public boolean[] optionals()
871        { return new boolean[] { false, false, false, }; }
872        
873        /** Monotonically increasing time (in seconds) when the coverage update was taken in the backend. */
874        public final Number timestamp;
875        
876        /** Identifier for distinguishing coverage events. */
877        public final String occasion;
878        
879        /** Coverage data for the current isolate. */
880        public final Profiler.ScriptCoverage[] result;
881        
882        /**
883         * Constructor
884         *
885         * @param timestamp Monotonically increasing time (in seconds) when the coverage update was taken in the backend.
886         * 
887         * @param occasion Identifier for distinguishing coverage events.
888         * 
889         * @param result Coverage data for the current isolate.
890         */
891        public preciseCoverageDeltaUpdate
892            (Number timestamp, String occasion, Profiler.ScriptCoverage[] result)
893        {
894            super("Profiler", "preciseCoverageDeltaUpdate", 3);
895            
896            // Exception-Check(s) to ensure that if any parameters which are not declared as
897            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
898            
899            if (timestamp == null) THROWS.throwNPE("timestamp");
900            if (occasion == null)  THROWS.throwNPE("occasion");
901            if (result == null)    THROWS.throwNPE("result");
902            
903            this.timestamp  = timestamp;
904            this.occasion   = occasion;
905            this.result     = result;
906        }
907        
908        /**
909         * JSON Object Constructor
910         * @param jo A Json-Object having data about an instance of {@code 'preciseCoverageDeltaUpdate'}.
911         */
912        public preciseCoverageDeltaUpdate (JsonObject jo)
913        {
914            super("Profiler", "preciseCoverageDeltaUpdate", 3);
915        
916            this.timestamp  = ReadNumberJSON.get(jo, "timestamp", false, true);
917            this.occasion   = ReadJSON.getString(jo, "occasion", false, true);
918            this.result = (jo.getJsonArray("result") == null)
919                ? null
920                : RJArrIntoStream.objArr(jo.getJsonArray("result"), null, 0, Profiler.ScriptCoverage.class).toArray(Profiler.ScriptCoverage[]::new);
921        
922        }
923        
924        
925        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
926        public boolean equals(Object other)
927        {
928            if (this == other)                       return true;
929            if (other == null)                       return false;
930            if (other.getClass() != this.getClass()) return false;
931        
932            preciseCoverageDeltaUpdate o = (preciseCoverageDeltaUpdate) other;
933        
934            return
935                    Objects.equals(this.timestamp, o.timestamp)
936                &&  Objects.equals(this.occasion, o.occasion)
937                &&  Arrays.deepEquals(this.result, o.result);
938        }
939        
940        /** Generates a Hash-Code for {@code 'this'} instance */
941        public int hashCode()
942        {
943            return
944                    Objects.hashCode(this.timestamp)
945                +   Objects.hashCode(this.occasion)
946                +   Arrays.deepHashCode(this.result);
947        }
948    }
949    
950    
951    // Counter for keeping the WebSocket Request ID's distinct.
952    private static int counter = 1;
953    
954    /**
955     * <CODE>[No Description Provided by Google]</CODE>
956     * 
957     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
958     * {@link Ret0}&gt;</CODE>
959     *
960     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
961     * browser receives the invocation-request.
962     *
963     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
964     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
965     * {@code >} to ensure the Browser Function has run to completion.
966     */
967    public static Script<String, JsonObject, Ret0> disable()
968    {
969        final int          webSocketID = 4000000 + counter++;
970        final boolean[]    optionals   = new boolean[0];
971        
972        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
973        String requestJSON = WriteJSON.get(
974            parameterTypes.get("disable"),
975            parameterNames.get("disable"),
976            optionals, webSocketID,
977            "Profiler.disable"
978        );
979        
980        // This Remote Command does not have a Return-Value.
981        return new Script<>
982            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
983    }
984    
985    /**
986     * <CODE>[No Description Provided by Google]</CODE>
987     * 
988     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
989     * {@link Ret0}&gt;</CODE>
990     *
991     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
992     * browser receives the invocation-request.
993     *
994     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
995     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
996     * {@code >} to ensure the Browser Function has run to completion.
997     */
998    public static Script<String, JsonObject, Ret0> enable()
999    {
1000        final int          webSocketID = 4001000 + counter++;
1001        final boolean[]    optionals   = new boolean[0];
1002        
1003        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1004        String requestJSON = WriteJSON.get(
1005            parameterTypes.get("enable"),
1006            parameterNames.get("enable"),
1007            optionals, webSocketID,
1008            "Profiler.enable"
1009        );
1010        
1011        // This Remote Command does not have a Return-Value.
1012        return new Script<>
1013            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1014    }
1015    
1016    /**
1017     * Collect coverage data for the current isolate. The coverage data may be incomplete due to
1018     * garbage collection.
1019     * 
1020     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1021     * {@link Profiler.ScriptCoverage}[]&gt;</CODE>
1022     * 
1023     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
1024     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
1025     * {@link Profiler.ScriptCoverage}[]&gt;</CODE> will be returned.
1026     *
1027     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
1028     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
1029      * may be retrieved.</I>
1030     *
1031     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
1032     * <BR /><BR /><UL CLASS=JDUL>
1033     * <LI><CODE>{@link Profiler.ScriptCoverage}[] (<B>result</B></CODE>)
1034     *     <BR />Coverage data for the current isolate.
1035     * </LI>
1036     * </UL> */
1037    public static Script<String, JsonObject, Profiler.ScriptCoverage[]> getBestEffortCoverage()
1038    {
1039        final int          webSocketID = 4002000 + counter++;
1040        final boolean[]    optionals   = new boolean[0];
1041        
1042        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1043        String requestJSON = WriteJSON.get(
1044            parameterTypes.get("getBestEffortCoverage"),
1045            parameterNames.get("getBestEffortCoverage"),
1046            optionals, webSocketID,
1047            "Profiler.getBestEffortCoverage"
1048        );
1049        
1050        // 'JSON Binding' ... Converts Browser Response-JSON to 'Profiler.ScriptCoverage[]'
1051        Function<JsonObject, Profiler.ScriptCoverage[]> responseProcessor = (JsonObject jo) ->
1052            (jo.getJsonArray("result") == null)
1053                ? null
1054                : RJArrIntoStream.objArr(jo.getJsonArray("result"), null, 0, Profiler.ScriptCoverage.class).toArray(Profiler.ScriptCoverage[]::new);
1055        
1056        return new Script<>(webSocketID, requestJSON, responseProcessor);
1057    }
1058    
1059    /**
1060     * Changes CPU profiler sampling interval. Must be called before CPU profiles recording started.
1061     * 
1062     * @param interval New sampling interval in microseconds.
1063     * 
1064     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1065     * {@link Ret0}&gt;</CODE>
1066     *
1067     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1068     * browser receives the invocation-request.
1069     *
1070     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1071     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1072     * {@code >} to ensure the Browser Function has run to completion.
1073     */
1074    public static Script<String, JsonObject, Ret0> setSamplingInterval(int interval)
1075    {
1076        final int       webSocketID = 4003000 + counter++;
1077        final boolean[] optionals   = { false, };
1078        
1079        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1080        String requestJSON = WriteJSON.get(
1081            parameterTypes.get("setSamplingInterval"),
1082            parameterNames.get("setSamplingInterval"),
1083            optionals, webSocketID,
1084            "Profiler.setSamplingInterval",
1085            interval
1086        );
1087        
1088        // This Remote Command does not have a Return-Value.
1089        return new Script<>
1090            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1091    }
1092    
1093    /**
1094     * <CODE>[No Description Provided by Google]</CODE>
1095     * 
1096     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1097     * {@link Ret0}&gt;</CODE>
1098     *
1099     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1100     * browser receives the invocation-request.
1101     *
1102     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1103     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1104     * {@code >} to ensure the Browser Function has run to completion.
1105     */
1106    public static Script<String, JsonObject, Ret0> start()
1107    {
1108        final int          webSocketID = 4004000 + counter++;
1109        final boolean[]    optionals   = new boolean[0];
1110        
1111        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1112        String requestJSON = WriteJSON.get(
1113            parameterTypes.get("start"),
1114            parameterNames.get("start"),
1115            optionals, webSocketID,
1116            "Profiler.start"
1117        );
1118        
1119        // This Remote Command does not have a Return-Value.
1120        return new Script<>
1121            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1122    }
1123    
1124    /**
1125     * Enable precise code coverage. Coverage data for JavaScript executed before enabling precise code
1126     * coverage may be incomplete. Enabling prevents running optimized code and resets execution
1127     * counters.
1128     * 
1129     * @param callCount Collect accurate call counts beyond simple 'covered' or 'not covered'.
1130     * <BR /><B CLASS=Opt>OPTIONAL</B>
1131     * 
1132     * @param detailed Collect block-based coverage.
1133     * <BR /><B CLASS=Opt>OPTIONAL</B>
1134     * 
1135     * @param allowTriggeredUpdates Allow the backend to send updates on its own initiative
1136     * <BR /><B CLASS=Opt>OPTIONAL</B>
1137     * 
1138     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1139     * Number&gt;</CODE>
1140     * 
1141     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
1142     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
1143     * Number&gt;</CODE> will be returned.
1144     *
1145     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
1146     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
1147      * may be retrieved.</I>
1148     *
1149     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
1150     * <BR /><BR /><UL CLASS=JDUL>
1151     * <LI><CODE>Number (<B>timestamp</B></CODE>)
1152     *     <BR />Monotonically increasing time (in seconds) when the coverage update was taken in the backend.
1153     * </LI>
1154     * </UL> */
1155    public static Script<String, JsonObject, Number> startPreciseCoverage
1156        (Boolean callCount, Boolean detailed, Boolean allowTriggeredUpdates)
1157    {
1158        final int       webSocketID = 4005000 + counter++;
1159        final boolean[] optionals   = { true, true, true, };
1160        
1161        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1162        String requestJSON = WriteJSON.get(
1163            parameterTypes.get("startPreciseCoverage"),
1164            parameterNames.get("startPreciseCoverage"),
1165            optionals, webSocketID,
1166            "Profiler.startPreciseCoverage",
1167            callCount, detailed, allowTriggeredUpdates
1168        );
1169        
1170        // 'JSON Binding' ... Converts Browser Response-JSON to 'Number'
1171        Function<JsonObject, Number> responseProcessor = (JsonObject jo) ->
1172            ReadNumberJSON.get(jo, "timestamp", false, true);
1173        
1174        return new Script<>(webSocketID, requestJSON, responseProcessor);
1175    }
1176    
1177    /**
1178     * <CODE>[No Description Provided by Google]</CODE>
1179     * 
1180     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1181     * {@link Profiler.Profile}&gt;</CODE>
1182     * 
1183     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
1184     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
1185     * {@link Profiler.Profile}&gt;</CODE> will be returned.
1186     *
1187     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
1188     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
1189      * may be retrieved.</I>
1190     *
1191     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
1192     * <BR /><BR /><UL CLASS=JDUL>
1193     * <LI><CODE>{@link Profiler.Profile} (<B>profile</B></CODE>)
1194     *     <BR />Recorded profile.
1195     * </LI>
1196     * </UL> */
1197    public static Script<String, JsonObject, Profiler.Profile> stop()
1198    {
1199        final int          webSocketID = 4006000 + counter++;
1200        final boolean[]    optionals   = new boolean[0];
1201        
1202        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1203        String requestJSON = WriteJSON.get(
1204            parameterTypes.get("stop"),
1205            parameterNames.get("stop"),
1206            optionals, webSocketID,
1207            "Profiler.stop"
1208        );
1209        
1210        // 'JSON Binding' ... Converts Browser Response-JSON to 'Profiler.Profile'
1211        Function<JsonObject, Profiler.Profile> responseProcessor = (JsonObject jo) ->
1212            ReadJSON.getObject(jo, "profile", Profiler.Profile.class, false, true);
1213        
1214        return new Script<>(webSocketID, requestJSON, responseProcessor);
1215    }
1216    
1217    /**
1218     * Disable precise code coverage. Disabling releases unnecessary execution count records and allows
1219     * executing optimized code.
1220     * 
1221     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1222     * {@link Ret0}&gt;</CODE>
1223     *
1224     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1225     * browser receives the invocation-request.
1226     *
1227     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1228     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1229     * {@code >} to ensure the Browser Function has run to completion.
1230     */
1231    public static Script<String, JsonObject, Ret0> stopPreciseCoverage()
1232    {
1233        final int          webSocketID = 4007000 + counter++;
1234        final boolean[]    optionals   = new boolean[0];
1235        
1236        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1237        String requestJSON = WriteJSON.get(
1238            parameterTypes.get("stopPreciseCoverage"),
1239            parameterNames.get("stopPreciseCoverage"),
1240            optionals, webSocketID,
1241            "Profiler.stopPreciseCoverage"
1242        );
1243        
1244        // This Remote Command does not have a Return-Value.
1245        return new Script<>
1246            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1247    }
1248    
1249    /**
1250     * Collect coverage data for the current isolate, and resets execution counters. Precise code
1251     * coverage needs to have started.
1252     * 
1253     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1254     * {@link Ret2}&gt;</CODE>
1255     *
1256     * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 
1257     * {@link Script#exec()}), and a {@link Promise} returned.
1258     *
1259     * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B>
1260     * (using {@link Promise#await()}), the {@code Ret2} will subsequently
1261     * be returned from that call.
1262     * 
1263     * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated
1264     * in an instance of <B>{@link Ret2}</B>
1265     *
1266     * <BR /><BR /><UL CLASS=JDUL>
1267     * <LI><CODE><B>Ret2.a:</B> {@link Profiler.ScriptCoverage}[] (<B>result</B>)</CODE>
1268     *     <BR />Coverage data for the current isolate.
1269     *     <BR /><BR /></LI>
1270     * <LI><CODE><B>Ret2.b:</B> Number (<B>timestamp</B>)</CODE>
1271     *     <BR />Monotonically increasing time (in seconds) when the coverage update was taken in the backend.
1272     *     </LI>
1273     * </UL>
1274     */
1275    public static Script<String, JsonObject, Ret2<Profiler.ScriptCoverage[], Number>> takePreciseCoverage()
1276    {
1277        final int          webSocketID = 4008000 + counter++;
1278        final boolean[]    optionals   = new boolean[0];
1279        
1280        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1281        String requestJSON = WriteJSON.get(
1282            parameterTypes.get("takePreciseCoverage"),
1283            parameterNames.get("takePreciseCoverage"),
1284            optionals, webSocketID,
1285            "Profiler.takePreciseCoverage"
1286        );
1287        
1288        // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret2'
1289        Function<JsonObject, Ret2<Profiler.ScriptCoverage[], Number>>
1290            responseProcessor = (JsonObject jo) -> new Ret2<>(
1291                (jo.getJsonArray("result") == null)
1292                    ? null
1293                    : RJArrIntoStream.objArr(jo.getJsonArray("result"), null, 0, Profiler.ScriptCoverage.class).toArray(Profiler.ScriptCoverage[]::new),
1294                ReadNumberJSON.get(jo, "timestamp", false, true)
1295            );
1296        
1297        return new Script<>(webSocketID, requestJSON, responseProcessor);
1298    }
1299    
1300}